summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarco Nelissen <marcone@google.com>2014-08-20 09:44:44 -0700
committerMarco Nelissen <marcone@google.com>2014-08-20 11:12:23 -0700
commiteb645a0d1820b227af287a5309f017afadbab4e3 (patch)
treeca86c9068cf2a3ec5eaed29c5cb02c9a93ee2d33
parent5596d7c4ad388d1757398181b3a1453d731a1b41 (diff)
downloadframeworks_av-eb645a0d1820b227af287a5309f017afadbab4e3.zip
frameworks_av-eb645a0d1820b227af287a5309f017afadbab4e3.tar.gz
frameworks_av-eb645a0d1820b227af287a5309f017afadbab4e3.tar.bz2
Fix NuPlayer deadlock
Mutexes can't be locked recursively. This would cause a seek in the prepared state to deadlock Bug: 14057920 Change-Id: Ifb5e25f24450b7e5f71611a8ee2bdba45dba70a7
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp33
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDriver.h1
2 files changed, 20 insertions, 14 deletions
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index 140e1ae..e11f40e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -227,7 +227,7 @@ status_t NuPlayerDriver::start() {
if (mStartupSeekTimeUs >= 0) {
if (mStartupSeekTimeUs == 0) {
- notifySeekComplete();
+ notifySeekComplete_l();
} else {
mPlayer->seekToAsync(mStartupSeekTimeUs);
}
@@ -320,7 +320,7 @@ status_t NuPlayerDriver::seekTo(int msec) {
// pretend that the seek completed. It will actually happen when starting playback.
// TODO: actually perform the seek here, so the player is ready to go at the new
// location
- notifySeekComplete();
+ notifySeekComplete_l();
break;
}
@@ -525,23 +525,28 @@ void NuPlayerDriver::notifyPosition(int64_t positionUs) {
}
void NuPlayerDriver::notifySeekComplete() {
+ Mutex::Autolock autoLock(mLock);
+ notifySeekComplete_l();
+}
+
+void NuPlayerDriver::notifySeekComplete_l() {
bool wasSeeking = true;
- {
- Mutex::Autolock autoLock(mLock);
- if (mState == STATE_STOPPED_AND_PREPARING) {
- wasSeeking = false;
- mState = STATE_STOPPED_AND_PREPARED;
- mCondition.broadcast();
- if (!mIsAsyncPrepare) {
- // if we are preparing synchronously, no need to notify listener
- return;
- }
- } else if (mState == STATE_STOPPED) {
- // no need to notify listener
+ if (mState == STATE_STOPPED_AND_PREPARING) {
+ wasSeeking = false;
+ mState = STATE_STOPPED_AND_PREPARED;
+ mCondition.broadcast();
+ if (!mIsAsyncPrepare) {
+ // if we are preparing synchronously, no need to notify listener
return;
}
+ } else if (mState == STATE_STOPPED) {
+ // no need to notify listener
+ return;
}
+ // note: notifyListener called with lock held
+ mLock.unlock();
notifyListener(wasSeeking ? MEDIA_SEEK_COMPLETE : MEDIA_PREPARED);
+ mLock.lock();
}
void NuPlayerDriver::notifyFrameStats(
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
index f520395..a006d8f 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
@@ -69,6 +69,7 @@ struct NuPlayerDriver : public MediaPlayerInterface {
void notifyDuration(int64_t durationUs);
void notifyPosition(int64_t positionUs);
void notifySeekComplete();
+ void notifySeekComplete_l();
void notifyFrameStats(int64_t numFramesTotal, int64_t numFramesDropped);
void notifyListener(int msg, int ext1 = 0, int ext2 = 0, const Parcel *in = NULL);
void notifyFlagsChanged(uint32_t flags);