lib/alsa/NonBlock: throw exception on error
Avoid another potential deadlock: if no file descriptors are registered, our non-blocking ALSA code cannot ever work.
This commit is contained in:
parent
e0f777d4eb
commit
7d579e7400
@ -20,22 +20,31 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "NonBlock.hxx"
|
#include "NonBlock.hxx"
|
||||||
#include "event/MultiSocketMonitor.hxx"
|
#include "event/MultiSocketMonitor.hxx"
|
||||||
|
#include "util/RuntimeError.hxx"
|
||||||
|
|
||||||
std::chrono::steady_clock::duration
|
std::chrono::steady_clock::duration
|
||||||
PrepareAlsaPcmSockets(MultiSocketMonitor &m, snd_pcm_t *pcm,
|
PrepareAlsaPcmSockets(MultiSocketMonitor &m, snd_pcm_t *pcm,
|
||||||
ReusableArray<pollfd> &pfd_buffer) noexcept
|
ReusableArray<pollfd> &pfd_buffer)
|
||||||
{
|
{
|
||||||
int count = snd_pcm_poll_descriptors_count(pcm);
|
int count = snd_pcm_poll_descriptors_count(pcm);
|
||||||
if (count <= 0) {
|
if (count <= 0) {
|
||||||
m.ClearSocketList();
|
if (count == 0)
|
||||||
return std::chrono::steady_clock::duration(-1);
|
throw std::runtime_error("snd_pcm_poll_descriptors_count() failed");
|
||||||
|
else
|
||||||
|
throw FormatRuntimeError("snd_pcm_poll_descriptors_count() failed: %s",
|
||||||
|
snd_strerror(-count));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pollfd *pfds = pfd_buffer.Get(count);
|
struct pollfd *pfds = pfd_buffer.Get(count);
|
||||||
|
|
||||||
count = snd_pcm_poll_descriptors(pcm, pfds, count);
|
count = snd_pcm_poll_descriptors(pcm, pfds, count);
|
||||||
if (count < 0)
|
if (count <= 0) {
|
||||||
count = 0;
|
if (count == 0)
|
||||||
|
throw std::runtime_error("snd_pcm_poll_descriptors() failed");
|
||||||
|
else
|
||||||
|
throw FormatRuntimeError("snd_pcm_poll_descriptors() failed: %s",
|
||||||
|
snd_strerror(-count));
|
||||||
|
}
|
||||||
|
|
||||||
m.ReplaceSocketList(pfds, count);
|
m.ReplaceSocketList(pfds, count);
|
||||||
return std::chrono::steady_clock::duration(-1);
|
return std::chrono::steady_clock::duration(-1);
|
||||||
|
@ -33,10 +33,12 @@ class MultiSocketMonitor;
|
|||||||
* Update #MultiSocketMonitor's socket list from
|
* Update #MultiSocketMonitor's socket list from
|
||||||
* snd_pcm_poll_descriptors(). To be called from
|
* snd_pcm_poll_descriptors(). To be called from
|
||||||
* MultiSocketMonitor::PrepareSockets().
|
* MultiSocketMonitor::PrepareSockets().
|
||||||
|
*
|
||||||
|
* Throws exception on error.
|
||||||
*/
|
*/
|
||||||
std::chrono::steady_clock::duration
|
std::chrono::steady_clock::duration
|
||||||
PrepareAlsaPcmSockets(MultiSocketMonitor &m, snd_pcm_t *pcm,
|
PrepareAlsaPcmSockets(MultiSocketMonitor &m, snd_pcm_t *pcm,
|
||||||
ReusableArray<pollfd> &pfd_buffer) noexcept;
|
ReusableArray<pollfd> &pfd_buffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update #MultiSocketMonitor's socket list from
|
* Update #MultiSocketMonitor's socket list from
|
||||||
|
@ -815,7 +815,13 @@ AlsaOutput::PrepareSockets() noexcept
|
|||||||
return std::chrono::steady_clock::duration(-1);
|
return std::chrono::steady_clock::duration(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return PrepareAlsaPcmSockets(*this, pcm, pfd_buffer);
|
try {
|
||||||
|
return PrepareAlsaPcmSockets(*this, pcm, pfd_buffer);
|
||||||
|
} catch (...) {
|
||||||
|
ClearSocketList();
|
||||||
|
LockCaughtError();
|
||||||
|
return std::chrono::steady_clock::duration(-1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user