diff --git a/src/lib/alsa/NonBlock.cxx b/src/lib/alsa/NonBlock.cxx index 800bc4886..a20255bcc 100644 --- a/src/lib/alsa/NonBlock.cxx +++ b/src/lib/alsa/NonBlock.cxx @@ -7,6 +7,25 @@ namespace Alsa { +std::span +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(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(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(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 diff --git a/src/lib/alsa/NonBlock.hxx b/src/lib/alsa/NonBlock.hxx index aae992f50..16cfb3102 100644 --- a/src/lib/alsa/NonBlock.hxx +++ b/src/lib/alsa/NonBlock.hxx @@ -8,16 +8,30 @@ #include +#include + class MultiSocketMonitor; namespace Alsa { +class NonBlock { + ReusableArray buffer; + +public: + std::span Allocate(std::size_t n) noexcept { + return {buffer.Get(n), n}; + } + + std::span 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 pfd_buffer; + NonBlock base; public: /** @@ -40,7 +54,7 @@ public: * manages the file descriptors for a #snd_mixer_t. */ class NonBlockMixer { - ReusableArray pfd_buffer; + NonBlock base; public: Event::Duration PrepareSockets(MultiSocketMonitor &m,