summaryrefslogtreecommitdiffstats
path: root/services/audiopolicy
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2015-09-23 10:25:31 -0700
committerDivya Sharma <c_shard@codeaurora.org>2015-11-04 11:52:03 -0800
commitf17204ea09e5629f3f9d9eba2e66d9fb6ce72357 (patch)
treef1e9c81a7a2b56a0b16c2d16903b4e3cd0c6ee7a /services/audiopolicy
parent36a5d0626d308c7dd04a6e0c8aa06a91d2398d3e (diff)
downloadframeworks_av-f17204ea09e5629f3f9d9eba2e66d9fb6ce72357.zip
frameworks_av-f17204ea09e5629f3f9d9eba2e66d9fb6ce72357.tar.gz
frameworks_av-f17204ea09e5629f3f9d9eba2e66d9fb6ce72357.tar.bz2
AudioPolicyService: fix race in AudioCommandThread
Fixe race condition in AudioCommandThread::threadLoop() where a command can be inserted in first position in the queue after the sleep time has been calculated causing a longer delay than expected. Also fix a failure to hold a wake lock while commands are still in the queue. Bug: 22707905. Change-Id: I813626986677bf00106acb37ee20d3dd75d5cf33
Diffstat (limited to 'services/audiopolicy')
-rw-r--r--services/audiopolicy/service/AudioPolicyService.cpp24
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();
}