lib/alsa/NonBlock: add common base class
This commit is contained in:
parent
3db8a4f41b
commit
4486b2eded
|
@ -7,6 +7,25 @@
|
|||
|
||||
namespace Alsa {
|
||||
|
||||
std::span<pollfd>
|
||||
NonBlock::CopyReturnedEvents(MultiSocketMonitor &m, std::size_t n) noexcept
|
||||
{
|
||||
const auto pfds = buffer.Get(n), end = pfds + n;
|
||||
|
||||
auto *i = pfds;
|
||||
m.ForEachReturnedEvent([&i, end](SocketDescriptor s, unsigned events){
|
||||
if (i >= end)
|
||||
return;
|
||||
|
||||
i->fd = s.Get();
|
||||
i->events = i->revents = events;
|
||||
++i;
|
||||
});
|
||||
|
||||
return {pfds, static_cast<std::size_t>(i - pfds)};
|
||||
|
||||
}
|
||||
|
||||
Event::Duration
|
||||
NonBlockPcm::PrepareSockets(MultiSocketMonitor &m, snd_pcm_t *pcm)
|
||||
{
|
||||
|
@ -18,9 +37,9 @@ NonBlockPcm::PrepareSockets(MultiSocketMonitor &m, snd_pcm_t *pcm)
|
|||
throw Alsa::MakeError(count, "snd_pcm_poll_descriptors_count() failed");
|
||||
}
|
||||
|
||||
struct pollfd *pfds = pfd_buffer.Get(count);
|
||||
const auto pfds = base.Allocate(count);
|
||||
|
||||
count = snd_pcm_poll_descriptors(pcm, pfds, count);
|
||||
count = snd_pcm_poll_descriptors(pcm, pfds.data(), count);
|
||||
if (count <= 0) {
|
||||
if (count == 0)
|
||||
throw std::runtime_error("snd_pcm_poll_descriptors() failed");
|
||||
|
@ -28,7 +47,7 @@ NonBlockPcm::PrepareSockets(MultiSocketMonitor &m, snd_pcm_t *pcm)
|
|||
throw Alsa::MakeError(count, "snd_pcm_poll_descriptors() failed");
|
||||
}
|
||||
|
||||
m.ReplaceSocketList({pfds, static_cast<std::size_t>(count)});
|
||||
m.ReplaceSocketList(pfds.first(count));
|
||||
return Event::Duration(-1);
|
||||
}
|
||||
|
||||
|
@ -39,20 +58,10 @@ NonBlockPcm::DispatchSockets(MultiSocketMonitor &m, snd_pcm_t *pcm)
|
|||
if (count <= 0)
|
||||
return;
|
||||
|
||||
const auto pfds = pfd_buffer.Get(count), end = pfds + count;
|
||||
|
||||
auto *i = pfds;
|
||||
m.ForEachReturnedEvent([&i, end](SocketDescriptor s, unsigned events){
|
||||
if (i >= end)
|
||||
return;
|
||||
|
||||
i->fd = s.Get();
|
||||
i->events = i->revents = events;
|
||||
++i;
|
||||
});
|
||||
const auto pfds = base.CopyReturnedEvents(m, count);
|
||||
|
||||
unsigned short dummy;
|
||||
int err = snd_pcm_poll_descriptors_revents(pcm, pfds, i - pfds, &dummy);
|
||||
int err = snd_pcm_poll_descriptors_revents(pcm, pfds.data(), pfds.size(), &dummy);
|
||||
if (err < 0)
|
||||
throw Alsa::MakeError(err, "snd_pcm_poll_descriptors_revents() failed");
|
||||
}
|
||||
|
@ -66,13 +75,13 @@ NonBlockMixer::PrepareSockets(MultiSocketMonitor &m, snd_mixer_t *mixer) noexcep
|
|||
return Event::Duration(-1);
|
||||
}
|
||||
|
||||
struct pollfd *pfds = pfd_buffer.Get(count);
|
||||
const auto pfds = base.Allocate(count);
|
||||
|
||||
count = snd_mixer_poll_descriptors(mixer, pfds, count);
|
||||
count = snd_mixer_poll_descriptors(mixer, pfds.data(), count);
|
||||
if (count < 0)
|
||||
count = 0;
|
||||
|
||||
m.ReplaceSocketList({pfds, static_cast<std::size_t>(count)});
|
||||
m.ReplaceSocketList(pfds.first(count));
|
||||
return Event::Duration(-1);
|
||||
}
|
||||
|
||||
|
@ -83,20 +92,10 @@ NonBlockMixer::DispatchSockets(MultiSocketMonitor &m, snd_mixer_t *mixer) noexce
|
|||
if (count <= 0)
|
||||
return;
|
||||
|
||||
const auto pfds = pfd_buffer.Get(count), end = pfds + count;
|
||||
|
||||
auto *i = pfds;
|
||||
m.ForEachReturnedEvent([&i, end](SocketDescriptor s, unsigned events){
|
||||
if (i >= end)
|
||||
return;
|
||||
|
||||
i->fd = s.Get();
|
||||
i->events = i->revents = events;
|
||||
++i;
|
||||
});
|
||||
const auto pfds = base.CopyReturnedEvents(m, count);
|
||||
|
||||
unsigned short dummy;
|
||||
snd_mixer_poll_descriptors_revents(mixer, pfds, i - pfds, &dummy);
|
||||
snd_mixer_poll_descriptors_revents(mixer, pfds.data(), pfds.size(), &dummy);
|
||||
}
|
||||
|
||||
} // namespace Alsa
|
||||
|
|
|
@ -8,16 +8,30 @@
|
|||
|
||||
#include <alsa/asoundlib.h>
|
||||
|
||||
#include <span>
|
||||
|
||||
class MultiSocketMonitor;
|
||||
|
||||
namespace Alsa {
|
||||
|
||||
class NonBlock {
|
||||
ReusableArray<pollfd> buffer;
|
||||
|
||||
public:
|
||||
std::span<pollfd> Allocate(std::size_t n) noexcept {
|
||||
return {buffer.Get(n), n};
|
||||
}
|
||||
|
||||
std::span<pollfd> CopyReturnedEvents(MultiSocketMonitor &m,
|
||||
std::size_t n) noexcept;
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper class for #MultiSocketMonitor's virtual methods which
|
||||
* manages the file descriptors for a #snd_pcm_t.
|
||||
*/
|
||||
class NonBlockPcm {
|
||||
ReusableArray<pollfd> pfd_buffer;
|
||||
NonBlock base;
|
||||
|
||||
public:
|
||||
/**
|
||||
|
@ -40,7 +54,7 @@ public:
|
|||
* manages the file descriptors for a #snd_mixer_t.
|
||||
*/
|
||||
class NonBlockMixer {
|
||||
ReusableArray<pollfd> pfd_buffer;
|
||||
NonBlock base;
|
||||
|
||||
public:
|
||||
Event::Duration PrepareSockets(MultiSocketMonitor &m,
|
||||
|
|
Loading…
Reference in New Issue