AudioFlinger: defer restartIfDisabled()
Defer restartIfDisabled() to the end of
the threadLoop worker thread, allowing execution
without any mutexes held. This prevents mutex
order issues.
To accomplish this, we add a DeferredExecutor object
to ThreadBase, which allows adding functors and dtors
to execute at the end of the worker loop,
where no mutexes are held.
Test: atest AudioPlaybackCaptureTest
Bug: 345400492
Bug: 345676143
Change-Id: I1d7f491fc1289882ce67cb7289b3bc1b58e81d23
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 2b17e92..98faf38 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -4582,7 +4582,11 @@
// FIXME Note that the above .clear() is no longer necessary since effectChains
// is now local to this block, but will keep it for now (at least until merge done).
+
+ mThreadloopExecutor.process();
}
+ mThreadloopExecutor.process(); // process any remaining deferred actions.
+ // deferred actions after this point are ignored.
threadLoop_exit();
@@ -8732,11 +8736,14 @@
mIoJitterMs.add(jitterMs);
mProcessTimeMs.add(processMs);
}
+ mThreadloopExecutor.process();
// update timing info.
mLastIoBeginNs = lastIoBeginNs;
mLastIoEndNs = lastIoEndNs;
lastLoopCountRead = loopCount;
}
+ mThreadloopExecutor.process(); // process any remaining deferred actions.
+ // deferred actions after this point are ignored.
standbyIfNotAlreadyInStandby();
@@ -10522,7 +10529,10 @@
unlockEffectChains(effectChains);
// Effect chains will be actually deleted here if they were removed from
// mEffectChains list during mixing or effects processing
+ mThreadloopExecutor.process();
}
+ mThreadloopExecutor.process(); // process any remaining deferred actions.
+ // deferred actions after this point are ignored.
threadLoop_exit();