Merge "audiohal: Make closing of effects and streams fast"
diff --git a/audio/2.0/default/StreamIn.cpp b/audio/2.0/default/StreamIn.cpp
index 1cde4ac..9c49170 100644
--- a/audio/2.0/default/StreamIn.cpp
+++ b/audio/2.0/default/StreamIn.cpp
@@ -16,10 +16,12 @@
 
 #define LOG_TAG "StreamInHAL"
 //#define LOG_NDEBUG 0
+#define ATRACE_TAG ATRACE_TAG_AUDIO
 
 #include <android/log.h>
 #include <hardware/audio.h>
 #include <mediautils/SchedulingPolicyService.h>
+#include <utils/Trace.h>
 
 #include "StreamIn.h"
 
@@ -156,7 +158,18 @@
 }
 
 StreamIn::~StreamIn() {
+    ATRACE_CALL();
     close();
+    if (mReadThread.get()) {
+        ATRACE_NAME("mReadThread->join");
+        status_t status = mReadThread->join();
+        ALOGE_IF(status, "read thread exit error: %s", strerror(-status));
+    }
+    if (mEfGroup) {
+        status_t status = EventFlag::deleteEventFlag(&mEfGroup);
+        ALOGE_IF(status, "read MQ event flag deletion error: %s", strerror(-status));
+    }
+    mDevice->close_input_stream(mDevice, mStream);
     mStream = nullptr;
     mDevice = nullptr;
 }
@@ -276,14 +289,10 @@
     mIsClosed = true;
     if (mReadThread.get()) {
         mStopReadThread.store(true, std::memory_order_release);
-        status_t status = mReadThread->requestExitAndWait();
-        ALOGE_IF(status, "read thread exit error: %s", strerror(-status));
     }
     if (mEfGroup) {
-        status_t status = EventFlag::deleteEventFlag(&mEfGroup);
-        ALOGE_IF(status, "read MQ event flag deletion error: %s", strerror(-status));
+        mEfGroup->wake(static_cast<uint32_t>(MessageQueueFlagBits::NOT_FULL));
     }
-    mDevice->close_input_stream(mDevice, mStream);
     return Result::OK;
 }
 
diff --git a/audio/2.0/default/StreamOut.cpp b/audio/2.0/default/StreamOut.cpp
index 084a1c3..6e46db2 100644
--- a/audio/2.0/default/StreamOut.cpp
+++ b/audio/2.0/default/StreamOut.cpp
@@ -16,10 +16,12 @@
 
 #define LOG_TAG "StreamOutHAL"
 //#define LOG_NDEBUG 0
+#define ATRACE_TAG ATRACE_TAG_AUDIO
 
 #include <android/log.h>
 #include <hardware/audio.h>
 #include <mediautils/SchedulingPolicyService.h>
+#include <utils/Trace.h>
 
 #include "StreamOut.h"
 
@@ -157,7 +159,19 @@
 }
 
 StreamOut::~StreamOut() {
+    ATRACE_CALL();
     close();
+    if (mWriteThread.get()) {
+        ATRACE_NAME("mWriteThread->join");
+        status_t status = mWriteThread->join();
+        ALOGE_IF(status, "write thread exit error: %s", strerror(-status));
+    }
+    if (mEfGroup) {
+        status_t status = EventFlag::deleteEventFlag(&mEfGroup);
+        ALOGE_IF(status, "write MQ event flag deletion error: %s", strerror(-status));
+    }
+    mCallback.clear();
+    mDevice->close_output_stream(mDevice, mStream);
     mStream = nullptr;
     mDevice = nullptr;
 }
@@ -261,15 +275,10 @@
     mIsClosed = true;
     if (mWriteThread.get()) {
         mStopWriteThread.store(true, std::memory_order_release);
-        status_t status = mWriteThread->requestExitAndWait();
-        ALOGE_IF(status, "write thread exit error: %s", strerror(-status));
     }
     if (mEfGroup) {
-        status_t status = EventFlag::deleteEventFlag(&mEfGroup);
-        ALOGE_IF(status, "write MQ event flag deletion error: %s", strerror(-status));
+        mEfGroup->wake(static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY));
     }
-    mCallback.clear();
-    mDevice->close_output_stream(mDevice, mStream);
     return Result::OK;
 }
 
diff --git a/audio/effect/2.0/default/Effect.cpp b/audio/effect/2.0/default/Effect.cpp
index 3c97fc4..0a4aeb7 100644
--- a/audio/effect/2.0/default/Effect.cpp
+++ b/audio/effect/2.0/default/Effect.cpp
@@ -17,8 +17,11 @@
 #include <memory.h>
 
 #define LOG_TAG "EffectHAL"
+#define ATRACE_TAG ATRACE_TAG_AUDIO
+
 #include <android/log.h>
 #include <media/EffectsFactoryApi.h>
+#include <utils/Trace.h>
 
 #include "Conversions.h"
 #include "Effect.h"
@@ -78,8 +81,9 @@
                 static_cast<uint32_t>(MessageQueueFlagBits::REQUEST_PROCESS_ALL),
                 &efState,
                 NS_PER_SEC);
-        if (!(efState & static_cast<uint32_t>(MessageQueueFlagBits::REQUEST_PROCESS_ALL))) {
-            continue;  // Nothing to do.
+        if (!(efState & static_cast<uint32_t>(MessageQueueFlagBits::REQUEST_PROCESS_ALL))
+                || (efState & static_cast<uint32_t>(MessageQueueFlagBits::REQUEST_QUIT))) {
+            continue;  // Nothing to do or time to quit.
         }
         Result retval = Result::OK;
         if (efState & static_cast<uint32_t>(MessageQueueFlagBits::REQUEST_PROCESS_REVERSE)
@@ -134,7 +138,23 @@
 }
 
 Effect::~Effect() {
+    ATRACE_CALL();
     close();
+    if (mProcessThread.get()) {
+        ATRACE_NAME("mProcessThread->join");
+        status_t status = mProcessThread->join();
+        ALOGE_IF(status, "processing thread exit error: %s", strerror(-status));
+    }
+    if (mEfGroup) {
+        status_t status = EventFlag::deleteEventFlag(&mEfGroup);
+        ALOGE_IF(status, "processing MQ event flag deletion error: %s", strerror(-status));
+    }
+    mInBuffer.clear();
+    mOutBuffer.clear();
+    int status = EffectRelease(mHandle);
+    ALOGW_IF(status, "Error releasing effect %p: %s", mHandle, strerror(-status));
+    EffectMap::getInstance().remove(mHandle);
+    mHandle = 0;
 }
 
 // static
@@ -731,19 +751,10 @@
     mIsClosed = true;
     if (mProcessThread.get()) {
         mStopProcessThread.store(true, std::memory_order_release);
-        status_t status = mProcessThread->requestExitAndWait();
-        ALOGE_IF(status, "processing thread exit error: %s", strerror(-status));
     }
     if (mEfGroup) {
-        status_t status = EventFlag::deleteEventFlag(&mEfGroup);
-        ALOGE_IF(status, "processing MQ event flag deletion error: %s", strerror(-status));
+        mEfGroup->wake(static_cast<uint32_t>(MessageQueueFlagBits::REQUEST_QUIT));
     }
-    mInBuffer.clear();
-    mOutBuffer.clear();
-    int status = EffectRelease(mHandle);
-    ALOGW_IF(status, "Error releasing effect %p: %s", mHandle, strerror(-status));
-    EffectMap::getInstance().remove(mHandle);
-    mHandle = 0;
     return Result::OK;
 }
 
diff --git a/audio/effect/2.0/types.hal b/audio/effect/2.0/types.hal
index 0cac59a..0626ec5 100644
--- a/audio/effect/2.0/types.hal
+++ b/audio/effect/2.0/types.hal
@@ -293,5 +293,7 @@
     DONE_PROCESSING = 1 << 0,
     REQUEST_PROCESS = 1 << 1,
     REQUEST_PROCESS_REVERSE = 1 << 2,
-    REQUEST_PROCESS_ALL = REQUEST_PROCESS | REQUEST_PROCESS_REVERSE
+    REQUEST_QUIT = 1 << 3,
+    REQUEST_PROCESS_ALL =
+        REQUEST_PROCESS | REQUEST_PROCESS_REVERSE | REQUEST_QUIT
 };