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

Commit e361ec05 authored by Andy Hung's avatar Andy Hung Committed by Android (Google) Code Review
Browse files

Merge "PatchPanel: Keep peer alive during use."

parents f920def4 abfab20f
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -836,8 +836,10 @@ sp<IAudioTrack> AudioFlinger::createTrack(const CreateTrackInput& input,
                }
                teePatches.push_back({patchRecord, patchTrack});
                secondaryThread->addPatchTrack(patchTrack);
                patchTrack->setPeerProxy(patchRecord.get());
                patchRecord->setPeerProxy(patchTrack.get());
                // In case the downstream patchTrack on the secondaryThread temporarily outlives
                // our created track, ensure the corresponding patchRecord is still alive.
                patchTrack->setPeerProxy(patchRecord, true /* holdReference */);
                patchRecord->setPeerProxy(patchTrack, false /* holdReference */);
            }
            track->setTeePatches(std::move(teePatches));
        }
+3 −2
Original line number Diff line number Diff line
@@ -527,8 +527,8 @@ status_t AudioFlinger::PatchPanel::Patch::createConnections(PatchPanel *panel)
    }

    // tie playback and record tracks together
    mRecord.setTrackAndPeer(tempRecordTrack, tempPatchTrack.get());
    mPlayback.setTrackAndPeer(tempPatchTrack, tempRecordTrack.get());
    mRecord.setTrackAndPeer(tempRecordTrack, tempPatchTrack);
    mPlayback.setTrackAndPeer(tempPatchTrack, tempRecordTrack);

    // start capture and playback
    mRecord.track()->start(AudioSystem::SYNC_EVENT_NONE, AUDIO_SESSION_NONE);
@@ -543,6 +543,7 @@ void AudioFlinger::PatchPanel::Patch::clearConnections(PatchPanel *panel)
            __func__, mRecord.handle(), mPlayback.handle());
    mRecord.stopTrack();
    mPlayback.stopTrack();
    mRecord.track()->clearPeerProxy(); // mRecord stop is synchronous. Break PeerProxy sp<> cycle.
    mRecord.closeConnections(panel);
    mPlayback.closeConnections(panel);
}
+3 −3
Original line number Diff line number Diff line
@@ -122,11 +122,11 @@ private:
            mThread = thread;
            mCloseThread = closeThread;
        }
        void setTrackAndPeer(const sp<TrackType>& track,
                             ThreadBase::PatchProxyBufferProvider *peer) {
        template <typename T>
        void setTrackAndPeer(const sp<TrackType>& track, const sp<T> &peer) {
            mTrack = track;
            mThread->addPatchTrack(mTrack);
            mTrack->setPeerProxy(peer);
            mTrack->setPeerProxy(peer, true /* holdReference */);
        }
        void stopTrack() { if (mTrack) mTrack->stop(); }

+2 −0
Original line number Diff line number Diff line
@@ -7683,6 +7683,8 @@ bool AudioFlinger::RecordThread::stop(RecordThread::RecordTrack* recordTrack) {
    // note that threadLoop may still be processing the track at this point [without lock]
    recordTrack->mState = TrackBase::PAUSING;

    // NOTE: Waiting here is important to keep stop synchronous.
    // This is needed for proper patchRecord peer release.
    while (recordTrack->mState == TrackBase::PAUSING && !recordTrack->isInvalid()) {
        mWaitWorkCV.broadcast(); // signal thread to stop
        mStartStopCond.wait(mLock);
+10 −1
Original line number Diff line number Diff line
@@ -337,10 +337,19 @@ public:
                        PatchTrackBase(sp<ClientProxy> proxy, const ThreadBase& thread,
                                       const Timeout& timeout);
            void        setPeerTimeout(std::chrono::nanoseconds timeout);
            void        setPeerProxy(PatchProxyBufferProvider *proxy) { mPeerProxy = proxy; }
            template <typename T>
            void        setPeerProxy(const sp<T> &proxy, bool holdReference) {
                            mPeerReferenceHold = holdReference ? proxy : nullptr;
                            mPeerProxy = proxy.get();
                        }
            void        clearPeerProxy() {
                            mPeerReferenceHold.clear();
                            mPeerProxy = nullptr;
                        }

protected:
    const sp<ClientProxy>       mProxy;
    sp<RefBase>                 mPeerReferenceHold;   // keeps mPeerProxy alive during access.
    PatchProxyBufferProvider*   mPeerProxy = nullptr;
    struct timespec             mPeerTimeout{};

Loading