From ebb020aebc157ff127458dc20e1d0066b86bb99d Mon Sep 17 00:00:00 2001 From: Jason Sams <> Date: Tue, 24 Mar 2009 18:45:22 -0700 Subject: [PATCH] Automated import from //branches/master/...@140868,140868 --- include/media/mediaplayer.h | 1 + media/libmedia/mediaplayer.cpp | 28 +++++++++++++++++++++++----- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h index 58906d1173774..255a67b0d84ab 100644 --- a/include/media/mediaplayer.h +++ b/include/media/mediaplayer.h @@ -173,6 +173,7 @@ private: }; sp mPlayer; + thread_id_t mLockThreadId; Mutex mLock; Mutex mNotifyLock; Condition mSignal; diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp index 6b40412447659..58419227264b2 100644 --- a/media/libmedia/mediaplayer.cpp +++ b/media/libmedia/mediaplayer.cpp @@ -91,6 +91,7 @@ MediaPlayer::MediaPlayer() mLoop = false; mLeftVolume = mRightVolume = 1.0; mVideoWidth = mVideoHeight = 0; + mLockThreadId = 0; } void MediaPlayer::onFirstRef() @@ -223,16 +224,24 @@ status_t MediaPlayer::prepare() { LOGV("prepare"); Mutex::Autolock _l(mLock); - if (mPrepareSync) return -EALREADY; + mLockThreadId = getThreadId(); + if (mPrepareSync) { + mLockThreadId = 0; + return -EALREADY; + } mPrepareSync = true; status_t ret = prepareAsync_l(); - if (ret != NO_ERROR) return ret; + if (ret != NO_ERROR) { + mLockThreadId = 0; + return ret; + } if (mPrepareSync) { mSignal.wait(mLock); // wait for prepare done mPrepareSync = false; } LOGV("prepare complete - status=%d", mPrepareStatus); + mLockThreadId = 0; return mPrepareStatus; } @@ -485,14 +494,23 @@ void MediaPlayer::notify(int msg, int ext1, int ext2) { LOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2); bool send = true; + bool locked = false; // TODO: In the future, we might be on the same thread if the app is // running in the same process as the media server. In that case, // this will deadlock. - mLock.lock(); + // + // The threadId hack below works around this for the care of prepare + // within the same process. + + if (mLockThreadId != getThreadId()) { + mLock.lock(); + locked = true; + } + if (mPlayer == 0) { LOGV("notify(%d, %d, %d) callback on disconnected mediaplayer", msg, ext1, ext2); - mLock.unlock(); // release the lock when done. + if (locked) mLock.unlock(); // release the lock when done. return; } @@ -561,7 +579,7 @@ void MediaPlayer::notify(int msg, int ext1, int ext2) } sp listener = mListener; - mLock.unlock(); + if (locked) mLock.unlock(); // this prevents re-entrant calls into client code if ((listener != 0) && send) {