diff options
author | Shen-Ta Hsieh <ibmibmibm.tw@gmail.com> | 2020-12-02 07:57:24 +0800 |
---|---|---|
committer | Max Kellermann <max@musicpd.org> | 2021-03-04 18:50:09 +0100 |
commit | 010f65a1d60ab76bfe0f3fb41475d8799784f9fe (patch) | |
tree | 934156a489581f7bbe5904d71a014e55c5c3b927 | |
parent | c46f97454af67014caf9444c6f8d68b5fdd4424b (diff) |
src/output: Add Interrupt interface
-rw-r--r-- | src/output/plugins/WasapiOutputPlugin.cxx | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/src/output/plugins/WasapiOutputPlugin.cxx b/src/output/plugins/WasapiOutputPlugin.cxx index b17c4ab7a..a9bfae83e 100644 --- a/src/output/plugins/WasapiOutputPlugin.cxx +++ b/src/output/plugins/WasapiOutputPlugin.cxx @@ -22,6 +22,7 @@ #include "WasapiOutputPlugin.hxx" #include "lib/icu/Win32.hxx" #include "mixer/MixerList.hxx" +#include "output/Error.hxx" #include "thread/Cond.hxx" #include "thread/Mutex.hxx" #include "thread/Name.hxx" @@ -30,6 +31,7 @@ #include "util/Domain.hxx" #include "util/RuntimeError.hxx" #include "util/ScopeExit.hxx" +#include "util/StringBuffer.hxx" #include "win32/Com.hxx" #include "win32/ComHeapPtr.hxx" #include "win32/ComWorker.hxx" @@ -129,7 +131,7 @@ public: void Finish() noexcept { return SetStatus(Status::FINISH); } void Play() noexcept { return SetStatus(Status::PLAY); } void Pause() noexcept { return SetStatus(Status::PAUSE); } - void WaitDataPoped() noexcept { data_poped.Wait(200); } + void WaitDataPoped() noexcept { data_poped.Wait(INFINITE); } void CheckException() { if (error.occur.load()) { auto err = std::exchange(error.ptr, nullptr); @@ -183,6 +185,7 @@ public: size_t Play(const void *chunk, size_t size) override; void Drain() override; bool Pause() override; + void Interrupt() noexcept override; constexpr bool Exclusive() const { return is_exclusive; } constexpr size_t FrameSize() const { return device_format.Format.nBlockAlign; } @@ -191,6 +194,7 @@ public: } private: + std::atomic_flag not_interrupted = true; bool is_started = false; bool is_exclusive; bool enumerate_devices; @@ -486,12 +490,17 @@ std::chrono::steady_clock::duration WasapiOutput::Delay() const noexcept { size_t WasapiOutput::Play(const void *chunk, size_t size) { assert(thread); + not_interrupted.test_and_set(); + do { const size_t consumed_size = thread->spsc_buffer.push(static_cast<const BYTE *>(chunk), size); if (consumed_size == 0) { assert(is_started); thread->WaitDataPoped(); + if (!not_interrupted.test_and_set()) { + throw AudioOutputInterrupted{}; + } continue; } @@ -536,6 +545,13 @@ bool WasapiOutput::Pause() { return true; } +void WasapiOutput::Interrupt() noexcept { + if (thread) { + not_interrupted.clear(); + thread->data_poped.Set(); + } +} + void WasapiOutput::Drain() { assert(thread); |