diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2015-11-09 18:02:25 -0800 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2015-11-09 18:02:25 -0800 |
commit | 898d55ba5c1467c615efdf6d553c4a3bf62aeb25 (patch) | |
tree | 61085dacd3702396f1dd13dd42073b2eb0391340 | |
parent | a519bcf25b5ade710ef5bbaba68571b04f86b5e4 (diff) | |
parent | f17204ea09e5629f3f9d9eba2e66d9fb6ce72357 (diff) | |
download | frameworks_av-898d55ba5c1467c615efdf6d553c4a3bf62aeb25.zip frameworks_av-898d55ba5c1467c615efdf6d553c4a3bf62aeb25.tar.gz frameworks_av-898d55ba5c1467c615efdf6d553c4a3bf62aeb25.tar.bz2 |
Merge "AudioPolicyService: fix race in AudioCommandThread"
-rw-r--r-- | services/audiopolicy/service/AudioPolicyService.cpp | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp index d689065..41dd40c 100644 --- a/services/audiopolicy/service/AudioPolicyService.cpp +++ b/services/audiopolicy/service/AudioPolicyService.cpp @@ -577,22 +577,28 @@ bool AudioPolicyService::AudioCommandThread::threadLoop() } } waitTime = INT64_MAX; + // release mLock before releasing strong reference on the service as + // AudioPolicyService destructor calls AudioCommandThread::exit() which + // acquires mLock. + mLock.unlock(); + svc.clear(); + mLock.lock(); } else { waitTime = mAudioCommands[0]->mTime - curTime; break; } } - // release mLock before releasing strong reference on the service as - // AudioPolicyService destructor calls AudioCommandThread::exit() which acquires mLock. - mLock.unlock(); - svc.clear(); - mLock.lock(); - if (!exitPending() && (mAudioCommands.isEmpty() || waitTime != INT64_MAX)) { - // release delayed commands wake lock + + // release delayed commands wake lock if the queue is empty + if (mAudioCommands.isEmpty()) { release_wake_lock(mName.string()); + } + + // At this stage we have either an empty command queue or the first command in the queue + // has a finite delay. So unless we are exiting it is safe to wait. + if (!exitPending()) { ALOGV("AudioCommandThread() going to sleep"); mWaitWorkCV.waitRelative(mLock, waitTime); - ALOGV("AudioCommandThread() waking up"); } } // release delayed commands wake lock before quitting @@ -1005,6 +1011,8 @@ void AudioPolicyService::AudioCommandThread::exit() requestExit(); mWaitWorkCV.signal(); } + // Note that we can call it from the thread loop if all other references have been released + // but it will safely return WOULD_BLOCK in this case requestExitAndWait(); } |