StreamOut: use atomic_sp<> for callback thread safety

Test: see bug
Test: basic audio works
Bug: 177278988
Change-Id: Id1f5036e36b2a3b3e71e0b0ec548d4c65a972b50
This commit is contained in:
Andy Hung 2021-01-12 14:54:10 -08:00
parent 2cac3d31d5
commit 6ee09f0457
3 changed files with 6 additions and 4 deletions

View file

@ -51,6 +51,7 @@ cc_defaults {
"libaudio_system_headers",
"libhardware_headers",
"libmedia_headers",
"libmediautils_headers",
],
export_header_lib_headers: [

View file

@ -163,7 +163,7 @@ StreamOut::~StreamOut() {
status_t status = EventFlag::deleteEventFlag(&mEfGroup);
ALOGE_IF(status, "write MQ event flag deletion error: %s", strerror(-status));
}
mCallback.clear();
mCallback = nullptr;
#if MAJOR_VERSION <= 5
mDevice->closeOutputStream(mStream);
// Closing the output stream in the HAL waits for the callback to finish,
@ -462,7 +462,7 @@ Return<Result> StreamOut::setCallback(const sp<IStreamOutCallback>& callback) {
Return<Result> StreamOut::clearCallback() {
if (mStream->set_callback == NULL) return Result::NOT_SUPPORTED;
mCallback.clear();
mCallback = nullptr;
return Result::OK;
}
@ -477,7 +477,7 @@ int StreamOut::asyncCallback(stream_callback_event_t event, void*, void* cookie)
// It's correct to hold an sp<> to callback because the reference
// in the StreamOut instance can be cleared in the meantime. There is
// no difference on which thread to run IStreamOutCallback's destructor.
sp<IStreamOutCallback> callback = self->mCallback;
sp<IStreamOutCallback> callback = self->mCallback.load();
if (callback.get() == nullptr) return 0;
ALOGV("asyncCallback() event %d", event);
Return<void> result;

View file

@ -29,6 +29,7 @@
#include <fmq/MessageQueue.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
#include <mediautils/Synchronization.h>
#include <utils/Thread.h>
namespace android {
@ -158,7 +159,7 @@ struct StreamOut : public IStreamOut {
audio_stream_out_t* mStream;
const sp<Stream> mStreamCommon;
const sp<StreamMmap<audio_stream_out_t>> mStreamMmap;
sp<IStreamOutCallback> mCallback; // Callback for non-blocking write and drain
mediautils::atomic_sp<IStreamOutCallback> mCallback; // for non-blocking write and drain
#if MAJOR_VERSION >= 6
sp<IStreamOutEventCallback> mEventCallback;
#endif