output/Interface: allow Pause() to throw exception

Coverity discovered that the Pulse plugin could throw exceptions from
Pause(), but that method was marked "noexcept" because its caller was
not designed to catch exceptions.  So instead of avoiding exceptions
(by catching and logging them in each and every implementation), let's
allow them, and do the catch/log game in the MPD core.
This commit is contained in:
Max Kellermann 2017-09-08 14:45:53 +02:00
parent 9cc37bdea2
commit d0f6131ba4
7 changed files with 18 additions and 21 deletions

View File

@ -140,8 +140,11 @@ public:
*
* @return false on error (output will be closed by caller),
* true for continue to pause
*
* Instead of returning false, the method may throw an
* exception, which will be logged.
*/
virtual bool Pause() noexcept {
virtual bool Pause() {
/* fail because this method is not implemented */
return false;
}

View File

@ -135,7 +135,7 @@ struct JackOutput final : AudioOutput {
size_t Play(const void *chunk, size_t size) override;
bool Pause() noexcept override;
bool Pause() override;
};
static constexpr Domain jack_output_domain("jack_output");
@ -661,7 +661,7 @@ JackOutput::Play(const void *chunk, size_t size)
}
inline bool
JackOutput::Pause() noexcept
JackOutput::Pause()
{
if (shutdown)
return false;

View File

@ -103,7 +103,7 @@ public:
std::chrono::steady_clock::duration Delay() const noexcept override;
size_t Play(const void *chunk, size_t size) override;
void Cancel() noexcept override;
bool Pause() noexcept override;
bool Pause() override;
private:
/**
@ -826,7 +826,7 @@ PulseOutput::Cancel() noexcept
}
bool
PulseOutput::Pause() noexcept
PulseOutput::Pause()
{
assert(mainloop != nullptr);
assert(stream != nullptr);

View File

@ -65,7 +65,7 @@ struct ShoutOutput final : AudioOutput {
void SendTag(const Tag &tag) override;
size_t Play(const void *chunk, size_t size) override;
void Cancel() noexcept override;
bool Pause() noexcept override;
bool Pause() override;
private:
void WritePage();
@ -378,16 +378,12 @@ ShoutOutput::Play(const void *chunk, size_t size)
}
bool
ShoutOutput::Pause() noexcept
ShoutOutput::Pause()
{
static char silence[1020];
try {
encoder->Write(silence, sizeof(silence));
WritePage();
} catch (const std::runtime_error &) {
return false;
}
encoder->Write(silence, sizeof(silence));
WritePage();
return true;
}

View File

@ -252,7 +252,7 @@ public:
void CancelAllClients();
void Cancel() noexcept override;
bool Pause() noexcept override;
bool Pause() override;
private:
virtual void RunDeferred() override;

View File

@ -371,7 +371,7 @@ HttpdOutput::Play(const void *chunk, size_t size)
}
bool
HttpdOutput::Pause() noexcept
HttpdOutput::Pause()
{
pause = true;

View File

@ -102,7 +102,7 @@ private:
void Drain() override;
void Cancel() noexcept override;
bool Pause() noexcept override;
bool Pause() override;
private:
void PlayedCallback();
@ -368,7 +368,7 @@ SlesOutput::Cancel() noexcept
}
bool
SlesOutput::Pause() noexcept
SlesOutput::Pause()
{
cancel = false;
@ -378,10 +378,8 @@ SlesOutput::Pause() noexcept
pause = true;
SLresult result = play.SetPlayState(SL_PLAYSTATE_PAUSED);
if (result != SL_RESULT_SUCCESS) {
FormatError(sles_domain, "Play.SetPlayState(PAUSED) failed");
return false;
}
if (result != SL_RESULT_SUCCESS)
throw std::runtime_error("Play.SetPlayState(PAUSED) failed");
return true;
}