summaryrefslogtreecommitdiffstats
path: root/services/audioflinger
diff options
context:
space:
mode:
authorGlenn Kasten <gkasten@google.com>2012-02-10 15:32:16 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-02-10 15:32:16 -0800
commitb6333aa8317ce5162ab006c4baed6b0890936dc7 (patch)
treed4fb7b888a6b12f4d3c35c0a84d49490dc33bc8e /services/audioflinger
parent3a144d08b713e3c0f6b7b8e95bc42cef5886f4fa (diff)
parentb28686f95daee16edeb5f39af2cd5274ac3dc99f (diff)
downloadframeworks_av-b6333aa8317ce5162ab006c4baed6b0890936dc7.zip
frameworks_av-b6333aa8317ce5162ab006c4baed6b0890936dc7.tar.gz
frameworks_av-b6333aa8317ce5162ab006c4baed6b0890936dc7.tar.bz2
Merge "Simplify ThreadBase::exit() aka requestExitAndWait"
Diffstat (limited to 'services/audioflinger')
-rw-r--r--services/audioflinger/AudioFlinger.cpp26
-rw-r--r--services/audioflinger/AudioFlinger.h3
2 files changed, 20 insertions, 9 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 285f7a1..aaf73ea 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -998,7 +998,7 @@ AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, audio
mChannelCount(0),
mFrameSize(1), mFormat(AUDIO_FORMAT_INVALID),
mParamStatus(NO_ERROR),
- mStandby(false), mId(id), mExiting(false),
+ mStandby(false), mId(id),
mDevice(device),
mDeathRecipient(new PMDeathRecipient(this))
{
@@ -1017,17 +1017,23 @@ AudioFlinger::ThreadBase::~ThreadBase()
void AudioFlinger::ThreadBase::exit()
{
- // keep a strong ref on ourself so that we won't get
- // destroyed in the middle of requestExitAndWait()
- sp <ThreadBase> strongMe = this;
-
ALOGV("ThreadBase::exit");
{
+ // This lock prevents the following race in thread (uniprocessor for illustration):
+ // if (!exitPending()) {
+ // // context switch from here to exit()
+ // // exit() calls requestExit(), what exitPending() observes
+ // // exit() calls signal(), which is dropped since no waiters
+ // // context switch back from exit() to here
+ // mWaitWorkCV.wait(...);
+ // // now thread is hung
+ // }
AutoMutex lock(mLock);
- mExiting = true;
requestExit();
mWaitWorkCV.signal();
}
+ // When Thread::requestExitAndWait is made virtual and this method is renamed to
+ // "virtual status_t requestExitAndWait()", replace by "return Thread::requestExitAndWait();"
requestExitAndWait();
}
@@ -4516,7 +4522,7 @@ status_t AudioFlinger::RecordThread::start(RecordThread::RecordTrack* recordTrac
ALOGV("Signal record thread");
mWaitWorkCV.signal();
// do not wait for mStartStopCond if exiting
- if (mExiting) {
+ if (exitPending()) {
mActiveTrack.clear();
status = INVALID_OPERATION;
goto startError;
@@ -4543,7 +4549,7 @@ void AudioFlinger::RecordThread::stop(RecordThread::RecordTrack* recordTrack) {
if (mActiveTrack != 0 && recordTrack == mActiveTrack.get()) {
mActiveTrack->mState = TrackBase::PAUSING;
// do not wait for mStartStopCond if exiting
- if (mExiting) {
+ if (exitPending()) {
return;
}
mStartStopCond.wait(mLock);
@@ -4989,6 +4995,8 @@ status_t AudioFlinger::closeOutput(audio_io_handle_t output)
mPlaybackThreads.removeItem(output);
}
thread->exit();
+ // The thread entity (active unit of execution) is no longer running here,
+ // but the ThreadBase container still exists.
if (thread->type() != ThreadBase::DUPLICATING) {
AudioStreamOut *out = thread->clearOutput();
@@ -5132,6 +5140,8 @@ status_t AudioFlinger::closeInput(audio_io_handle_t input)
mRecordThreads.removeItem(input);
}
thread->exit();
+ // The thread entity (active unit of execution) is no longer running here,
+ // but the ThreadBase container still exists.
AudioStreamIn *in = thread->clearInput();
assert(in != NULL);
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 45df893..c66b19e 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -401,6 +401,8 @@ private:
audio_format_t format() const { return mFormat; }
size_t frameCount() const { return mFrameCount; }
void wakeUp() { mWaitWorkCV.broadcast(); }
+ // Should be "virtual status_t requestExitAndWait()" and override same
+ // method in Thread, but Thread::requestExitAndWait() is not yet virtual.
void exit();
virtual bool checkForNewParameters_l() = 0;
virtual status_t setParameters(const String8& keyValuePairs);
@@ -532,7 +534,6 @@ private:
Vector<ConfigEvent> mConfigEvents;
bool mStandby;
const audio_io_handle_t mId;
- bool mExiting;
Vector< sp<EffectChain> > mEffectChains;
uint32_t mDevice; // output device for PlaybackThread
// input + output devices for RecordThread