output/alsa: make the "active" attribute thread-safe

This commit is contained in:
Max Kellermann 2018-04-26 16:12:32 +02:00
parent 7d546f80f9
commit 485ed0b156
1 changed files with 12 additions and 4 deletions

View File

@ -123,8 +123,7 @@ class AlsaOutput final
* After Open(), has this output been activated by a Play() * After Open(), has this output been activated by a Play()
* command? * command?
* *
* This attribute is not thread-safe. It is only used by the * Protected by #mutex.
* client thread (the thread which calls AudioOutput public methods).
*/ */
bool active; bool active;
@ -162,7 +161,7 @@ class AlsaOutput final
Alsa::PeriodBuffer period_buffer; Alsa::PeriodBuffer period_buffer;
/** /**
* Protects #cond, #error, #drain. * Protects #cond, #error, #active, #drain.
*/ */
mutable Mutex mutex; mutable Mutex mutex;
@ -228,6 +227,12 @@ private:
#endif #endif
); );
gcc_pure
bool LockIsActive() const noexcept {
const std::lock_guard<Mutex> lock(mutex);
return active;
}
/** /**
* Activate the output by registering the sockets in the * Activate the output by registering the sockets in the
* #EventLoop. Before calling this, filling the ring buffer * #EventLoop. Before calling this, filling the ring buffer
@ -784,7 +789,7 @@ AlsaOutput::CancelInternal() noexcept
void void
AlsaOutput::Cancel() noexcept AlsaOutput::Cancel() noexcept
{ {
if (!active) { if (!LockIsActive()) {
/* early cancel, quick code path without thread /* early cancel, quick code path without thread
synchronization */ synchronization */
@ -880,6 +885,9 @@ AlsaOutput::DispatchSockets() noexcept
try { try {
{ {
const std::lock_guard<Mutex> lock(mutex); const std::lock_guard<Mutex> lock(mutex);
assert(active);
if (drain) { if (drain) {
{ {
ScopeUnlock unlock(mutex); ScopeUnlock unlock(mutex);