diff options
author | Glenn Kasten <gkasten@google.com> | 2012-02-10 15:32:16 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-02-10 15:32:16 -0800 |
commit | b6333aa8317ce5162ab006c4baed6b0890936dc7 (patch) | |
tree | d4fb7b888a6b12f4d3c35c0a84d49490dc33bc8e /services/audioflinger | |
parent | 3a144d08b713e3c0f6b7b8e95bc42cef5886f4fa (diff) | |
parent | b28686f95daee16edeb5f39af2cd5274ac3dc99f (diff) | |
download | frameworks_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.cpp | 26 | ||||
-rw-r--r-- | services/audioflinger/AudioFlinger.h | 3 |
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 |