StreamHalHidl: Use atomic_wp and make pointers const
Avoid concurrency issues with modification of wp.
Test: basic audio
Bug: 177278988
Change-Id: I5b968a1dad24e1d6c18260884d35c3170661da01
diff --git a/media/libaudiohal/impl/StreamHalHidl.h b/media/libaudiohal/impl/StreamHalHidl.h
index 88f8587..8b1c3d3 100644
--- a/media/libaudiohal/impl/StreamHalHidl.h
+++ b/media/libaudiohal/impl/StreamHalHidl.h
@@ -25,6 +25,7 @@
#include <fmq/EventFlag.h>
#include <fmq/MessageQueue.h>
#include <media/audiohal/StreamHalInterface.h>
+#include <mediautils/Synchronization.h>
#include "ConversionHelperHidl.h"
#include "StreamPowerLog.h"
@@ -100,9 +101,6 @@
// Subclasses can not be constructed directly by clients.
explicit StreamHalHidl(IStream *stream);
- // The destructor automatically closes the stream.
- virtual ~StreamHalHidl();
-
status_t getCachedBufferSize(size_t *size);
bool requestHalThreadPriority(pid_t threadPid, pid_t threadId);
@@ -112,7 +110,7 @@
private:
const int HAL_THREAD_PRIORITY_DEFAULT = -1;
- IStream *mStream;
+ IStream * const mStream;
int mHalThreadPriority;
size_t mCachedBufferSize;
};
@@ -184,9 +182,16 @@
typedef MessageQueue<uint8_t, hardware::kSynchronizedReadWrite> DataMQ;
typedef MessageQueue<WriteStatus, hardware::kSynchronizedReadWrite> StatusMQ;
- wp<StreamOutHalInterfaceCallback> mCallback;
- wp<StreamOutHalInterfaceEventCallback> mEventCallback;
- sp<IStreamOut> mStream;
+ // Do not move the Defer. This should be the first member variable in the class;
+ // thus the last member destructor called upon instance destruction.
+ //
+ // The last step is to flush all binder commands so that the AudioFlinger
+ // may recognize the deletion of IStreamOut (mStream) with less delay. See b/35394629.
+ mediautils::Defer mLast{[]() { hardware::IPCThreadState::self()->flushCommands(); }};
+
+ mediautils::atomic_wp<StreamOutHalInterfaceCallback> mCallback;
+ mediautils::atomic_wp<StreamOutHalInterfaceEventCallback> mEventCallback;
+ const sp<IStreamOut> mStream;
std::unique_ptr<CommandMQ> mCommandMQ;
std::unique_ptr<DataMQ> mDataMQ;
std::unique_ptr<StatusMQ> mStatusMQ;
@@ -242,7 +247,14 @@
typedef MessageQueue<uint8_t, hardware::kSynchronizedReadWrite> DataMQ;
typedef MessageQueue<ReadStatus, hardware::kSynchronizedReadWrite> StatusMQ;
- sp<IStreamIn> mStream;
+ // Do not move the Defer. This should be the first member variable in the class;
+ // thus the last member destructor called upon instance destruction.
+ //
+ // The last step is to flush all binder commands so that the AudioFlinger
+ // may recognize the deletion of IStreamIn (mStream) with less delay. See b/35394629.
+ mediautils::Defer mLast{[]() { hardware::IPCThreadState::self()->flushCommands(); }};
+
+ const sp<IStreamIn> mStream;
std::unique_ptr<CommandMQ> mCommandMQ;
std::unique_ptr<DataMQ> mDataMQ;
std::unique_ptr<StatusMQ> mStatusMQ;