diff --git a/src/output/plugins/WasapiOutputPlugin.cxx b/src/output/plugins/WasapiOutputPlugin.cxx index 30eeb2c75..b2833b2d9 100644 --- a/src/output/plugins/WasapiOutputPlugin.cxx +++ b/src/output/plugins/WasapiOutputPlugin.cxx @@ -129,15 +129,11 @@ public: void Finish() noexcept { return SetStatus(Status::FINISH); } void Play() noexcept { return SetStatus(Status::PLAY); } void Pause() noexcept { return SetStatus(Status::PAUSE); } - void WaitWrite() noexcept { - std::unique_lock lock(write.mutex); - write.cond.wait(lock); - } + void WaitDataPoped() noexcept { data_poped.Wait(200); } void CheckException() { - std::unique_lock lock(error.mutex); - if (error.error_ptr) { - std::exception_ptr err = std::exchange(error.error_ptr, nullptr); - error.cond.notify_all(); + if (error.occur.load()) { + auto err = std::exchange(error.ptr, nullptr); + error.thrown.Set(); std::rethrow_exception(err); } } @@ -145,6 +141,7 @@ public: private: friend class WasapiOutput; WinEvent event; + WinEvent data_poped; IAudioClient *client; ComPtr render_client; const UINT32 frame_size; @@ -153,14 +150,10 @@ private: alignas(BOOST_LOCKFREE_CACHELINE_BYTES) std::atomic status = Status::PAUSE; alignas(BOOST_LOCKFREE_CACHELINE_BYTES) struct { - Mutex mutex; - Cond cond; - } write{}; - alignas(BOOST_LOCKFREE_CACHELINE_BYTES) struct { - Mutex mutex; - Cond cond; - std::exception_ptr error_ptr = nullptr; - } error{}; + std::atomic_bool occur = false; + std::exception_ptr ptr = nullptr; + WinEvent thrown; + } error; boost::lockfree::spsc_queue spsc_buffer; void SetStatus(Status s) noexcept { @@ -255,8 +248,6 @@ void WasapiOutputThread::Work() noexcept { return; } - AtScopeExit(&) { write.cond.notify_all(); }; - HRESULT result; UINT32 data_in_frames; result = client->GetCurrentPadding(&data_in_frames); @@ -293,16 +284,16 @@ void WasapiOutputThread::Work() noexcept { new_data_size = spsc_buffer.pop(data, write_size); std::fill_n(data + new_data_size, write_size - new_data_size, 0); + data_poped.Set(); } else { mode = AUDCLNT_BUFFERFLAGS_SILENT; FormatDebug(wasapi_output_domain, "Working thread paused"); } } catch (...) { - std::unique_lock lock(error.mutex); - error.error_ptr = std::current_exception(); - error.cond.wait(lock); - assert(error.error_ptr == nullptr); + error.ptr = std::current_exception(); + error.occur.store(true); + error.thrown.Wait(INFINITE); } } } @@ -491,7 +482,7 @@ size_t WasapiOutput::Play(const void *chunk, size_t size) { thread->spsc_buffer.push(static_cast(chunk), size); if (consumed_size == 0) { assert(is_started); - thread->WaitWrite(); + thread->WaitDataPoped(); continue; }