Loading services/audioflinger/AudioFlinger.cpp +4 −2 Original line number Diff line number Diff line Loading @@ -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)); } Loading services/audioflinger/PatchPanel.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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); } Loading services/audioflinger/PatchPanel.h +3 −3 Original line number Diff line number Diff line Loading @@ -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(); } Loading services/audioflinger/Threads.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -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); Loading services/audioflinger/TrackBase.h +10 −1 Original line number Diff line number Diff line Loading @@ -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 Loading
services/audioflinger/AudioFlinger.cpp +4 −2 Original line number Diff line number Diff line Loading @@ -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)); } Loading
services/audioflinger/PatchPanel.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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); } Loading
services/audioflinger/PatchPanel.h +3 −3 Original line number Diff line number Diff line Loading @@ -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(); } Loading
services/audioflinger/Threads.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
services/audioflinger/TrackBase.h +10 −1 Original line number Diff line number Diff line Loading @@ -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