OutputThread: use class ScopeUnlock for exception-safety
This commit is contained in:
parent
69de99636f
commit
f39823eac0
@ -51,9 +51,8 @@ AudioOutput::CommandFinished()
|
|||||||
assert(command != Command::NONE);
|
assert(command != Command::NONE);
|
||||||
command = Command::NONE;
|
command = Command::NONE;
|
||||||
|
|
||||||
mutex.unlock();
|
const ScopeUnlock unlock(mutex);
|
||||||
audio_output_client_notify.Signal();
|
audio_output_client_notify.Signal();
|
||||||
mutex.lock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
@ -62,15 +61,15 @@ AudioOutput::Enable()
|
|||||||
if (really_enabled)
|
if (really_enabled)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
mutex.unlock();
|
{
|
||||||
Error error;
|
const ScopeUnlock unlock(mutex);
|
||||||
bool success = ao_plugin_enable(this, error);
|
Error error;
|
||||||
mutex.lock();
|
if (!ao_plugin_enable(this, error)) {
|
||||||
if (!success) {
|
FormatError(error,
|
||||||
FormatError(error,
|
"Failed to enable \"%s\" [%s]",
|
||||||
"Failed to enable \"%s\" [%s]",
|
name, plugin.name);
|
||||||
name, plugin.name);
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
really_enabled = true;
|
really_enabled = true;
|
||||||
@ -86,9 +85,8 @@ AudioOutput::Disable()
|
|||||||
if (really_enabled) {
|
if (really_enabled) {
|
||||||
really_enabled = false;
|
really_enabled = false;
|
||||||
|
|
||||||
mutex.unlock();
|
const ScopeUnlock unlock(mutex);
|
||||||
ao_plugin_disable(this);
|
ao_plugin_disable(this);
|
||||||
mutex.lock();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,9 +183,10 @@ AudioOutput::Open()
|
|||||||
FormatError(error, "Failed to open \"%s\" [%s]",
|
FormatError(error, "Failed to open \"%s\" [%s]",
|
||||||
name, plugin.name);
|
name, plugin.name);
|
||||||
|
|
||||||
mutex.unlock();
|
{
|
||||||
CloseFilter();
|
const ScopeUnlock unlock(mutex);
|
||||||
mutex.lock();
|
CloseFilter();
|
||||||
|
}
|
||||||
|
|
||||||
fail_timer.Update();
|
fail_timer.Update();
|
||||||
return;
|
return;
|
||||||
@ -256,13 +255,11 @@ AudioOutput::Close(bool drain)
|
|||||||
current_chunk = nullptr;
|
current_chunk = nullptr;
|
||||||
open = false;
|
open = false;
|
||||||
|
|
||||||
mutex.unlock();
|
const ScopeUnlock unlock(mutex);
|
||||||
|
|
||||||
CloseOutput(drain);
|
CloseOutput(drain);
|
||||||
CloseFilter();
|
CloseFilter();
|
||||||
|
|
||||||
mutex.lock();
|
|
||||||
|
|
||||||
FormatDebug(output_domain, "closed plugin=%s name=\"%s\"",
|
FormatDebug(output_domain, "closed plugin=%s name=\"%s\"",
|
||||||
plugin.name, name);
|
plugin.name, name);
|
||||||
}
|
}
|
||||||
@ -283,9 +280,10 @@ AudioOutput::ReopenFilter()
|
|||||||
{
|
{
|
||||||
Error error;
|
Error error;
|
||||||
|
|
||||||
mutex.unlock();
|
{
|
||||||
CloseFilter();
|
const ScopeUnlock unlock(mutex);
|
||||||
mutex.lock();
|
CloseFilter();
|
||||||
|
}
|
||||||
|
|
||||||
AudioFormat filter_audio_format;
|
AudioFormat filter_audio_format;
|
||||||
try {
|
try {
|
||||||
@ -458,9 +456,8 @@ AudioOutput::PlayChunk(const MusicChunk *chunk)
|
|||||||
assert(filter_instance != nullptr);
|
assert(filter_instance != nullptr);
|
||||||
|
|
||||||
if (tags && gcc_unlikely(chunk->tag != nullptr)) {
|
if (tags && gcc_unlikely(chunk->tag != nullptr)) {
|
||||||
mutex.unlock();
|
const ScopeUnlock unlock(mutex);
|
||||||
ao_plugin_send_tag(this, *chunk->tag);
|
ao_plugin_send_tag(this, *chunk->tag);
|
||||||
mutex.lock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto data = ConstBuffer<char>::FromVoid(ao_filter_chunk(this, chunk));
|
auto data = ConstBuffer<char>::FromVoid(ao_filter_chunk(this, chunk));
|
||||||
@ -479,10 +476,14 @@ AudioOutput::PlayChunk(const MusicChunk *chunk)
|
|||||||
if (!WaitForDelay())
|
if (!WaitForDelay())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
mutex.unlock();
|
size_t nbytes;
|
||||||
size_t nbytes = ao_plugin_play(this, data.data, data.size,
|
|
||||||
error);
|
{
|
||||||
mutex.lock();
|
const ScopeUnlock unlock(mutex);
|
||||||
|
nbytes = ao_plugin_play(this, data.data, data.size,
|
||||||
|
error);
|
||||||
|
}
|
||||||
|
|
||||||
if (nbytes == 0) {
|
if (nbytes == 0) {
|
||||||
/* play()==0 means failure */
|
/* play()==0 means failure */
|
||||||
FormatError(error, "\"%s\" [%s] failed to play",
|
FormatError(error, "\"%s\" [%s] failed to play",
|
||||||
@ -552,9 +553,8 @@ AudioOutput::Play()
|
|||||||
|
|
||||||
current_chunk_finished = true;
|
current_chunk_finished = true;
|
||||||
|
|
||||||
mutex.unlock();
|
const ScopeUnlock unlock(mutex);
|
||||||
player_control->LockSignal();
|
player_control->LockSignal();
|
||||||
mutex.lock();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -562,9 +562,10 @@ AudioOutput::Play()
|
|||||||
inline void
|
inline void
|
||||||
AudioOutput::Pause()
|
AudioOutput::Pause()
|
||||||
{
|
{
|
||||||
mutex.unlock();
|
{
|
||||||
ao_plugin_cancel(this);
|
const ScopeUnlock unlock(mutex);
|
||||||
mutex.lock();
|
ao_plugin_cancel(this);
|
||||||
|
}
|
||||||
|
|
||||||
pause = true;
|
pause = true;
|
||||||
CommandFinished();
|
CommandFinished();
|
||||||
@ -573,9 +574,11 @@ AudioOutput::Pause()
|
|||||||
if (!WaitForDelay())
|
if (!WaitForDelay())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
mutex.unlock();
|
bool success;
|
||||||
bool success = ao_plugin_pause(this);
|
{
|
||||||
mutex.lock();
|
const ScopeUnlock unlock(mutex);
|
||||||
|
success = ao_plugin_pause(this);
|
||||||
|
}
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
Close(false);
|
Close(false);
|
||||||
@ -600,7 +603,7 @@ AudioOutput::Task()
|
|||||||
|
|
||||||
SetThreadTimerSlackUS(100);
|
SetThreadTimerSlackUS(100);
|
||||||
|
|
||||||
mutex.lock();
|
const ScopeLock lock(mutex);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
switch (command) {
|
switch (command) {
|
||||||
@ -657,9 +660,8 @@ AudioOutput::Task()
|
|||||||
assert(current_chunk == nullptr);
|
assert(current_chunk == nullptr);
|
||||||
assert(pipe->Peek() == nullptr);
|
assert(pipe->Peek() == nullptr);
|
||||||
|
|
||||||
mutex.unlock();
|
const ScopeUnlock unlock(mutex);
|
||||||
ao_plugin_drain(this);
|
ao_plugin_drain(this);
|
||||||
mutex.lock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandFinished();
|
CommandFinished();
|
||||||
@ -669,9 +671,8 @@ AudioOutput::Task()
|
|||||||
current_chunk = nullptr;
|
current_chunk = nullptr;
|
||||||
|
|
||||||
if (open) {
|
if (open) {
|
||||||
mutex.unlock();
|
const ScopeUnlock unlock(mutex);
|
||||||
ao_plugin_cancel(this);
|
ao_plugin_cancel(this);
|
||||||
mutex.lock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandFinished();
|
CommandFinished();
|
||||||
@ -680,7 +681,6 @@ AudioOutput::Task()
|
|||||||
case Command::KILL:
|
case Command::KILL:
|
||||||
current_chunk = nullptr;
|
current_chunk = nullptr;
|
||||||
CommandFinished();
|
CommandFinished();
|
||||||
mutex.unlock();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user