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
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index f9cc17b..e36dba0 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -559,7 +559,7 @@
track = thread->createTrack_l(client, streamType, sampleRate, format,
channelMask, frameCount, sharedBuffer, lSessionId, flags, tid, clientUid, &lStatus);
- LOG_ALWAYS_FATAL_IF((track != 0) != (lStatus == NO_ERROR));
+ 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
@@ -1340,7 +1340,7 @@
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) {
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 2b37761..81b37a1 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1342,7 +1342,7 @@
lStatus = track != 0 ? track->initCheck() : (status_t) NO_MEMORY;
if (lStatus != NO_ERROR) {
ALOGE("createTrack_l() initCheck failed %d; no control block?", lStatus);
- track.clear();
+ // track must be cleared from the caller as the caller has the AF lock
goto Exit;
}
@@ -4855,7 +4855,7 @@
lStatus = track->initCheck();
if (lStatus != NO_ERROR) {
ALOGE("createRecordTrack_l() initCheck failed %d; no control block?", lStatus);
- track.clear();
+ // track must be cleared from the caller as the caller has the AF lock
goto Exit;
}
mTracks.add(track);