This missing piece probably never really hurt, because
HttpdClient::OnSocketClosed() would be called right after a socket
error, but it's better to be explicit about closing on error.
Fixes#184.
Semaphores are kernel-managed objects, calling delete_sem() twice is not more
dangerous than calling close() twice on an fd though, it would just return
an error.
Unlike pa_channel_map_init_auto(), pa_channel_map_init_extend() does
not fail if there is no valid mapping for the given channel count, but
instead maps additional "AUX" channels.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/493
Currently it falls back to system default device (either internal speaker or headphone) when device not found.
I believe it is a better to fail in this case, to make it better aligned with platforms (such as alsa).
libwrap is an obscure artefact from a past long ago, when source IP
address meant something.
And its API is "interesting"; it requires the application to expose
two global variables `allow_severity` and `deny_severity`. This led
to bug #437. I don't want to declare those variables; instead, I'd
like to remove libwrap support.
Closes#437
Since we switched from autotools to Meson in commit
94592c1406, we don't need to include
`config.h` early to properly enable large file support. Meson passes
the required macros on the compiler command line instead of defining
them in `config.h`.
This means we can include `config.h` at any time, whenever we want to
check its macros, and there are no ordering constraints.
Works around a problem where MPD goes into a busy loop because
snd_pcm_drain() always returns `-EAGAIN` without making any progress
(fixes#425).
This problem was triggered by snd_pcm_drain() after snd_pcm_cancel()
and snd_pcm_prepare(), but without submitting any data with
snd_pcm_writei().
I believe this is a kernel bug: in non-blocking mode, the kernel's
snd_pcm_drain() function returns early. In this mode, it only checks
whether snd_pcm_drain_done() has been called already, but
snd_pcm_drain_done() is never called if no data was submitted.
In blocking mode, the following `for` loop detects this condition, so
snd_pcm_drain_done() is not necessary, but without this extra check,
we get `-EAGAIN` forever.
This fixes a problem which caused a failure with snd_pcm_writei()
because snd_pcm_drain() had already been called in the previous
iteration. This commit makes sure that snd_pcm_drain() is only called
after the final snd_pcm_writei() call.
This fixes discarded samples at the end of playback.
If our `ring_buffer` is smaller than the ALSA-PCM buffer (if the
latter has more than the 4 periods we allocate), it can happen that
the start threshold is crossed and ALSA switches to
`SND_PCM_STATE_RUNNING`, but the `ring_buffer` is empty. In this
case, MPDD will generate silence, even though the ALSA-PCM buffer has
enough data. This causes stuttering (#420).
This commit amends an older workaround for a similar problem (commit
e08598e7e2) by adding a snd_pcm_avail()
check, and only generate silence if there is less than one period of
data in the ALSA-PCM buffer.
Fixes#420
The method Cancel() assumes that the `period_buffer` must be empty
when `active==false`, but that is not the case when Play() fails.
Of course the assertion in Cancel() is not 100% correct, but I decided
to rather fix this in LockCaughtError() because the `period_buffer`
should only be accessed from within the RTIO thread, and this is the
only code path where `active` can be set to `false` with a non-empty
`period_buffer`.
Fixes#423
This check was added 9 years ago in commit
4dc25d3908 to work around a dmix bug
which I assume has been fixed long ago.
Removing this fixes another corner case: if draining is requested
before the start threshold is reached, the PCM is still in
SND_PCM_STATE_PREPARED but not yet SND_PCM_STATE_RUNNING, which means
the submitted data will never be played. This corner case is
realistic when playing songs shorter than the ALSA buffer (if the
buffer is very large).
This fixes a corner case which has probably never occurred and
probably never will: if Cancel() is called, and then Play() followed
by Drain(), the plugin should really play that data. However
currently, this never happens, because snd_pcm_prepare() is never
called.