diff options
Diffstat (limited to 'media/libcubeb/uplift-wasapi-part-to-beta.patch')
-rw-r--r-- | media/libcubeb/uplift-wasapi-part-to-beta.patch | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/media/libcubeb/uplift-wasapi-part-to-beta.patch b/media/libcubeb/uplift-wasapi-part-to-beta.patch new file mode 100644 index 000000000..90e827830 --- /dev/null +++ b/media/libcubeb/uplift-wasapi-part-to-beta.patch @@ -0,0 +1,118 @@ +# HG changeset patch +# User Alex Chronopoulos <achronop@gmail.com> +# Parent b7bb31e5a851d6f8e142c39dc077e3774719eced +Bug 1342363 - Uplift wasapi fixes in Beta. r?kinetik + +diff --git a/media/libcubeb/src/cubeb_wasapi.cpp b/media/libcubeb/src/cubeb_wasapi.cpp +--- a/media/libcubeb/src/cubeb_wasapi.cpp ++++ b/media/libcubeb/src/cubeb_wasapi.cpp +@@ -807,16 +807,20 @@ wasapi_stream_render_loop(LPVOID stream) + maybe WebRTC. */ + mmcss_handle = + stm->context->set_mm_thread_characteristics("Audio", &mmcss_task_index); + if (!mmcss_handle) { + /* This is not fatal, but we might glitch under heavy load. */ + LOG("Unable to use mmcss to bump the render thread priority: %x", GetLastError()); + } + ++ // This has already been nulled out, simply exit. ++ if (!emergency_bailout) { ++ is_playing = false; ++ } + + /* WaitForMultipleObjects timeout can trigger in cases where we don't want to + treat it as a timeout, such as across a system sleep/wake cycle. Trigger + the timeout error handling only when the timeout_limit is reached, which is + reset on each successful loop. */ + unsigned timeout_count = 0; + const unsigned timeout_limit = 5; + while (is_playing) { +@@ -1158,22 +1162,26 @@ bool stop_and_join_render_thread(cubeb_s + + /* Wait five seconds for the rendering thread to return. It's supposed to + * check its event loop very often, five seconds is rather conservative. */ + DWORD r = WaitForSingleObject(stm->thread, 5000); + if (r == WAIT_TIMEOUT) { + /* Something weird happened, leak the thread and continue the shutdown + * process. */ + *(stm->emergency_bailout) = true; ++ // We give the ownership to the rendering thread. ++ stm->emergency_bailout = nullptr; + LOG("Destroy WaitForSingleObject on thread timed out," + " leaking the thread: %d", GetLastError()); + rv = false; + } + if (r == WAIT_FAILED) { + *(stm->emergency_bailout) = true; ++ // We give the ownership to the rendering thread. ++ stm->emergency_bailout = nullptr; + LOG("Destroy WaitForSingleObject on thread failed: %d", GetLastError()); + rv = false; + } + + + // Only attempts to close and null out the thread and event if the + // WaitForSingleObject above succeeded, so that calling this function again + // attemps to clean up the thread and event each time. +@@ -1798,19 +1806,16 @@ void wasapi_stream_destroy(cubeb_stream + XASSERT(stm); + + // Only free stm->emergency_bailout if we could not join the thread. + // If we could not join the thread, stm->emergency_bailout is true + // and is still alive until the thread wakes up and exits cleanly. + if (stop_and_join_render_thread(stm)) { + delete stm->emergency_bailout.load(); + stm->emergency_bailout = nullptr; +- } else { +- // If we're leaking, it must be that this is true. +- assert(*(stm->emergency_bailout)); + } + + unregister_notification_client(stm); + + SafeRelease(stm->reconfigure_event); + SafeRelease(stm->refill_event); + SafeRelease(stm->input_available_event); + +@@ -1865,21 +1870,21 @@ int stream_start_one_side(cubeb_stream * + return CUBEB_ERROR; + } + + return CUBEB_OK; + } + + int wasapi_stream_start(cubeb_stream * stm) + { ++ auto_lock lock(stm->stream_reset_lock); ++ + XASSERT(stm && !stm->thread && !stm->shutdown_event); + XASSERT(stm->output_client || stm->input_client); + +- auto_lock lock(stm->stream_reset_lock); +- + stm->emergency_bailout = new std::atomic<bool>(false); + + if (stm->output_client) { + int rv = stream_start_one_side(stm, OUTPUT); + if (rv != CUBEB_OK) { + return rv; + } + } +@@ -1932,16 +1937,17 @@ int wasapi_stream_stop(cubeb_stream * st + } + } + + + stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_STOPPED); + } + + if (stop_and_join_render_thread(stm)) { ++ // This is null if we've given the pointer to the other thread + if (stm->emergency_bailout.load()) { + delete stm->emergency_bailout.load(); + stm->emergency_bailout = nullptr; + } + } + + return CUBEB_OK; + } |