diff options
author | Max Kellermann <max@musicpd.org> | 2018-11-12 11:30:05 +0100 |
---|---|---|
committer | Max Kellermann <max@musicpd.org> | 2018-11-12 12:09:37 +0100 |
commit | e097fef79e66b6ff6cf04a911067d3750b20bd48 (patch) | |
tree | e40e3df98debf38d8399fd00d4b3fac745765e82 /src/output | |
parent | 9a813cd3b11057d767e5bc30b83350e6052d1c28 (diff) |
output/control: add command `RELEASE`
With the new command, the decision to pause or close the output moves
into the output thread.
Diffstat (limited to 'src/output')
-rw-r--r-- | src/output/Control.cxx | 18 | ||||
-rw-r--r-- | src/output/Control.hxx | 6 | ||||
-rw-r--r-- | src/output/Thread.cxx | 24 |
3 files changed, 45 insertions, 3 deletions
diff --git a/src/output/Control.cxx b/src/output/Control.cxx index 81847a1de..39812b165 100644 --- a/src/output/Control.cxx +++ b/src/output/Control.cxx @@ -347,10 +347,22 @@ AudioOutputControl::LockAllowPlay() noexcept void AudioOutputControl::LockRelease() noexcept { - if (always_on) - LockPauseAsync(); + if (output->mixer != nullptr && + (!always_on || !output->SupportsPause())) + /* the device has no pause mode: close the mixer, + unless its "global" flag is set (checked by + mixer_auto_close()) */ + mixer_auto_close(output->mixer); + + const std::lock_guard<Mutex> protect(mutex); + + assert(!open || !fail_timer.IsDefined()); + assert(allow_play); + + if (IsOpen()) + CommandWait(Command::RELEASE); else - LockCloseWait(); + fail_timer.Reset(); } void diff --git a/src/output/Control.hxx b/src/output/Control.hxx index 58924edd5..3a961c57c 100644 --- a/src/output/Control.hxx +++ b/src/output/Control.hxx @@ -132,6 +132,12 @@ class AudioOutputControl { PAUSE, /** + * Close or pause the device, depending on the + * #always_on setting. + */ + RELEASE, + + /** * Drains the internal (hardware) buffers of the device. This * operation may take a while to complete. */ diff --git a/src/output/Thread.cxx b/src/output/Thread.cxx index 4211cd078..b88eecbad 100644 --- a/src/output/Thread.cxx +++ b/src/output/Thread.cxx @@ -456,6 +456,30 @@ AudioOutputControl::Task() noexcept the new command first */ continue; + case Command::RELEASE: + if (!open) { + /* the output has failed after + the PAUSE command was submitted; bail + out */ + CommandFinished(); + break; + } + + if (always_on) { + /* in "always_on" mode, the output is + paused instead of being closed */ + InternalPause(); + } else { + InternalClose(false); + CommandFinished(); + } + + /* don't "break" here: this might cause + Play() to be called when command==CLOSE + ends the paused state - "continue" checks + the new command first */ + continue; + case Command::DRAIN: if (open) InternalDrain(); |