Loading include/media/mediaplayer.h +1 −0 Original line number Diff line number Diff line Loading @@ -173,6 +173,7 @@ private: }; sp<IMediaPlayer> mPlayer; thread_id_t mLockThreadId; Mutex mLock; Mutex mNotifyLock; Condition mSignal; Loading media/libmedia/mediaplayer.cpp +23 −5 Original line number Diff line number Diff line Loading @@ -91,6 +91,7 @@ MediaPlayer::MediaPlayer() mLoop = false; mLeftVolume = mRightVolume = 1.0; mVideoWidth = mVideoHeight = 0; mLockThreadId = 0; } void MediaPlayer::onFirstRef() Loading Loading @@ -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; } Loading Loading @@ -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. // // 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; } Loading Loading @@ -561,7 +579,7 @@ void MediaPlayer::notify(int msg, int ext1, int ext2) } sp<MediaPlayerListener> listener = mListener; mLock.unlock(); if (locked) mLock.unlock(); // this prevents re-entrant calls into client code if ((listener != 0) && send) { Loading Loading
include/media/mediaplayer.h +1 −0 Original line number Diff line number Diff line Loading @@ -173,6 +173,7 @@ private: }; sp<IMediaPlayer> mPlayer; thread_id_t mLockThreadId; Mutex mLock; Mutex mNotifyLock; Condition mSignal; Loading
media/libmedia/mediaplayer.cpp +23 −5 Original line number Diff line number Diff line Loading @@ -91,6 +91,7 @@ MediaPlayer::MediaPlayer() mLoop = false; mLeftVolume = mRightVolume = 1.0; mVideoWidth = mVideoHeight = 0; mLockThreadId = 0; } void MediaPlayer::onFirstRef() Loading Loading @@ -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; } Loading Loading @@ -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. // // 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; } Loading Loading @@ -561,7 +579,7 @@ void MediaPlayer::notify(int msg, int ext1, int ext2) } sp<MediaPlayerListener> listener = mListener; mLock.unlock(); if (locked) mLock.unlock(); // this prevents re-entrant calls into client code if ((listener != 0) && send) { Loading