Skip to content

Commit da639f5

Browse files
gkastenAndroid (Google) Code Review
authored andcommitted
Merge "Simplify ThreadBase::exit() aka requestExitAndWait"
2 parents 6f5f9ce + 761286f commit da639f5

File tree

2 files changed

+20
-9
lines changed

2 files changed

+20
-9
lines changed

services/audioflinger/AudioFlinger.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -998,7 +998,7 @@ AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, audio
998998
mChannelCount(0),
999999
mFrameSize(1), mFormat(AUDIO_FORMAT_INVALID),
10001000
mParamStatus(NO_ERROR),
1001-
mStandby(false), mId(id), mExiting(false),
1001+
mStandby(false), mId(id),
10021002
mDevice(device),
10031003
mDeathRecipient(new PMDeathRecipient(this))
10041004
{
@@ -1017,17 +1017,23 @@ AudioFlinger::ThreadBase::~ThreadBase()
10171017

10181018
void AudioFlinger::ThreadBase::exit()
10191019
{
1020-
// keep a strong ref on ourself so that we won't get
1021-
// destroyed in the middle of requestExitAndWait()
1022-
sp <ThreadBase> strongMe = this;
1023-
10241020
ALOGV("ThreadBase::exit");
10251021
{
1022+
// This lock prevents the following race in thread (uniprocessor for illustration):
1023+
// if (!exitPending()) {
1024+
// // context switch from here to exit()
1025+
// // exit() calls requestExit(), what exitPending() observes
1026+
// // exit() calls signal(), which is dropped since no waiters
1027+
// // context switch back from exit() to here
1028+
// mWaitWorkCV.wait(...);
1029+
// // now thread is hung
1030+
// }
10261031
AutoMutex lock(mLock);
1027-
mExiting = true;
10281032
requestExit();
10291033
mWaitWorkCV.signal();
10301034
}
1035+
// When Thread::requestExitAndWait is made virtual and this method is renamed to
1036+
// "virtual status_t requestExitAndWait()", replace by "return Thread::requestExitAndWait();"
10311037
requestExitAndWait();
10321038
}
10331039

@@ -4516,7 +4522,7 @@ status_t AudioFlinger::RecordThread::start(RecordThread::RecordTrack* recordTrac
45164522
ALOGV("Signal record thread");
45174523
mWaitWorkCV.signal();
45184524
// do not wait for mStartStopCond if exiting
4519-
if (mExiting) {
4525+
if (exitPending()) {
45204526
mActiveTrack.clear();
45214527
status = INVALID_OPERATION;
45224528
goto startError;
@@ -4543,7 +4549,7 @@ void AudioFlinger::RecordThread::stop(RecordThread::RecordTrack* recordTrack) {
45434549
if (mActiveTrack != 0 && recordTrack == mActiveTrack.get()) {
45444550
mActiveTrack->mState = TrackBase::PAUSING;
45454551
// do not wait for mStartStopCond if exiting
4546-
if (mExiting) {
4552+
if (exitPending()) {
45474553
return;
45484554
}
45494555
mStartStopCond.wait(mLock);
@@ -4989,6 +4995,8 @@ status_t AudioFlinger::closeOutput(audio_io_handle_t output)
49894995
mPlaybackThreads.removeItem(output);
49904996
}
49914997
thread->exit();
4998+
// The thread entity (active unit of execution) is no longer running here,
4999+
// but the ThreadBase container still exists.
49925000

49935001
if (thread->type() != ThreadBase::DUPLICATING) {
49945002
AudioStreamOut *out = thread->clearOutput();
@@ -5132,6 +5140,8 @@ status_t AudioFlinger::closeInput(audio_io_handle_t input)
51325140
mRecordThreads.removeItem(input);
51335141
}
51345142
thread->exit();
5143+
// The thread entity (active unit of execution) is no longer running here,
5144+
// but the ThreadBase container still exists.
51355145

51365146
AudioStreamIn *in = thread->clearInput();
51375147
assert(in != NULL);

services/audioflinger/AudioFlinger.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,8 @@ class AudioFlinger :
401401
audio_format_t format() const { return mFormat; }
402402
size_t frameCount() const { return mFrameCount; }
403403
void wakeUp() { mWaitWorkCV.broadcast(); }
404+
// Should be "virtual status_t requestExitAndWait()" and override same
405+
// method in Thread, but Thread::requestExitAndWait() is not yet virtual.
404406
void exit();
405407
virtual bool checkForNewParameters_l() = 0;
406408
virtual status_t setParameters(const String8& keyValuePairs);
@@ -532,7 +534,6 @@ class AudioFlinger :
532534
Vector<ConfigEvent> mConfigEvents;
533535
bool mStandby;
534536
const audio_io_handle_t mId;
535-
bool mExiting;
536537
Vector< sp<EffectChain> > mEffectChains;
537538
uint32_t mDevice; // output device for PlaybackThread
538539
// input + output devices for RecordThread

0 commit comments

Comments
 (0)