diff options
author | Jean-Yves Avenard <[email protected]> | 2018-09-12 22:26:28 +0200 |
---|---|---|
committer | Jean-Yves Avenard <[email protected]> | 2018-09-14 15:07:50 +0200 |
commit | f4968d996d3451a879e892893bfd19239aca17d8 (patch) | |
tree | a70f6b9ff29a66fe71c06fac496e44bfd0c173b6 /src/cubeb_audiounit.cpp | |
parent | 78359c0e12283592c3bb55a09f3c64b470e22d1b (diff) | |
download | cubeb-f4968d996d3451a879e892893bfd19239aca17d8.tar.gz cubeb-f4968d996d3451a879e892893bfd19239aca17d8.zip |
Cancel reinit task when a audiounit_stream_destroy call is pending
It is possible that the callback caused a reinit task to be queued while at the same time audiounit_stream_destroy got called.
We need to abort early as otherwise both stm->input_unit and stm->output_unit would have been cleared.
Diffstat (limited to 'src/cubeb_audiounit.cpp')
-rw-r--r-- | src/cubeb_audiounit.cpp | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/src/cubeb_audiounit.cpp b/src/cubeb_audiounit.cpp index 879e2c4..b9f2709 100644 --- a/src/cubeb_audiounit.cpp +++ b/src/cubeb_audiounit.cpp @@ -235,6 +235,7 @@ struct cubeb_stream { atomic<int64_t> frames_read{ 0 }; atomic<bool> shutdown{ true }; atomic<bool> draining{ false }; + atomic<bool> destroy_pending{ false }; /* Latency requested by the user. */ uint32_t latency_frames = 0; atomic<uint32_t> current_latency_frames{ 0 }; @@ -848,6 +849,10 @@ audiounit_reinit_stream_async(cubeb_stream * stm, device_flags_value flags) // Use a new thread, through the queue, to avoid deadlock when calling // Get/SetProperties method from inside notify callback dispatch_async(stm->context->serial_queue, ^() { + if (stm->destroy_pending) { + ALOG("(%p) stream pending destroy, cancelling reinit task", stm); + return; + } if (audiounit_reinit_stream(stm, flags) != CUBEB_OK) { if (audiounit_uninstall_system_changed_callback(stm) != CUBEB_OK) { LOG("(%p) Could not uninstall system changed callback", stm); @@ -2823,6 +2828,7 @@ audiounit_stream_destroy(cubeb_stream * stm) stm->shutdown = true; } + stm->destroy_pending = true; // Execute close in serial queue to avoid collision // with reinit when un/plug devices dispatch_sync(stm->context->serial_queue, ^() { |