From f4968d996d3451a879e892893bfd19239aca17d8 Mon Sep 17 00:00:00 2001 From: Jean-Yves Avenard Date: Wed, 12 Sep 2018 22:26:28 +0200 Subject: 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. --- src/cubeb_audiounit.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/cubeb_audiounit.cpp') 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 frames_read{ 0 }; atomic shutdown{ true }; atomic draining{ false }; + atomic destroy_pending{ false }; /* Latency requested by the user. */ uint32_t latency_frames = 0; atomic 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, ^() { -- cgit v1.2.3