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

Commit 7ecc1aea authored by Andy Hung's avatar Andy Hung Committed by Gerrit Code Review
Browse files

Merge "Thread and Track: Update to audio_utils mutex" into main

parents 0fbd59a4 87e82415
Loading
Loading
Loading
Loading
+19 −19
Original line number Diff line number Diff line
@@ -318,7 +318,7 @@ status_t AudioFlinger::updateSecondaryOutputs(
        size_t i = 0;
        for (; i < mPlaybackThreads.size(); ++i) {
            IAfPlaybackThread* thread = mPlaybackThreads.valueAt(i).get();
            Mutex::Autolock _tl(thread->mutex());
            audio_utils::lock_guard _tl(thread->mutex());
            sp<IAfTrack> track = thread->getTrackById_l(trackId);
            if (track != nullptr) {
                ALOGD("%s trackId: %u", __func__, trackId);
@@ -1089,7 +1089,7 @@ status_t AudioFlinger::createTrack(const media::CreateTrackRequest& _input,

        if (lStatus == NO_ERROR) {
            // no risk of deadlock because AudioFlinger::mutex() is held
            Mutex::Autolock _dl(thread->mutex());
            audio_utils::lock_guard _dl(thread->mutex());
            // Connect secondary outputs. Failure on a secondary output must not imped the primary
            // Any secondary output setup failure will lead to a desync between the AP and AF until
            // the track is destroyed.
@@ -1097,7 +1097,7 @@ status_t AudioFlinger::createTrack(const media::CreateTrackRequest& _input,
            // move effect chain to this output thread if an effect on same session was waiting
            // for a track to be created
            if (effectThread != nullptr) {
                Mutex::Autolock _sl(effectThread->mutex());
                audio_utils::lock_guard _sl(effectThread->mutex());
                if (moveEffectChain_l(sessionId, effectThread, thread) == NO_ERROR) {
                    effectThreadId = thread->id();
                    effectIds = thread->getEffectIds_l(sessionId);
@@ -2364,7 +2364,7 @@ status_t AudioFlinger::createRecord(const media::CreateRecordRequest& _input,
        // session and move it to this thread.
        sp<IAfEffectChain> chain = getOrphanEffectChain_l(sessionId);
        if (chain != 0) {
            Mutex::Autolock _l2(thread->mutex());
            audio_utils::lock_guard _l2(thread->mutex());
            thread->addEffectChain_l(chain);
        }
        break;
@@ -3023,8 +3023,8 @@ status_t AudioFlinger::closeOutput_nonvirtual(audio_io_handle_t output)
                        checkPlaybackThread_l(mPlaybackThreads.keyAt(0));
                if (dstThread != NULL) {
                    // audioflinger lock is held so order of thread lock acquisition doesn't matter
                    Mutex::Autolock _dl(dstThread->mutex());
                    Mutex::Autolock _sl(playbackThread->mutex());
                    audio_utils::lock_guard _dl(dstThread->mutex());
                    audio_utils::lock_guard _sl(playbackThread->mutex());
                    Vector<sp<IAfEffectChain>> effectChains = playbackThread->getEffectChains_l();
                    for (size_t i = 0; i < effectChains.size(); i ++) {
                        moveEffectChain_l(effectChains[i]->sessionId(), playbackThread.get(),
@@ -3263,7 +3263,7 @@ status_t AudioFlinger::closeInput_nonvirtual(audio_io_handle_t input)
            // new capture on the same session
            sp<IAfEffectChain> chain;
            {
                Mutex::Autolock _sl(recordThread->mutex());
                audio_utils::lock_guard _sl(recordThread->mutex());
                const Vector<sp<IAfEffectChain>> effectChains = recordThread->getEffectChains_l();
                // Note: maximum one chain per record thread
                if (effectChains.size() != 0) {
@@ -3281,7 +3281,7 @@ status_t AudioFlinger::closeInput_nonvirtual(audio_io_handle_t input)
                        continue;
                    }
                    if (t->hasAudioSession(chain->sessionId()) != 0) {
                        Mutex::Autolock _l2(t->mutex());
                        audio_utils::lock_guard _l2(t->mutex());
                        ALOGV("closeInput() found thread %d for effect session %d",
                              t->id(), chain->sessionId());
                        t->addEffectChain_l(chain);
@@ -3465,7 +3465,7 @@ std::vector<sp<IAfEffectModule>> AudioFlinger::purgeStaleEffects_l() {

    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
        sp<IAfPlaybackThread> t = mPlaybackThreads.valueAt(i);
        Mutex::Autolock _l(t->mutex());
        audio_utils::lock_guard _l(t->mutex());
        const Vector<sp<IAfEffectChain>> threadChains = t->getEffectChains_l();
        for (size_t j = 0; j < threadChains.size(); j++) {
            sp<IAfEffectChain> ec = threadChains[j];
@@ -3477,7 +3477,7 @@ std::vector<sp<IAfEffectModule>> AudioFlinger::purgeStaleEffects_l() {

    for (size_t i = 0; i < mRecordThreads.size(); i++) {
        sp<IAfRecordThread> t = mRecordThreads.valueAt(i);
        Mutex::Autolock _l(t->mutex());
        audio_utils::lock_guard _l(t->mutex());
        const Vector<sp<IAfEffectChain>> threadChains = t->getEffectChains_l();
        for (size_t j = 0; j < threadChains.size(); j++) {
            sp<IAfEffectChain> ec = threadChains[j];
@@ -3487,7 +3487,7 @@ std::vector<sp<IAfEffectModule>> AudioFlinger::purgeStaleEffects_l() {

    for (size_t i = 0; i < mMmapThreads.size(); i++) {
        const sp<IAfMmapThread> t = mMmapThreads.valueAt(i);
        Mutex::Autolock _l(t->mutex());
        audio_utils::lock_guard _l(t->mutex());
        const Vector<sp<IAfEffectChain>> threadChains = t->getEffectChains_l();
        for (size_t j = 0; j < threadChains.size(); j++) {
            sp<IAfEffectChain> ec = threadChains[j];
@@ -3515,7 +3515,7 @@ std::vector<sp<IAfEffectModule>> AudioFlinger::purgeStaleEffects_l() {
            }
        }
        if (!found) {
            Mutex::Autolock _l(t->mutex());
            audio_utils::lock_guard _l(t->mutex());
            // remove all effects from the chain
            while (ec->numberOfEffects()) {
                sp<IAfEffectModule> effect = ec->getEffectModule(0);
@@ -3747,7 +3747,7 @@ void AudioFlinger::updateSecondaryOutputsForTrack_l(
        // The frameCount should also not be smaller than the secondary thread min frame
        // count
        size_t minFrameCount = AudioSystem::calculateMinFrameCount(
                    [&] { Mutex::Autolock _l(secondaryThread->mutex());
                    [&] { audio_utils::lock_guard _l(secondaryThread->mutex());
                          return secondaryThread->latency_l(); }(),
                    secondaryThread->frameCount(), // normal frame count
                    secondaryThread->sampleRate(),
@@ -4193,7 +4193,7 @@ status_t AudioFlinger::createEffect(const media::CreateEffectRequest& request,
            // session and used it instead of creating a new one.
            sp<IAfEffectChain> chain = getOrphanEffectChain_l(sessionId);
            if (chain != 0) {
                Mutex::Autolock _l2(thread->mutex());
                audio_utils::lock_guard _l2(thread->mutex());
                thread->addEffectChain_l(chain);
            }
        }
@@ -4285,8 +4285,8 @@ status_t AudioFlinger::moveEffects(audio_session_t sessionId, audio_io_handle_t
        return BAD_VALUE;
    }

    Mutex::Autolock _dl(dstThread->mutex());
    Mutex::Autolock _sl(srcThread->mutex());
    audio_utils::lock_guard _dl(dstThread->mutex());
    audio_utils::lock_guard _sl(srcThread->mutex());
    return moveEffectChain_l(sessionId, srcThread, dstThread);
}

@@ -4301,7 +4301,7 @@ void AudioFlinger::setEffectSuspended(int effectId,
    if (thread == nullptr) {
      return;
    }
    Mutex::Autolock _sl(thread->mutex());
    audio_utils::lock_guard _sl(thread->mutex());
    sp<IAfEffectModule> effect = thread->getEffect_l(sessionId, effectId);
    thread->setEffectSuspended_l(&effect->desc().type, suspended, sessionId);
}
@@ -4426,8 +4426,8 @@ status_t AudioFlinger::moveAuxEffectToIo(int EffectId,
    const sp<IAfPlaybackThread> thread = threadBase ? threadBase->asIAfPlaybackThread() : nullptr;

    if (EffectId != 0 && thread != 0 && dstThread != thread.get()) {
        Mutex::Autolock _dl(dstThread->mutex());
        Mutex::Autolock _sl(thread->mutex());
        audio_utils::lock_guard _dl(dstThread->mutex());
        audio_utils::lock_guard _sl(thread->mutex());
        sp<IAfEffectChain> srcChain = thread->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX);
        sp<IAfEffectChain> dstChain;
        if (srcChain == 0) {
+1 −2
Original line number Diff line number Diff line
@@ -31,7 +31,6 @@
#include <media/audiohal/StreamHalInterface.h>
#include <media/nblog/NBLog.h>
#include <timing/SyncEvent.h>
#include <utils/Mutex.h>
#include <utils/RefBase.h>
#include <vibrator/ExternalVibration.h>

@@ -311,7 +310,7 @@ public:
    // deliver stats to mediametrics.
    virtual void sendStatistics(bool force) = 0;

    virtual Mutex& mutex() const = 0;
    virtual audio_utils::mutex& mutex() const = 0;

    virtual void onEffectEnable(const sp<IAfEffectModule>& effect) = 0;
    virtual void onEffectDisable() = 0;
+2 −1
Original line number Diff line number Diff line
@@ -468,7 +468,8 @@ private:
     */
    SourceMetadatas mTrackMetadatas;
    /** Protects mTrackMetadatas against concurrent access. */
    mutable audio_utils::mutex mTrackMetadatasMutex;
    audio_utils::mutex& trackMetadataMutex() const { return mTrackMetadataMutex; }
    mutable audio_utils::mutex mTrackMetadataMutex;
};  // end of OutputTrack

// playback track, used by PatchPanel
+208 −206

File changed.

Preview size limit exceeded, changes collapsed.

+29 −25
Original line number Diff line number Diff line
@@ -77,20 +77,20 @@ public:

    // Config event sequence by client if status needed (e.g binder thread calling setParameters()):
    //  1. create SetParameterConfigEvent. This sets mWaitStatus in config event
    //  2. Lock mLock
    //  2. Lock mutex()
    //  3. Call sendConfigEvent_l(): Append to mConfigEvents and mWaitWorkCV.signal
    //  4. sendConfigEvent_l() reads status from event->mStatus;
    //  5. sendConfigEvent_l() returns status
    //  6. Unlock
    //
    // Parameter sequence by server: threadLoop calling processConfigEvents_l():
    // 1. Lock mLock
    // 1. Lock mutex()
    // 2. If there is an entry in mConfigEvents proceed ...
    // 3. Read first entry in mConfigEvents
    // 4. Remove first entry from mConfigEvents
    // 5. Process
    // 6. Set event->mStatus
    // 7. event->mCond.signal
    // 7. event->mCondition.notify_one()
    // 8. Unlock

    class ConfigEvent: public RefBase {
@@ -103,9 +103,10 @@ public:
            }
        }

        audio_utils::mutex& mutex() const { return mMutex; }
        const int mType; // event type e.g. CFG_EVENT_IO
        Mutex mLock;     // mutex associated with mCond
        Condition mCond; // condition for status return
        mutable audio_utils::mutex mMutex; // mutex associated with mCondition
        audio_utils::condition_variable mCondition; // condition for status return
        status_t mStatus; // status communicated to sender
        bool mWaitStatus; // true if sender is waiting for status
        bool mRequiresSystemReady; // true if must wait for system ready to enter event queue
@@ -322,7 +323,7 @@ public:
    void exit() final;
    status_t setParameters(const String8& keyValuePairs) final;

                // sendConfigEvent_l() must be called with ThreadBase::mLock held
                // sendConfigEvent_l() must be called with ThreadBase::mutex() held
                // Can temporarily release the lock if waiting for a reply from
                // processConfigEvents_l().
    status_t sendConfigEvent_l(sp<ConfigEvent>& event);
@@ -439,7 +440,7 @@ public:
    // TODO(b/291317898) - remove hasAudioSession_l below.
    uint32_t hasAudioSession_l(audio_session_t sessionId) const override = 0;
    uint32_t hasAudioSession(audio_session_t sessionId) const final {
                    Mutex::Autolock _l(mLock);
                    std::lock_guard _l(mutex());
                    return hasAudioSession_l(sessionId);
                }

@@ -507,19 +508,19 @@ public:
                // deliver stats to mediametrics.
    void sendStatistics(bool force) final;

    Mutex& mutex() const final {
        return mLock;
    audio_utils::mutex& mutex() const final {
        return mMutex;
    }
    mutable     Mutex                   mLock;
    mutable audio_utils::mutex mMutex;

    void onEffectEnable(const sp<IAfEffectModule>& effect) final;
    void onEffectDisable() final;

                // invalidateTracksForAudioSession_l must be called with holding mLock.
                // invalidateTracksForAudioSession_l must be called with holding mutex().
    void invalidateTracksForAudioSession_l(audio_session_t /* sessionId */) const override {}
                // Invalidate all the tracks with the given audio session.
    void invalidateTracksForAudioSession(audio_session_t sessionId) const final {
                    Mutex::Autolock _l(mLock);
                    std::lock_guard _l(mutex());
                    invalidateTracksForAudioSession_l(sessionId);
                }

@@ -599,7 +600,7 @@ protected:
                const type_t            mType;

                // Used by parameters, config events, addTrack_l, exit
                Condition               mWaitWorkCV;
                audio_utils::condition_variable mWaitWorkCV;

                const sp<IAfThreadCallback>  mAfThreadCallback;
                ThreadMetrics           mThreadMetrics;
@@ -1041,7 +1042,7 @@ public:
                }

    void setDownStreamPatch(const struct audio_patch* patch) final {
                    Mutex::Autolock _l(mLock);
                    std::lock_guard _l(mutex());
                    mDownStreamPatch = *patch;
                }

@@ -1067,7 +1068,7 @@ public:
    void stopMelComputation_l() override;

    void setStandby() final {
                    Mutex::Autolock _l(mLock);
                    std::lock_guard _l(mutex());
                    setStandby_l();
                }

@@ -1079,7 +1080,7 @@ public:
                }

    bool waitForHalStart() final {
                    Mutex::Autolock _l(mLock);
                    audio_utils::unique_lock _l(mutex());
                    static const nsecs_t kWaitHalTimeoutNs = seconds(2);
                    nsecs_t endWaitTimetNs = systemTime() + kWaitHalTimeoutNs;
                    while (!mHalStarted) {
@@ -1088,7 +1089,7 @@ public:
                            break;
                        }
                        nsecs_t waitTimeLeftNs = endWaitTimetNs - timeNs;
                        mWaitHalStartCV.waitRelative(mLock, waitTimeLeftNs);
                        mWaitHalStartCV.wait_for(_l, std::chrono::nanoseconds(waitTimeLeftNs));
                    }
                    return mHalStarted;
                }
@@ -1369,7 +1370,8 @@ protected:

    sp<AsyncCallbackThread>         mCallbackThread;

    Mutex                                    mAudioTrackCbLock;
    audio_utils::mutex& audioTrackCbMutex() const { return mAudioTrackCbMutex; }
    mutable audio_utils::mutex mAudioTrackCbMutex;
    // Record of IAudioTrackCallback
    std::map<sp<IAfTrack>, sp<media::IAudioTrackCallback>> mAudioTrackCallbacks;

@@ -1390,7 +1392,7 @@ protected:

    // output stream start detection based on render position returned by the kernel
    // condition signalled when the output stream has started
    Condition                mWaitHalStartCV;
    audio_utils::condition_variable mWaitHalStartCV;
    // true when the output stream render position has moved, reset to false in standby
    bool                     mHalStarted = false;
    // last kernel render position saved when entering standby
@@ -1717,9 +1719,11 @@ private:
    // setDraining(). The sequence is shifted one bit to the left and the lsb is used
    // to indicate that the callback has been received via resetDraining()
    uint32_t                   mDrainSequence;
    Condition                  mWaitWorkCV;
    Mutex                      mLock;
    audio_utils::condition_variable mWaitWorkCV;
    mutable audio_utils::mutex mMutex;
    bool                       mAsyncError;

    audio_utils::mutex& mutex() const { return mMutex; }
};

class DuplicatingThread : public MixerThread, public IAfDuplicatingThread {
@@ -1976,10 +1980,10 @@ private:
            Source                              *mSource;
            SortedVector <sp<IAfRecordTrack>>    mTracks;
            // mActiveTracks has dual roles:  it indicates the current active track(s), and
            // is used together with mStartStopCond to indicate start()/stop() progress
            // is used together with mStartStopCV to indicate start()/stop() progress
            ActiveTracks<IAfRecordTrack>           mActiveTracks;

            Condition                           mStartStopCond;
            audio_utils::condition_variable mStartStopCV;

            // resampler converts input at HAL Hz to output at AudioRecord client Hz
            void                               *mRsmpInBuffer;  // size = mRsmpInFramesOA
@@ -2081,7 +2085,7 @@ class MmapThread : public ThreadBase, public virtual IAfMmapThread
    virtual void threadLoop_exit() final;
    virtual void threadLoop_standby() final;
    virtual bool shouldStandby_l() final { return false; }
    virtual status_t exitStandby_l() REQUIRES(mLock);
    virtual status_t exitStandby_l() REQUIRES(mutex());

    status_t initCheck() const final { return mHalStream == nullptr ? NO_INIT : NO_ERROR; }
    size_t frameCount() const final { return mFrameCount; }
@@ -2245,7 +2249,7 @@ public:

    AudioStreamIn* clearInput() final;

    status_t exitStandby_l() REQUIRES(mLock) final;
    status_t exitStandby_l() REQUIRES(mutex()) final;

    MetadataUpdate updateMetadata_l() final;
    void processVolume_l() final;
Loading