aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJean-Yves Avenard <[email protected]>2018-09-12 22:26:28 +0200
committerJean-Yves Avenard <[email protected]>2018-09-14 15:07:50 +0200
commitf4968d996d3451a879e892893bfd19239aca17d8 (patch)
treea70f6b9ff29a66fe71c06fac496e44bfd0c173b6
parent78359c0e12283592c3bb55a09f3c64b470e22d1b (diff)
downloadcubeb-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.
-rw-r--r--src/cubeb_audiounit.cpp6
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, ^() {