From e010f65e6337267cb15f8894c950a3f64370dd36 Mon Sep 17 00:00:00 2001 From: Haynes Mathew George Date: Fri, 13 Dec 2013 15:40:13 -0800 Subject: audioflinger: Fix for a deadlock in track creation AudioFlinger enters a deadlock (with itself) on trying to free a RecordTrack or Track object that failed initialization. Clear this bad object from the caller instead. Bug: 12423233 Change-Id: I926f2beb922a70f6924e593e2bbf1a5b5df85b16 --- services/audioflinger/AudioFlinger.cpp | 4 +++- services/audioflinger/Threads.cpp | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'services') diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 3132e54..acbd19a 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -513,6 +513,8 @@ sp AudioFlinger::createTrack( track = thread->createTrack_l(client, streamType, sampleRate, format, channelMask, frameCount, sharedBuffer, lSessionId, flags, tid, clientUid, &lStatus); + LOG_ALWAYS_FATAL_IF((lStatus == NO_ERROR) && (track == 0)); + // we don't abort yet if lStatus != NO_ERROR; there is still work to be done regardless // move effect chain to this output thread if an effect on same session was waiting // for a track to be created @@ -1291,7 +1293,7 @@ sp AudioFlinger::openRecord( frameCount, lSessionId, IPCThreadState::self()->getCallingUid(), flags, tid, &lStatus); - LOG_ALWAYS_FATAL_IF((recordTrack != 0) != (lStatus == NO_ERROR)); + LOG_ALWAYS_FATAL_IF((lStatus == NO_ERROR) && (recordTrack == 0)); } if (lStatus != NO_ERROR) { // remove local strong reference to Client before deleting the RecordTrack so that the diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index bf85b51..64d7ec3 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -1326,8 +1326,10 @@ sp AudioFlinger::PlaybackThread::createTrac track = TimedTrack::create(this, client, streamType, sampleRate, format, channelMask, frameCount, sharedBuffer, sessionId, uid); } + if (track == 0 || track->getCblk() == NULL || track->name() < 0) { lStatus = NO_MEMORY; + // track must be cleared from the caller as the caller has the AF lock goto Exit; } @@ -4742,7 +4744,7 @@ sp AudioFlinger::RecordThread::createR if (track->getCblk() == 0) { ALOGE("createRecordTrack_l() no control block"); lStatus = NO_MEMORY; - track.clear(); + // track must be cleared from the caller as the caller has the AF lock goto Exit; } mTracks.add(track); -- cgit v1.1