Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit da639f54 authored by Glenn Kasten's avatar Glenn Kasten Committed by Android (Google) Code Review
Browse files

Merge "Simplify ThreadBase::exit() aka requestExitAndWait"

parents 6f5f9ce7 761286f6
Loading
Loading
Loading
Loading
+18 −8
Original line number Diff line number Diff line
@@ -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);
+2 −1
Original line number Diff line number Diff line
@@ -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