diff options
author | Max Kellermann <max@musicpd.org> | 2020-10-02 10:55:49 +0200 |
---|---|---|
committer | Max Kellermann <max@musicpd.org> | 2020-10-02 11:00:04 +0200 |
commit | 4484d7a5c2faabd6632e9ca6bc88712781cd4fa6 (patch) | |
tree | 2c6068e9536226e7b4767093aa88a28cb592758a /src | |
parent | b80a135cf3cab19dfaef2ddc95a72e67d6c55f2a (diff) |
output/jack: implement Interrupt()
Diffstat (limited to 'src')
-rw-r--r-- | src/output/plugins/JackOutputPlugin.cxx | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/src/output/plugins/JackOutputPlugin.cxx b/src/output/plugins/JackOutputPlugin.cxx index 8c6da5405..e2f0a63f1 100644 --- a/src/output/plugins/JackOutputPlugin.cxx +++ b/src/output/plugins/JackOutputPlugin.cxx @@ -20,6 +20,7 @@ #include "config.h" #include "JackOutputPlugin.hxx" #include "../OutputAPI.hxx" +#include "../Error.hxx" #include "output/Features.h" #include "thread/Mutex.hxx" #include "util/ScopeExit.hxx" @@ -80,6 +81,15 @@ class JackOutput final : public AudioOutput { std::atomic_bool pause; /** + * Was Interrupt() called? This will unblock Play(). It will + * be reset by Cancel() and Pause(), as documented by the + * #AudioOutput interface. + * + * Only initialized while the output is open. + */ + bool interrupted; + + /** * Protects #error. */ mutable Mutex mutex; @@ -156,6 +166,8 @@ public: Stop(); } + void Interrupt() noexcept override; + std::chrono::steady_clock::duration Delay() const noexcept override { return pause && !LockWasShutdown() ? std::chrono::seconds(1) @@ -164,6 +176,7 @@ public: size_t Play(const void *chunk, size_t size) override; + void Cancel() noexcept override; bool Pause() override; private: @@ -613,9 +626,21 @@ JackOutput::Open(AudioFormat &new_audio_format) new_audio_format.format = SampleFormat::FLOAT; audio_format = new_audio_format; + interrupted = false; + Start(); } +void +JackOutput::Interrupt() noexcept +{ + const std::unique_lock<Mutex> lock(mutex); + + /* the "interrupted" flag will prevent Play() from waiting, + and will instead throw AudioOutputInterrupted */ + interrupted = true; +} + inline size_t JackOutput::WriteSamples(const float *src, size_t n_frames) { @@ -671,6 +696,9 @@ JackOutput::Play(const void *chunk, size_t size) const std::lock_guard<Mutex> lock(mutex); if (error) std::rethrow_exception(error); + + if (interrupted) + throw AudioOutputInterrupted{}; } size_t frames_written = @@ -684,11 +712,19 @@ JackOutput::Play(const void *chunk, size_t size) } } +void +JackOutput::Cancel() noexcept +{ + const std::unique_lock<Mutex> lock(mutex); + interrupted = false; +} + inline bool JackOutput::Pause() { { const std::lock_guard<Mutex> lock(mutex); + interrupted = false; if (error) std::rethrow_exception(error); } |