mixer/MixerInternal: remember error details
If a mixer is not open, rethrow the original exception each time setting the volume is requested. This further improves error messages sent to MPD clients.
This commit is contained in:
parent
47680f936b
commit
ecee6f415b
|
@ -60,9 +60,9 @@ mixer_open(Mixer *mixer)
|
||||||
try {
|
try {
|
||||||
mixer->Open();
|
mixer->Open();
|
||||||
mixer->open = true;
|
mixer->open = true;
|
||||||
mixer->failed = false;
|
mixer->failure = {};
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
mixer->failed = true;
|
mixer->failure = std::current_exception();
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,6 +75,7 @@ mixer_close_internal(Mixer *mixer)
|
||||||
|
|
||||||
mixer->Close();
|
mixer->Close();
|
||||||
mixer->open = false;
|
mixer->open = false;
|
||||||
|
mixer->failure = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -95,20 +96,6 @@ mixer_auto_close(Mixer *mixer)
|
||||||
mixer_close(mixer);
|
mixer_close(mixer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Close the mixer due to failure. The mutex must be locked before
|
|
||||||
* calling this function.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
mixer_failed(Mixer *mixer)
|
|
||||||
{
|
|
||||||
assert(mixer->open);
|
|
||||||
|
|
||||||
mixer_close_internal(mixer);
|
|
||||||
|
|
||||||
mixer->failed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
mixer_get_volume(Mixer *mixer)
|
mixer_get_volume(Mixer *mixer)
|
||||||
{
|
{
|
||||||
|
@ -116,7 +103,7 @@ mixer_get_volume(Mixer *mixer)
|
||||||
|
|
||||||
assert(mixer != nullptr);
|
assert(mixer != nullptr);
|
||||||
|
|
||||||
if (mixer->plugin.global && !mixer->failed)
|
if (mixer->plugin.global && !mixer->failure)
|
||||||
mixer_open(mixer);
|
mixer_open(mixer);
|
||||||
|
|
||||||
const std::scoped_lock<Mutex> protect(mixer->mutex);
|
const std::scoped_lock<Mutex> protect(mixer->mutex);
|
||||||
|
@ -125,7 +112,8 @@ mixer_get_volume(Mixer *mixer)
|
||||||
try {
|
try {
|
||||||
volume = mixer->GetVolume();
|
volume = mixer->GetVolume();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
mixer_failed(mixer);
|
mixer_close_internal(mixer);
|
||||||
|
mixer->failure = std::current_exception();
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
|
@ -140,11 +128,13 @@ mixer_set_volume(Mixer *mixer, unsigned volume)
|
||||||
assert(mixer != nullptr);
|
assert(mixer != nullptr);
|
||||||
assert(volume <= 100);
|
assert(volume <= 100);
|
||||||
|
|
||||||
if (mixer->plugin.global && !mixer->failed)
|
if (mixer->plugin.global && !mixer->failure)
|
||||||
mixer_open(mixer);
|
mixer_open(mixer);
|
||||||
|
|
||||||
const std::scoped_lock<Mutex> protect(mixer->mutex);
|
const std::scoped_lock<Mutex> protect(mixer->mutex);
|
||||||
|
|
||||||
if (mixer->open)
|
if (mixer->open)
|
||||||
mixer->SetVolume(volume);
|
mixer->SetVolume(volume);
|
||||||
|
else if (mixer->failure)
|
||||||
|
std::rethrow_exception(mixer->failure);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#include "thread/Mutex.hxx"
|
#include "thread/Mutex.hxx"
|
||||||
#include "util/Compiler.h"
|
#include "util/Compiler.h"
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
class MixerListener;
|
class MixerListener;
|
||||||
|
|
||||||
class Mixer {
|
class Mixer {
|
||||||
|
@ -39,17 +41,17 @@ public:
|
||||||
*/
|
*/
|
||||||
Mutex mutex;
|
Mutex mutex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains error details if this mixer has failed. If set,
|
||||||
|
* it should not be reopened automatically.
|
||||||
|
*/
|
||||||
|
std::exception_ptr failure;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is the mixer device currently open?
|
* Is the mixer device currently open?
|
||||||
*/
|
*/
|
||||||
bool open = false;
|
bool open = false;
|
||||||
|
|
||||||
/**
|
|
||||||
* Has this mixer failed, and should not be reopened
|
|
||||||
* automatically?
|
|
||||||
*/
|
|
||||||
bool failed = false;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Mixer(const MixerPlugin &_plugin,
|
explicit Mixer(const MixerPlugin &_plugin,
|
||||||
MixerListener &_listener) noexcept
|
MixerListener &_listener) noexcept
|
||||||
|
|
Loading…
Reference in New Issue