Merge "PatchPanel: Keep peer alive during use."

gugelfrei
Andy Hung 5 years ago committed by Android (Google) Code Review
commit e361ec05a0

@ -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));
}

@ -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);
}

@ -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(); }

@ -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);

@ -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{};

@ -1723,6 +1723,7 @@ AudioFlinger::PlaybackThread::PatchTrack::PatchTrack(PlaybackThread *playbackThr
AudioFlinger::PlaybackThread::PatchTrack::~PatchTrack()
{
ALOGV("%s(%d)", __func__, mId);
}
status_t AudioFlinger::PlaybackThread::PatchTrack::start(AudioSystem::sync_event_t event,
@ -2193,6 +2194,7 @@ AudioFlinger::RecordThread::PatchRecord::PatchRecord(RecordThread *recordThread,
AudioFlinger::RecordThread::PatchRecord::~PatchRecord()
{
ALOGV("%s(%d)", __func__, mId);
}
// AudioBufferProvider interface

Loading…
Cancel
Save