output/Control: pass std::unique_lock<> to Cond::wait()
This commit is contained in:
parent
4473816384
commit
23d56cb6a1
@ -112,10 +112,10 @@ AudioOutputControl::LockToggleEnabled() noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioOutputControl::WaitForCommand() noexcept
|
AudioOutputControl::WaitForCommand(std::unique_lock<Mutex> &lock) noexcept
|
||||||
{
|
{
|
||||||
while (!IsCommandFinished())
|
while (!IsCommandFinished())
|
||||||
client_cond.wait(mutex);
|
client_cond.wait(lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -128,17 +128,18 @@ AudioOutputControl::CommandAsync(Command cmd) noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioOutputControl::CommandWait(Command cmd) noexcept
|
AudioOutputControl::CommandWait(std::unique_lock<Mutex> &lock,
|
||||||
|
Command cmd) noexcept
|
||||||
{
|
{
|
||||||
CommandAsync(cmd);
|
CommandAsync(cmd);
|
||||||
WaitForCommand();
|
WaitForCommand(lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioOutputControl::LockCommandWait(Command cmd) noexcept
|
AudioOutputControl::LockCommandWait(Command cmd) noexcept
|
||||||
{
|
{
|
||||||
const std::lock_guard<Mutex> protect(mutex);
|
std::unique_lock<Mutex> lock(mutex);
|
||||||
CommandWait(cmd);
|
CommandWait(lock, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -189,7 +190,8 @@ AudioOutputControl::EnableDisableAsync()
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
AudioOutputControl::Open(const AudioFormat audio_format,
|
AudioOutputControl::Open(std::unique_lock<Mutex> &lock,
|
||||||
|
const AudioFormat audio_format,
|
||||||
const MusicPipe &mp) noexcept
|
const MusicPipe &mp) noexcept
|
||||||
{
|
{
|
||||||
assert(allow_play);
|
assert(allow_play);
|
||||||
@ -218,7 +220,7 @@ AudioOutputControl::Open(const AudioFormat audio_format,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandWait(Command::OPEN);
|
CommandWait(lock, Command::OPEN);
|
||||||
const bool open2 = open;
|
const bool open2 = open;
|
||||||
|
|
||||||
if (open2 && output->mixer != nullptr) {
|
if (open2 && output->mixer != nullptr) {
|
||||||
@ -236,7 +238,7 @@ AudioOutputControl::Open(const AudioFormat audio_format,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioOutputControl::CloseWait() noexcept
|
AudioOutputControl::CloseWait(std::unique_lock<Mutex> &lock) noexcept
|
||||||
{
|
{
|
||||||
assert(allow_play);
|
assert(allow_play);
|
||||||
|
|
||||||
@ -246,7 +248,7 @@ AudioOutputControl::CloseWait() noexcept
|
|||||||
assert(!open || !fail_timer.IsDefined());
|
assert(!open || !fail_timer.IsDefined());
|
||||||
|
|
||||||
if (open)
|
if (open)
|
||||||
CommandWait(Command::CLOSE);
|
CommandWait(lock, Command::CLOSE);
|
||||||
else
|
else
|
||||||
fail_timer.Reset();
|
fail_timer.Reset();
|
||||||
}
|
}
|
||||||
@ -256,15 +258,15 @@ AudioOutputControl::LockUpdate(const AudioFormat audio_format,
|
|||||||
const MusicPipe &mp,
|
const MusicPipe &mp,
|
||||||
bool force) noexcept
|
bool force) noexcept
|
||||||
{
|
{
|
||||||
const std::lock_guard<Mutex> protect(mutex);
|
std::unique_lock<Mutex> lock(mutex);
|
||||||
|
|
||||||
if (enabled && really_enabled) {
|
if (enabled && really_enabled) {
|
||||||
if (force || !fail_timer.IsDefined() ||
|
if (force || !fail_timer.IsDefined() ||
|
||||||
fail_timer.Check(REOPEN_AFTER * 1000)) {
|
fail_timer.Check(REOPEN_AFTER * 1000)) {
|
||||||
return Open(audio_format, mp);
|
return Open(lock, audio_format, mp);
|
||||||
}
|
}
|
||||||
} else if (IsOpen())
|
} else if (IsOpen())
|
||||||
CloseWait();
|
CloseWait(lock);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -355,13 +357,13 @@ AudioOutputControl::LockRelease() noexcept
|
|||||||
mixer_auto_close()) */
|
mixer_auto_close()) */
|
||||||
mixer_auto_close(output->mixer);
|
mixer_auto_close(output->mixer);
|
||||||
|
|
||||||
const std::lock_guard<Mutex> protect(mutex);
|
std::unique_lock<Mutex> lock(mutex);
|
||||||
|
|
||||||
assert(!open || !fail_timer.IsDefined());
|
assert(!open || !fail_timer.IsDefined());
|
||||||
assert(allow_play);
|
assert(allow_play);
|
||||||
|
|
||||||
if (IsOpen())
|
if (IsOpen())
|
||||||
CommandWait(Command::RELEASE);
|
CommandWait(lock, Command::RELEASE);
|
||||||
else
|
else
|
||||||
fail_timer.Reset();
|
fail_timer.Reset();
|
||||||
}
|
}
|
||||||
@ -371,8 +373,8 @@ AudioOutputControl::LockCloseWait() noexcept
|
|||||||
{
|
{
|
||||||
assert(!open || !fail_timer.IsDefined());
|
assert(!open || !fail_timer.IsDefined());
|
||||||
|
|
||||||
const std::lock_guard<Mutex> protect(mutex);
|
std::unique_lock<Mutex> lock(mutex);
|
||||||
CloseWait();
|
CloseWait(lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -307,11 +307,11 @@ public:
|
|||||||
*
|
*
|
||||||
* Caller must lock the mutex.
|
* Caller must lock the mutex.
|
||||||
*/
|
*/
|
||||||
void WaitForCommand() noexcept;
|
void WaitForCommand(std::unique_lock<Mutex> &lock) noexcept;
|
||||||
|
|
||||||
void LockWaitForCommand() noexcept {
|
void LockWaitForCommand() noexcept {
|
||||||
const std::lock_guard<Mutex> protect(mutex);
|
std::unique_lock<Mutex> lock(mutex);
|
||||||
WaitForCommand();
|
WaitForCommand(lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -326,7 +326,7 @@ public:
|
|||||||
*
|
*
|
||||||
* Caller must lock the mutex.
|
* Caller must lock the mutex.
|
||||||
*/
|
*/
|
||||||
void CommandWait(Command cmd) noexcept;
|
void CommandWait(std::unique_lock<Mutex> &lock, Command cmd) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lock the object and execute the command synchronously.
|
* Lock the object and execute the command synchronously.
|
||||||
@ -368,7 +368,7 @@ public:
|
|||||||
|
|
||||||
void LockPauseAsync() noexcept;
|
void LockPauseAsync() noexcept;
|
||||||
|
|
||||||
void CloseWait() noexcept;
|
void CloseWait(std::unique_lock<Mutex> &lock) noexcept;
|
||||||
void LockCloseWait() noexcept;
|
void LockCloseWait() noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -391,7 +391,8 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Caller must lock the mutex.
|
* Caller must lock the mutex.
|
||||||
*/
|
*/
|
||||||
bool Open(AudioFormat audio_format, const MusicPipe &mp) noexcept;
|
bool Open(std::unique_lock<Mutex> &lock,
|
||||||
|
AudioFormat audio_format, const MusicPipe &mp) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens or closes the device, depending on the "enabled"
|
* Opens or closes the device, depending on the "enabled"
|
||||||
@ -522,7 +523,7 @@ private:
|
|||||||
* @return true if playback should be continued, false if a
|
* @return true if playback should be continued, false if a
|
||||||
* command was issued
|
* command was issued
|
||||||
*/
|
*/
|
||||||
bool WaitForDelay() noexcept;
|
bool WaitForDelay(std::unique_lock<Mutex> &lock) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Caller must lock the mutex.
|
* Caller must lock the mutex.
|
||||||
@ -532,7 +533,7 @@ private:
|
|||||||
/**
|
/**
|
||||||
* Caller must lock the mutex.
|
* Caller must lock the mutex.
|
||||||
*/
|
*/
|
||||||
bool PlayChunk() noexcept;
|
bool PlayChunk(std::unique_lock<Mutex> &lock) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plays all remaining chunks, until the tail of the pipe has
|
* Plays all remaining chunks, until the tail of the pipe has
|
||||||
@ -546,14 +547,14 @@ private:
|
|||||||
* @return true if at least one chunk has been available,
|
* @return true if at least one chunk has been available,
|
||||||
* false if the tail of the pipe was already reached
|
* false if the tail of the pipe was already reached
|
||||||
*/
|
*/
|
||||||
bool InternalPlay() noexcept;
|
bool InternalPlay(std::unique_lock<Mutex> &lock) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs inside the OutputThread.
|
* Runs inside the OutputThread.
|
||||||
* Caller must lock the mutex.
|
* Caller must lock the mutex.
|
||||||
* Handles exceptions.
|
* Handles exceptions.
|
||||||
*/
|
*/
|
||||||
void InternalPause() noexcept;
|
void InternalPause(std::unique_lock<Mutex> &lock) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs inside the OutputThread.
|
* Runs inside the OutputThread.
|
||||||
|
@ -208,14 +208,14 @@ AudioOutputControl::InternalCheckClose(bool drain) noexcept
|
|||||||
* was issued
|
* was issued
|
||||||
*/
|
*/
|
||||||
inline bool
|
inline bool
|
||||||
AudioOutputControl::WaitForDelay() noexcept
|
AudioOutputControl::WaitForDelay(std::unique_lock<Mutex> &lock) noexcept
|
||||||
{
|
{
|
||||||
while (true) {
|
while (true) {
|
||||||
const auto delay = output->Delay();
|
const auto delay = output->Delay();
|
||||||
if (delay <= std::chrono::steady_clock::duration::zero())
|
if (delay <= std::chrono::steady_clock::duration::zero())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
(void)wake_cond.wait_for(mutex, delay);
|
(void)wake_cond.wait_for(lock, delay);
|
||||||
|
|
||||||
if (command != Command::NONE)
|
if (command != Command::NONE)
|
||||||
return false;
|
return false;
|
||||||
@ -234,7 +234,7 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
AudioOutputControl::PlayChunk() noexcept
|
AudioOutputControl::PlayChunk(std::unique_lock<Mutex> &lock) noexcept
|
||||||
{
|
{
|
||||||
// ensure pending tags are flushed in all cases
|
// ensure pending tags are flushed in all cases
|
||||||
const auto *tag = source.ReadTag();
|
const auto *tag = source.ReadTag();
|
||||||
@ -256,7 +256,7 @@ AudioOutputControl::PlayChunk() noexcept
|
|||||||
|
|
||||||
if (skip_delay)
|
if (skip_delay)
|
||||||
skip_delay = false;
|
skip_delay = false;
|
||||||
else if (!WaitForDelay())
|
else if (!WaitForDelay(lock))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
size_t nbytes;
|
size_t nbytes;
|
||||||
@ -282,7 +282,7 @@ AudioOutputControl::PlayChunk() noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
AudioOutputControl::InternalPlay() noexcept
|
AudioOutputControl::InternalPlay(std::unique_lock<Mutex> &lock) noexcept
|
||||||
{
|
{
|
||||||
if (!FillSourceOrClose())
|
if (!FillSourceOrClose())
|
||||||
/* no chunk available */
|
/* no chunk available */
|
||||||
@ -311,7 +311,7 @@ AudioOutputControl::InternalPlay() noexcept
|
|||||||
n = 0;
|
n = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PlayChunk())
|
if (!PlayChunk(lock))
|
||||||
break;
|
break;
|
||||||
} while (FillSourceOrClose());
|
} while (FillSourceOrClose());
|
||||||
|
|
||||||
@ -322,7 +322,7 @@ AudioOutputControl::InternalPlay() noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
AudioOutputControl::InternalPause() noexcept
|
AudioOutputControl::InternalPause(std::unique_lock<Mutex> &lock) noexcept
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
const ScopeUnlock unlock(mutex);
|
const ScopeUnlock unlock(mutex);
|
||||||
@ -334,7 +334,7 @@ AudioOutputControl::InternalPause() noexcept
|
|||||||
CommandFinished();
|
CommandFinished();
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (!WaitForDelay())
|
if (!WaitForDelay(lock))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
bool success;
|
bool success;
|
||||||
@ -448,7 +448,7 @@ AudioOutputControl::Task() noexcept
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
InternalPause();
|
InternalPause(lock);
|
||||||
/* don't "break" here: this might cause
|
/* don't "break" here: this might cause
|
||||||
Play() to be called when command==CLOSE
|
Play() to be called when command==CLOSE
|
||||||
ends the paused state - "continue" checks
|
ends the paused state - "continue" checks
|
||||||
@ -472,7 +472,7 @@ AudioOutputControl::Task() noexcept
|
|||||||
have been invalidated by stopping
|
have been invalidated by stopping
|
||||||
the actual playback */
|
the actual playback */
|
||||||
source.Cancel();
|
source.Cancel();
|
||||||
InternalPause();
|
InternalPause(lock);
|
||||||
} else {
|
} else {
|
||||||
InternalClose(false);
|
InternalClose(false);
|
||||||
CommandFinished();
|
CommandFinished();
|
||||||
@ -509,7 +509,7 @@ AudioOutputControl::Task() noexcept
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (open && allow_play && InternalPlay())
|
if (open && allow_play && InternalPlay(lock))
|
||||||
/* don't wait for an event if there are more
|
/* don't wait for an event if there are more
|
||||||
chunks in the pipe */
|
chunks in the pipe */
|
||||||
continue;
|
continue;
|
||||||
|
Loading…
Reference in New Issue
Block a user