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/IAfThread.h b/services/audioflinger/IAfThread.h
index c2a58c6..74fc62f 100644
--- a/services/audioflinger/IAfThread.h
+++ b/services/audioflinger/IAfThread.h
@@ -19,8 +19,9 @@
 #include <android/media/IAudioTrackCallback.h>
 #include <android/media/IEffectClient.h>
 #include <audiomanager/IAudioManager.h>
-#include <audio_utils/mutex.h>
+#include <audio_utils/DeferredExecutor.h>
 #include <audio_utils/MelProcessor.h>
+#include <audio_utils/mutex.h>
 #include <binder/MemoryDealer.h>
 #include <datapath/AudioStreamIn.h>
 #include <datapath/AudioStreamOut.h>
@@ -394,6 +395,12 @@
     // avoid races.
     virtual void waitWhileThreadBusy_l(audio_utils::unique_lock& ul)
             REQUIRES(mutex()) = 0;
+
+    // The ThreadloopExecutor is used to defer functors or dtors
+    // to when the Threadloop does not hold any mutexes (at the end of the
+    // processing period cycle).
+    virtual audio_utils::DeferredExecutor& getThreadloopExecutor() = 0;
+
     // Dynamic cast to derived interface
     virtual sp<IAfDirectOutputThread> asIAfDirectOutputThread() { return nullptr; }
     virtual sp<IAfDuplicatingThread> asIAfDuplicatingThread() { return nullptr; }