Change error message handling

Change the handling of non-fatal errors.  Now the non-fatal error
messages are not shown in stderr and no assert() as default.  The
behavior can be changed with LIBASOUND_DEBUG environment variable.
This commit is contained in:
Takashi Iwai 2004-12-21 14:11:00 +00:00
parent 73aa2549d9
commit 2b54677fdb
9 changed files with 462 additions and 165 deletions

14
NOTES
View file

@ -14,3 +14,17 @@ this API, because they are no longer used:
#define ALSA_PCM_NEW_HW_PARAMS_API #define ALSA_PCM_NEW_HW_PARAMS_API
#define ALSA_PCM_NEW_SW_PARAMS_API #define ALSA_PCM_NEW_SW_PARAMS_API
Verbose Error Messages
======================
Since version 1.0.8, assert() for some non-fatal errors are removed
and error messages are no longer shown to stderr as default. Instead,
the error messages appear only when the environment variable
LIBASOUND_DEBUG is set. When LIBASOUND_DEBUG=assert is set, the
default error message handler calls assert() to catch with a
debugger.
This feature is disabled when --with-debug=no is passed to configure,
i.e. no strict checking is done in alsa-lib.

View file

@ -155,6 +155,22 @@ int safe_strtol(const char *str, long *val);
int snd_send_fd(int sock, void *data, size_t len, int fd); int snd_send_fd(int sock, void *data, size_t len, int fd);
int snd_receive_fd(int sock, void *data, size_t len, int *fd); int snd_receive_fd(int sock, void *data, size_t len, int *fd);
/*
* error messages
*/
#ifndef NDEBUG
#define CHECK_SANITY(x) x
extern snd_lib_error_handler_t snd_err_msg;
#define SNDMSG(args...) snd_err_msg(__FILE__, __LINE__, __FUNCTION__, 0, ##args)
#define SYSMSG(args...) snd_err_msg(__FILE__, __LINE__, __FUNCTION__, errno, ##args)
#else
#define CHECK_SANITY(x) 0 /* not evaluated */
#define SNDMSG(args...) /* nop */
#define SYSMSG(args...) /* nop */
#endif
/*
*/
#define HAVE_GNU_LD #define HAVE_GNU_LD
#define HAVE_ELF #define HAVE_ELF
#define HAVE_ASM_PREVIOUS_DIRECTIVE #define HAVE_ASM_PREVIOUS_DIRECTIVE

View file

@ -100,6 +100,10 @@ snd_lib_error_handler_t snd_lib_error = snd_lib_error_default;
int snd_lib_error_set_handler(snd_lib_error_handler_t handler) int snd_lib_error_set_handler(snd_lib_error_handler_t handler)
{ {
snd_lib_error = handler == NULL ? snd_lib_error_default : handler; snd_lib_error = handler == NULL ? snd_lib_error_default : handler;
#ifndef NDEBUG
if (snd_lib_error != snd_lib_error_default)
snd_err_msg = snd_lib_error;
#endif
return 0; return 0;
} }
@ -111,3 +115,30 @@ const char *snd_asoundlib_version(void)
{ {
return SND_LIB_VERSION_STR; return SND_LIB_VERSION_STR;
} }
#ifndef NDEBUG
/*
* internal error handling
*/
static void snd_err_msg_default(const char *file, int line, const char *function, int err, const char *fmt, ...)
{
va_list arg;
const char *verbose;
verbose = getenv("LIBASOUND_DEBUG");
if (! verbose || ! *verbose)
return;
va_start(arg, fmt);
fprintf(stderr, "ALSA lib %s:%i:(%s) ", file, line, function);
vfprintf(stderr, fmt, arg);
if (err)
fprintf(stderr, ": %s", snd_strerror(err));
putc('\n', stderr);
va_end(arg);
if (! strcmp(verbose, "assert"))
assert(0);
}
snd_lib_error_handler_t snd_err_msg = snd_err_msg_default;
#endif

View file

@ -797,7 +797,8 @@ int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
int snd_pcm_hw_free(snd_pcm_t *pcm) int snd_pcm_hw_free(snd_pcm_t *pcm)
{ {
int err; int err;
assert(pcm->setup); if (! pcm->setup)
return 0;
if (pcm->mmap_channels) { if (pcm->mmap_channels) {
err = snd_pcm_munmap(pcm); err = snd_pcm_munmap(pcm);
if (err < 0) if (err < 0)
@ -820,17 +821,21 @@ int snd_pcm_hw_free(snd_pcm_t *pcm)
int snd_pcm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params) int snd_pcm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
{ {
int err; int err;
assert(pcm->setup); /* the hw_params must be set at first!!! */ /* the hw_params must be set at first!!! */
if (CHECK_SANITY(! pcm->setup)) {
SNDMSG("PCM not set up");
return -EIO;
}
if (! params->avail_min || ! params->xfer_align) if (! params->avail_min || ! params->xfer_align)
return -EINVAL; return -EINVAL;
if (params->start_threshold <= pcm->buffer_size && if (params->start_threshold <= pcm->buffer_size &&
params->start_threshold > (pcm->buffer_size / params->avail_min) * params->avail_min) { params->start_threshold > (pcm->buffer_size / params->avail_min) * params->avail_min) {
SNDERR("snd_pcm_sw_params: params->avail_min problem for start_threshold"); SNDMSG("params->avail_min problem for start_threshold");
return -EINVAL; return -EINVAL;
} }
if (params->start_threshold <= pcm->buffer_size && if (params->start_threshold <= pcm->buffer_size &&
params->start_threshold > (pcm->buffer_size / params->xfer_align) * params->xfer_align) { params->start_threshold > (pcm->buffer_size / params->xfer_align) * params->xfer_align) {
SNDERR("snd_pcm_sw_params: params->xfer_align problem for start_threshold"); SNDMSG("params->xfer_align problem for start_threshold");
return -EINVAL; return -EINVAL;
} }
err = pcm->ops->sw_params(pcm->op_arg, params); err = pcm->ops->sw_params(pcm->op_arg, params);
@ -887,7 +892,10 @@ snd_pcm_state_t snd_pcm_state(snd_pcm_t *pcm)
int snd_pcm_hwsync(snd_pcm_t *pcm) int snd_pcm_hwsync(snd_pcm_t *pcm)
{ {
assert(pcm); assert(pcm);
assert(pcm->setup); if (CHECK_SANITY(! pcm->setup)) {
SNDMSG("PCM not set up");
return -EIO;
}
return pcm->fast_ops->hwsync(pcm->fast_op_arg); return pcm->fast_ops->hwsync(pcm->fast_op_arg);
} }
@ -910,7 +918,10 @@ int snd_pcm_hwsync(snd_pcm_t *pcm)
int snd_pcm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp) int snd_pcm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
{ {
assert(pcm); assert(pcm);
assert(pcm->setup); if (CHECK_SANITY(! pcm->setup)) {
SNDMSG("PCM not set up");
return -EIO;
}
return pcm->fast_ops->delay(pcm->fast_op_arg, delayp); return pcm->fast_ops->delay(pcm->fast_op_arg, delayp);
} }
@ -929,7 +940,10 @@ int snd_pcm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
int snd_pcm_resume(snd_pcm_t *pcm) int snd_pcm_resume(snd_pcm_t *pcm)
{ {
assert(pcm); assert(pcm);
assert(pcm->setup); if (CHECK_SANITY(! pcm->setup)) {
SNDMSG("PCM not set up");
return -EIO;
}
return pcm->fast_ops->resume(pcm->fast_op_arg); return pcm->fast_ops->resume(pcm->fast_op_arg);
} }
@ -941,7 +955,10 @@ int snd_pcm_resume(snd_pcm_t *pcm)
int snd_pcm_prepare(snd_pcm_t *pcm) int snd_pcm_prepare(snd_pcm_t *pcm)
{ {
assert(pcm); assert(pcm);
assert(pcm->setup); if (CHECK_SANITY(! pcm->setup)) {
SNDMSG("PCM not set up");
return -EIO;
}
return pcm->fast_ops->prepare(pcm->fast_op_arg); return pcm->fast_ops->prepare(pcm->fast_op_arg);
} }
@ -955,7 +972,10 @@ int snd_pcm_prepare(snd_pcm_t *pcm)
int snd_pcm_reset(snd_pcm_t *pcm) int snd_pcm_reset(snd_pcm_t *pcm)
{ {
assert(pcm); assert(pcm);
assert(pcm->setup); if (CHECK_SANITY(! pcm->setup)) {
SNDMSG("PCM not set up");
return -EIO;
}
return pcm->fast_ops->reset(pcm->fast_op_arg); return pcm->fast_ops->reset(pcm->fast_op_arg);
} }
@ -967,7 +987,10 @@ int snd_pcm_reset(snd_pcm_t *pcm)
int snd_pcm_start(snd_pcm_t *pcm) int snd_pcm_start(snd_pcm_t *pcm)
{ {
assert(pcm); assert(pcm);
assert(pcm->setup); if (CHECK_SANITY(! pcm->setup)) {
SNDMSG("PCM not set up");
return -EIO;
}
return pcm->fast_ops->start(pcm->fast_op_arg); return pcm->fast_ops->start(pcm->fast_op_arg);
} }
@ -985,7 +1008,10 @@ int snd_pcm_start(snd_pcm_t *pcm)
int snd_pcm_drop(snd_pcm_t *pcm) int snd_pcm_drop(snd_pcm_t *pcm)
{ {
assert(pcm); assert(pcm);
assert(pcm->setup); if (CHECK_SANITY(! pcm->setup)) {
SNDMSG("PCM not set up");
return -EIO;
}
return pcm->fast_ops->drop(pcm->fast_op_arg); return pcm->fast_ops->drop(pcm->fast_op_arg);
} }
@ -1005,7 +1031,10 @@ int snd_pcm_drop(snd_pcm_t *pcm)
int snd_pcm_drain(snd_pcm_t *pcm) int snd_pcm_drain(snd_pcm_t *pcm)
{ {
assert(pcm); assert(pcm);
assert(pcm->setup); if (CHECK_SANITY(! pcm->setup)) {
SNDMSG("PCM not set up");
return -EIO;
}
return pcm->fast_ops->drain(pcm->fast_op_arg); return pcm->fast_ops->drain(pcm->fast_op_arg);
} }
@ -1022,7 +1051,10 @@ int snd_pcm_drain(snd_pcm_t *pcm)
int snd_pcm_pause(snd_pcm_t *pcm, int enable) int snd_pcm_pause(snd_pcm_t *pcm, int enable)
{ {
assert(pcm); assert(pcm);
assert(pcm->setup); if (CHECK_SANITY(! pcm->setup)) {
SNDMSG("PCM not set up");
return -EIO;
}
return pcm->fast_ops->pause(pcm->fast_op_arg, enable); return pcm->fast_ops->pause(pcm->fast_op_arg, enable);
} }
@ -1036,8 +1068,12 @@ int snd_pcm_pause(snd_pcm_t *pcm, int enable)
snd_pcm_sframes_t snd_pcm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames) snd_pcm_sframes_t snd_pcm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{ {
assert(pcm); assert(pcm);
assert(pcm->setup); if (CHECK_SANITY(! pcm->setup)) {
assert(frames > 0); SNDMSG("PCM not set up");
return -EIO;
}
if (frames == 0)
return 0;
return pcm->fast_ops->rewind(pcm->fast_op_arg, frames); return pcm->fast_ops->rewind(pcm->fast_op_arg, frames);
} }
@ -1055,8 +1091,12 @@ snd_pcm_sframes_t snd_pcm_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
#endif #endif
{ {
assert(pcm); assert(pcm);
assert(pcm->setup); if (CHECK_SANITY(! pcm->setup)) {
assert(frames > 0); SNDMSG("PCM not set up");
return -EIO;
}
if (frames == 0)
return 0;
return pcm->fast_ops->forward(pcm->fast_op_arg, frames); return pcm->fast_ops->forward(pcm->fast_op_arg, frames);
} }
use_default_symbol_version(__snd_pcm_forward, snd_pcm_forward, ALSA_0.9.0rc8); use_default_symbol_version(__snd_pcm_forward, snd_pcm_forward, ALSA_0.9.0rc8);
@ -1082,8 +1122,14 @@ snd_pcm_sframes_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_ufr
{ {
assert(pcm); assert(pcm);
assert(size == 0 || buffer); assert(size == 0 || buffer);
assert(pcm->setup); if (CHECK_SANITY(! pcm->setup)) {
assert(pcm->access == SND_PCM_ACCESS_RW_INTERLEAVED); SNDMSG("PCM not set up");
return -EIO;
}
if (pcm->access != SND_PCM_ACCESS_RW_INTERLEAVED) {
SNDMSG("invalid access type %s", snd_pcm_access_name(pcm->access));
return -EINVAL;
}
return _snd_pcm_writei(pcm, buffer, size); return _snd_pcm_writei(pcm, buffer, size);
} }
@ -1108,8 +1154,14 @@ snd_pcm_sframes_t snd_pcm_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t
{ {
assert(pcm); assert(pcm);
assert(size == 0 || bufs); assert(size == 0 || bufs);
assert(pcm->setup); if (CHECK_SANITY(! pcm->setup)) {
assert(pcm->access == SND_PCM_ACCESS_RW_NONINTERLEAVED); SNDMSG("PCM not set up");
return -EIO;
}
if (pcm->access != SND_PCM_ACCESS_RW_NONINTERLEAVED) {
SNDMSG("invalid access type %s", snd_pcm_access_name(pcm->access));
return -EINVAL;
}
return _snd_pcm_writen(pcm, bufs, size); return _snd_pcm_writen(pcm, bufs, size);
} }
@ -1134,8 +1186,14 @@ snd_pcm_sframes_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t
{ {
assert(pcm); assert(pcm);
assert(size == 0 || buffer); assert(size == 0 || buffer);
assert(pcm->setup); if (CHECK_SANITY(! pcm->setup)) {
assert(pcm->access == SND_PCM_ACCESS_RW_INTERLEAVED); SNDMSG("PCM not set up");
return -EIO;
}
if (pcm->access != SND_PCM_ACCESS_RW_INTERLEAVED) {
SNDMSG("invalid access type %s", snd_pcm_access_name(pcm->access));
return -EINVAL;
}
return _snd_pcm_readi(pcm, buffer, size); return _snd_pcm_readi(pcm, buffer, size);
} }
@ -1160,8 +1218,14 @@ snd_pcm_sframes_t snd_pcm_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t s
{ {
assert(pcm); assert(pcm);
assert(size == 0 || bufs); assert(size == 0 || bufs);
assert(pcm->setup); if (CHECK_SANITY(! pcm->setup)) {
assert(pcm->access == SND_PCM_ACCESS_RW_NONINTERLEAVED); SNDMSG("PCM not set up");
return -EIO;
}
if (pcm->access != SND_PCM_ACCESS_RW_NONINTERLEAVED) {
SNDMSG("invalid access type %s", snd_pcm_access_name(pcm->access));
return -EINVAL;
}
return _snd_pcm_readn(pcm, bufs, size); return _snd_pcm_readn(pcm, bufs, size);
} }
@ -1180,7 +1244,7 @@ int snd_pcm_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2)
if (fd1 < 0 || fd2 < 0) if (fd1 < 0 || fd2 < 0)
return -ENOSYS; return -ENOSYS;
if (ioctl(fd1, SNDRV_PCM_IOCTL_LINK, fd2) < 0) { if (ioctl(fd1, SNDRV_PCM_IOCTL_LINK, fd2) < 0) {
SYSERR("SNDRV_PCM_IOCTL_LINK failed"); SYSMSG("SNDRV_PCM_IOCTL_LINK failed");
return -errno; return -errno;
} }
return 0; return 0;
@ -1196,7 +1260,7 @@ int snd_pcm_unlink(snd_pcm_t *pcm)
int fd; int fd;
fd = _snd_pcm_link_descriptor(pcm); fd = _snd_pcm_link_descriptor(pcm);
if (ioctl(fd, SNDRV_PCM_IOCTL_UNLINK) < 0) { if (ioctl(fd, SNDRV_PCM_IOCTL_UNLINK) < 0) {
SYSERR("SNDRV_PCM_IOCTL_UNLINK failed"); SYSMSG("SNDRV_PCM_IOCTL_UNLINK failed");
return -errno; return -errno;
} }
return 0; return 0;
@ -1248,7 +1312,10 @@ int snd_pcm_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int s
if (err < 0) if (err < 0)
return err; return err;
} }
assert(pcm->poll_fd >= 0); if (! pcm->poll_fd < 0) {
SNDMSG("poll_fd < 0");
return -EIO;
}
if (space >= 1 && pfds) { if (space >= 1 && pfds) {
pfds->fd = pcm->poll_fd; pfds->fd = pcm->poll_fd;
pfds->events = pcm->poll_events | POLLERR | POLLNVAL; pfds->events = pcm->poll_events | POLLERR | POLLNVAL;
@ -1470,7 +1537,8 @@ static const char *snd_pcm_tstamp_mode_names[] = {
*/ */
const char *snd_pcm_stream_name(snd_pcm_stream_t stream) const char *snd_pcm_stream_name(snd_pcm_stream_t stream)
{ {
assert(stream <= SND_PCM_STREAM_LAST); if (stream > SND_PCM_STREAM_LAST)
return NULL;
return snd_pcm_stream_names[stream]; return snd_pcm_stream_names[stream];
} }
@ -1564,7 +1632,8 @@ const char *snd_pcm_subformat_description(snd_pcm_subformat_t subformat)
*/ */
const char *snd_pcm_start_mode_name(snd_pcm_start_t mode) const char *snd_pcm_start_mode_name(snd_pcm_start_t mode)
{ {
assert(mode <= SND_PCM_START_LAST); if (mode > SND_PCM_START_LAST)
return NULL;
return snd_pcm_start_mode_names[mode]; return snd_pcm_start_mode_names[mode];
} }
@ -1579,7 +1648,8 @@ link_warning(snd_pcm_start_mode_name, "Warning: start_mode is deprecated, consid
*/ */
const char *snd_pcm_xrun_mode_name(snd_pcm_xrun_t mode) const char *snd_pcm_xrun_mode_name(snd_pcm_xrun_t mode)
{ {
assert(mode <= SND_PCM_XRUN_LAST); if (mode > SND_PCM_XRUN_LAST)
return NULL;
return snd_pcm_xrun_mode_names[mode]; return snd_pcm_xrun_mode_names[mode];
} }
@ -1638,7 +1708,10 @@ int snd_pcm_dump_hw_setup(snd_pcm_t *pcm, snd_output_t *out)
{ {
assert(pcm); assert(pcm);
assert(out); assert(out);
assert(pcm->setup); if (CHECK_SANITY(! pcm->setup)) {
SNDMSG("PCM not set up");
return -EIO;
}
snd_output_printf(out, "stream : %s\n", snd_pcm_stream_name(pcm->stream)); snd_output_printf(out, "stream : %s\n", snd_pcm_stream_name(pcm->stream));
snd_output_printf(out, "access : %s\n", snd_pcm_access_name(pcm->access)); snd_output_printf(out, "access : %s\n", snd_pcm_access_name(pcm->access));
snd_output_printf(out, "format : %s\n", snd_pcm_format_name(pcm->format)); snd_output_printf(out, "format : %s\n", snd_pcm_format_name(pcm->format));
@ -1664,7 +1737,10 @@ int snd_pcm_dump_sw_setup(snd_pcm_t *pcm, snd_output_t *out)
{ {
assert(pcm); assert(pcm);
assert(out); assert(out);
assert(pcm->setup); if (CHECK_SANITY(! pcm->setup)) {
SNDMSG("PCM not set up");
return -EIO;
}
snd_output_printf(out, "tstamp_mode : %s\n", snd_pcm_tstamp_mode_name(pcm->tstamp_mode)); snd_output_printf(out, "tstamp_mode : %s\n", snd_pcm_tstamp_mode_name(pcm->tstamp_mode));
snd_output_printf(out, "period_step : %d\n", pcm->period_step); snd_output_printf(out, "period_step : %d\n", pcm->period_step);
snd_output_printf(out, "sleep_min : %d\n", pcm->sleep_min); snd_output_printf(out, "sleep_min : %d\n", pcm->sleep_min);
@ -1734,7 +1810,10 @@ int snd_pcm_dump(snd_pcm_t *pcm, snd_output_t *out)
snd_pcm_sframes_t snd_pcm_bytes_to_frames(snd_pcm_t *pcm, ssize_t bytes) snd_pcm_sframes_t snd_pcm_bytes_to_frames(snd_pcm_t *pcm, ssize_t bytes)
{ {
assert(pcm); assert(pcm);
assert(pcm->setup); if (CHECK_SANITY(! pcm->setup)) {
SNDMSG("PCM not set up");
return -EIO;
}
return bytes * 8 / pcm->frame_bits; return bytes * 8 / pcm->frame_bits;
} }
@ -1747,7 +1826,10 @@ snd_pcm_sframes_t snd_pcm_bytes_to_frames(snd_pcm_t *pcm, ssize_t bytes)
ssize_t snd_pcm_frames_to_bytes(snd_pcm_t *pcm, snd_pcm_sframes_t frames) ssize_t snd_pcm_frames_to_bytes(snd_pcm_t *pcm, snd_pcm_sframes_t frames)
{ {
assert(pcm); assert(pcm);
assert(pcm->setup); if (CHECK_SANITY(! pcm->setup)) {
SNDMSG("PCM not set up");
return -EIO;
}
return frames * pcm->frame_bits / 8; return frames * pcm->frame_bits / 8;
} }
@ -1760,7 +1842,10 @@ ssize_t snd_pcm_frames_to_bytes(snd_pcm_t *pcm, snd_pcm_sframes_t frames)
long snd_pcm_bytes_to_samples(snd_pcm_t *pcm, ssize_t bytes) long snd_pcm_bytes_to_samples(snd_pcm_t *pcm, ssize_t bytes)
{ {
assert(pcm); assert(pcm);
assert(pcm->setup); if (CHECK_SANITY(! pcm->setup)) {
SNDMSG("PCM not set up");
return -EIO;
}
return bytes * 8 / pcm->sample_bits; return bytes * 8 / pcm->sample_bits;
} }
@ -1773,7 +1858,10 @@ long snd_pcm_bytes_to_samples(snd_pcm_t *pcm, ssize_t bytes)
ssize_t snd_pcm_samples_to_bytes(snd_pcm_t *pcm, long samples) ssize_t snd_pcm_samples_to_bytes(snd_pcm_t *pcm, long samples)
{ {
assert(pcm); assert(pcm);
assert(pcm->setup); if (CHECK_SANITY(! pcm->setup)) {
SNDMSG("PCM not set up");
return -EIO;
}
return samples * pcm->sample_bits / 8; return samples * pcm->sample_bits / 8;
} }
@ -1819,7 +1907,10 @@ int snd_async_add_pcm_handler(snd_async_handler_t **handler, snd_pcm_t *pcm,
*/ */
snd_pcm_t *snd_async_handler_get_pcm(snd_async_handler_t *handler) snd_pcm_t *snd_async_handler_get_pcm(snd_async_handler_t *handler)
{ {
assert(handler->type == SND_ASYNC_HANDLER_PCM); if (handler->type == SND_ASYNC_HANDLER_PCM) {
SNDMSG("invalid handler type %d", handler->type);
return NULL;
}
return handler->u.pcm; return handler->u.pcm;
} }
@ -2099,7 +2190,10 @@ int snd_pcm_wait(snd_pcm_t *pcm, int timeout)
err = snd_pcm_poll_descriptors(pcm, &pfd, 1); err = snd_pcm_poll_descriptors(pcm, &pfd, 1);
if (err < 0) if (err < 0)
return err; return err;
assert(err == 1); if (err != 1) {
SNDMSG("invalid poll descriptors %d\n", err);
return -EIO;
}
__retry: __retry:
err_poll = poll(&pfd, 1, timeout); err_poll = poll(&pfd, 1, timeout);
if (err_poll < 0) if (err_poll < 0)
@ -2250,7 +2344,8 @@ int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes
break; break;
} }
default: default:
assert(0); SNDMSG("invalid format width %d", width);
return -EINVAL;
} }
return 0; return 0;
} }
@ -2417,7 +2512,8 @@ int snd_pcm_area_copy(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes_t
break; break;
} }
default: default:
assert(0); SNDMSG("invalid format width %d", width);
return -EINVAL;
} }
return 0; return 0;
} }
@ -2440,8 +2536,14 @@ int snd_pcm_areas_copy(const snd_pcm_channel_area_t *dst_areas, snd_pcm_uframes_
int width = snd_pcm_format_physical_width(format); int width = snd_pcm_format_physical_width(format);
assert(dst_areas); assert(dst_areas);
assert(src_areas); assert(src_areas);
assert(channels > 0); if (! channels) {
assert(frames > 0); SNDMSG("invalid channels %d", channels);
return -EINVAL;
}
if (! frames) {
SNDMSG("invalid frames %ld", frames);
return -EINVAL;
}
while (channels > 0) { while (channels > 0) {
unsigned int step = src_areas->step; unsigned int step = src_areas->step;
void *src_addr = src_areas->addr; void *src_addr = src_areas->addr;
@ -2524,7 +2626,11 @@ int snd_pcm_hw_params_dump(snd_pcm_hw_params_t *params, snd_output_t *out)
*/ */
int snd_pcm_hw_params_can_mmap_sample_resolution(const snd_pcm_hw_params_t *params) int snd_pcm_hw_params_can_mmap_sample_resolution(const snd_pcm_hw_params_t *params)
{ {
assert(params && params->info != ~0U); assert(params);
if (CHECK_SANITY(params->info == ~0U)) {
SNDMSG("invalid PCM info field");
return 0; /* FIXME: should be a negative error? */
}
return !!(params->info & SNDRV_PCM_INFO_MMAP_VALID); return !!(params->info & SNDRV_PCM_INFO_MMAP_VALID);
} }
@ -2541,7 +2647,11 @@ int snd_pcm_hw_params_can_mmap_sample_resolution(const snd_pcm_hw_params_t *para
*/ */
int snd_pcm_hw_params_is_double(const snd_pcm_hw_params_t *params) int snd_pcm_hw_params_is_double(const snd_pcm_hw_params_t *params)
{ {
assert(params && params->info != ~0U); assert(params);
if (CHECK_SANITY(params->info == ~0U)) {
SNDMSG("invalid PCM info field");
return 0; /* FIXME: should be a negative error? */
}
return !!(params->info & SNDRV_PCM_INFO_DOUBLE); return !!(params->info & SNDRV_PCM_INFO_DOUBLE);
} }
@ -2558,7 +2668,11 @@ int snd_pcm_hw_params_is_double(const snd_pcm_hw_params_t *params)
*/ */
int snd_pcm_hw_params_is_batch(const snd_pcm_hw_params_t *params) int snd_pcm_hw_params_is_batch(const snd_pcm_hw_params_t *params)
{ {
assert(params && params->info != ~0U); assert(params);
if (CHECK_SANITY(params->info == ~0U)) {
SNDMSG("invalid PCM info field");
return 0; /* FIXME: should be a negative error? */
}
return !!(params->info & SNDRV_PCM_INFO_BATCH); return !!(params->info & SNDRV_PCM_INFO_BATCH);
} }
@ -2575,7 +2689,11 @@ int snd_pcm_hw_params_is_batch(const snd_pcm_hw_params_t *params)
*/ */
int snd_pcm_hw_params_is_block_transfer(const snd_pcm_hw_params_t *params) int snd_pcm_hw_params_is_block_transfer(const snd_pcm_hw_params_t *params)
{ {
assert(params && params->info != ~0U); assert(params);
if (CHECK_SANITY(params->info == ~0U)) {
SNDMSG("invalid PCM info field");
return 0; /* FIXME: should be a negative error? */
}
return !!(params->info & SNDRV_PCM_INFO_BLOCK_TRANSFER); return !!(params->info & SNDRV_PCM_INFO_BLOCK_TRANSFER);
} }
@ -2592,7 +2710,11 @@ int snd_pcm_hw_params_is_block_transfer(const snd_pcm_hw_params_t *params)
*/ */
int snd_pcm_hw_params_can_overrange(const snd_pcm_hw_params_t *params) int snd_pcm_hw_params_can_overrange(const snd_pcm_hw_params_t *params)
{ {
assert(params && params->info != ~0U); assert(params);
if (CHECK_SANITY(params->info == ~0U)) {
SNDMSG("invalid PCM info field");
return 0; /* FIXME: should be a negative error? */
}
return !!(params->info & SNDRV_PCM_INFO_OVERRANGE); return !!(params->info & SNDRV_PCM_INFO_OVERRANGE);
} }
@ -2609,7 +2731,11 @@ int snd_pcm_hw_params_can_overrange(const snd_pcm_hw_params_t *params)
*/ */
int snd_pcm_hw_params_can_pause(const snd_pcm_hw_params_t *params) int snd_pcm_hw_params_can_pause(const snd_pcm_hw_params_t *params)
{ {
assert(params && params->info != ~0U); assert(params);
if (CHECK_SANITY(params->info == ~0U)) {
SNDMSG("invalid PCM info field");
return 0; /* FIXME: should be a negative error? */
}
return !!(params->info & SNDRV_PCM_INFO_PAUSE); return !!(params->info & SNDRV_PCM_INFO_PAUSE);
} }
@ -2626,7 +2752,11 @@ int snd_pcm_hw_params_can_pause(const snd_pcm_hw_params_t *params)
*/ */
int snd_pcm_hw_params_can_resume(const snd_pcm_hw_params_t *params) int snd_pcm_hw_params_can_resume(const snd_pcm_hw_params_t *params)
{ {
assert(params && params->info != ~0U); assert(params);
if (CHECK_SANITY(params->info == ~0U)) {
SNDMSG("invalid PCM info field");
return 0; /* FIXME: should be a negative error? */
}
return !!(params->info & SNDRV_PCM_INFO_RESUME); return !!(params->info & SNDRV_PCM_INFO_RESUME);
} }
@ -2643,7 +2773,11 @@ int snd_pcm_hw_params_can_resume(const snd_pcm_hw_params_t *params)
*/ */
int snd_pcm_hw_params_is_half_duplex(const snd_pcm_hw_params_t *params) int snd_pcm_hw_params_is_half_duplex(const snd_pcm_hw_params_t *params)
{ {
assert(params && params->info != ~0U); assert(params);
if (CHECK_SANITY(params->info == ~0U)) {
SNDMSG("invalid PCM info field");
return 0; /* FIXME: should be a negative error? */
}
return !!(params->info & SNDRV_PCM_INFO_HALF_DUPLEX); return !!(params->info & SNDRV_PCM_INFO_HALF_DUPLEX);
} }
@ -2660,7 +2794,11 @@ int snd_pcm_hw_params_is_half_duplex(const snd_pcm_hw_params_t *params)
*/ */
int snd_pcm_hw_params_is_joint_duplex(const snd_pcm_hw_params_t *params) int snd_pcm_hw_params_is_joint_duplex(const snd_pcm_hw_params_t *params)
{ {
assert(params && params->info != ~0U); assert(params);
if (CHECK_SANITY(params->info == ~0U)) {
SNDMSG("invalid PCM info field");
return 0; /* FIXME: should be a negative error? */
}
return !!(params->info & SNDRV_PCM_INFO_JOINT_DUPLEX); return !!(params->info & SNDRV_PCM_INFO_JOINT_DUPLEX);
} }
@ -2677,7 +2815,11 @@ int snd_pcm_hw_params_is_joint_duplex(const snd_pcm_hw_params_t *params)
*/ */
int snd_pcm_hw_params_can_sync_start(const snd_pcm_hw_params_t *params) int snd_pcm_hw_params_can_sync_start(const snd_pcm_hw_params_t *params)
{ {
assert(params && params->info != ~0U); assert(params);
if (CHECK_SANITY(params->info == ~0U)) {
SNDMSG("invalid PCM info field");
return 0; /* FIXME: should be a negative error? */
}
return !!(params->info & SNDRV_PCM_INFO_SYNC_START); return !!(params->info & SNDRV_PCM_INFO_SYNC_START);
} }
@ -2695,7 +2837,11 @@ int snd_pcm_hw_params_can_sync_start(const snd_pcm_hw_params_t *params)
int snd_pcm_hw_params_get_rate_numden(const snd_pcm_hw_params_t *params, int snd_pcm_hw_params_get_rate_numden(const snd_pcm_hw_params_t *params,
unsigned int *rate_num, unsigned int *rate_den) unsigned int *rate_num, unsigned int *rate_den)
{ {
assert(params && params->rate_den != 0); assert(params);
if (CHECK_SANITY(params->rate_den == 0)) {
SNDMSG("invalid rate_den value");
return -EINVAL;
}
*rate_num = params->rate_num; *rate_num = params->rate_num;
*rate_den = params->rate_den; *rate_den = params->rate_den;
return 0; return 0;
@ -2712,7 +2858,11 @@ int snd_pcm_hw_params_get_rate_numden(const snd_pcm_hw_params_t *params,
*/ */
int snd_pcm_hw_params_get_sbits(const snd_pcm_hw_params_t *params) int snd_pcm_hw_params_get_sbits(const snd_pcm_hw_params_t *params)
{ {
assert(params && params->msbits != 0); assert(params);
if (CHECK_SANITY(params->msbits == 0)) {
SNDMSG("invalid msbits value");
return -EINVAL;
}
return params->msbits; return params->msbits;
} }
@ -2727,7 +2877,11 @@ int snd_pcm_hw_params_get_sbits(const snd_pcm_hw_params_t *params)
*/ */
int snd_pcm_hw_params_get_fifo_size(const snd_pcm_hw_params_t *params) int snd_pcm_hw_params_get_fifo_size(const snd_pcm_hw_params_t *params)
{ {
assert(params && params->info != ~0U); assert(params);
if (CHECK_SANITY(params->info == ~0U)) {
SNDMSG("invalid PCM info field");
return -EINVAL;
}
return params->fifo_size; return params->fifo_size;
} }
@ -4978,7 +5132,10 @@ int snd_pcm_hw_params_get_min_align(const snd_pcm_hw_params_t *params, snd_pcm_u
int snd_pcm_sw_params_current(snd_pcm_t *pcm, snd_pcm_sw_params_t *params) int snd_pcm_sw_params_current(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
{ {
assert(pcm && params); assert(pcm && params);
assert(pcm->setup); if (CHECK_SANITY(! pcm->setup)) {
SNDMSG("PCM not set up");
return -EIO;
}
params->tstamp_mode = pcm->tstamp_mode; params->tstamp_mode = pcm->tstamp_mode;
params->period_step = pcm->period_step; params->period_step = pcm->period_step;
params->sleep_min = pcm->sleep_min; params->sleep_min = pcm->sleep_min;
@ -5087,8 +5244,8 @@ int snd_pcm_sw_params_set_start_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params
params->start_threshold = pcm->boundary; params->start_threshold = pcm->boundary;
break; break;
default: default:
assert(0); SNDMSG("invalid start mode value %d\n", val);
break; return -EINVAL;
} }
return 0; return 0;
} }
@ -5135,8 +5292,8 @@ int snd_pcm_sw_params_set_xrun_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *params,
params->stop_threshold = pcm->boundary; params->stop_threshold = pcm->boundary;
break; break;
default: default:
assert(0); SNDMSG("invalid xrun mode value %d\n", val);
break; return -EINVAL;
} }
return 0; return 0;
} }
@ -5175,7 +5332,10 @@ int snd_pcm_sw_params_set_tstamp_mode(snd_pcm_t *pcm, snd_pcm_sw_params_t *param
#endif #endif
{ {
assert(pcm && params); assert(pcm && params);
assert(val <= SND_PCM_TSTAMP_LAST); if (CHECK_SANITY(val > SND_PCM_TSTAMP_LAST)) {
SNDMSG("invalid tstamp_mode value %d", val);
return -EINVAL;
}
params->tstamp_mode = val; params->tstamp_mode = val;
return 0; return 0;
} }
@ -5291,7 +5451,10 @@ int snd_pcm_sw_params_set_xfer_align(snd_pcm_t *pcm, snd_pcm_sw_params_t *params
#endif #endif
{ {
assert(pcm && params); assert(pcm && params);
assert(val % pcm->min_align == 0); if (CHECK_SANITY(val % pcm->min_align)) {
SNDMSG("xfer_align (%ld) is not aligned to min_align (%ld)", val, pcm->min_align);
return -EINVAL;
}
params->xfer_align = val; params->xfer_align = val;
return 0; return 0;
} }
@ -5420,7 +5583,11 @@ int snd_pcm_sw_params_set_silence_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t
#endif #endif
{ {
assert(pcm && params); assert(pcm && params);
assert(val < pcm->buffer_size); if (CHECK_SANITY(val >= pcm->buffer_size)) {
SNDMSG("invalid silent_threshold value %ld (buffer_size = %ld)",
val, pcm->buffer_size);
return -EINVAL;
}
params->silence_threshold = val; params->silence_threshold = val;
return 0; return 0;
} }
@ -5470,7 +5637,11 @@ int snd_pcm_sw_params_set_silence_size(snd_pcm_t *pcm, snd_pcm_sw_params_t *para
#endif #endif
{ {
assert(pcm && params); assert(pcm && params);
assert(val >= pcm->boundary || val <= pcm->buffer_size); if (CHECK_SANITY(val < pcm->boundary && val > pcm->buffer_size)) {
SNDMSG("invalid silence_size %ld (boundary %ld, buffer_size %ld)",
val, pcm->boundary, pcm->buffer_size);
return -EINVAL;
}
params->silence_size = val; params->silence_size = val;
return 0; return 0;
} }
@ -5961,8 +6132,16 @@ snd_pcm_sframes_t snd_pcm_mmap_commit(snd_pcm_t *pcm,
snd_pcm_uframes_t frames) snd_pcm_uframes_t frames)
{ {
assert(pcm); assert(pcm);
assert(offset == *pcm->appl.ptr % pcm->buffer_size); if (CHECK_SANITY(offset != *pcm->appl.ptr % pcm->buffer_size)) {
assert(frames <= snd_pcm_mmap_avail(pcm)); SNDMSG("commit offset (%ld) doesn't match with appl_ptr (%ld) %% buf_size (%ld)",
offset, *pcm->appl.ptr, pcm->buffer_size);
return -EPIPE;
}
if (CHECK_SANITY(frames > snd_pcm_mmap_avail(pcm))) {
SNDMSG("commit frames (%ld) overflow (avail = %ld)", frames,
snd_pcm_mmap_avail(pcm));
return -EPIPE;
}
return pcm->fast_ops->mmap_commit(pcm->fast_op_arg, offset, frames); return pcm->fast_ops->mmap_commit(pcm->fast_op_arg, offset, frames);
} }
@ -6065,7 +6244,8 @@ snd_pcm_sframes_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_
frames = size; frames = size;
if (frames > (snd_pcm_uframes_t) avail) if (frames > (snd_pcm_uframes_t) avail)
frames = avail; frames = avail;
assert(frames != 0); if (! frames)
break;
err = func(pcm, areas, offset, frames); err = func(pcm, areas, offset, frames);
if (err < 0) if (err < 0)
break; break;
@ -6136,7 +6316,8 @@ snd_pcm_sframes_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area
frames = size; frames = size;
if (frames > (snd_pcm_uframes_t) avail) if (frames > (snd_pcm_uframes_t) avail)
frames = avail; frames = avail;
assert(frames != 0); if (! frames)
break;
err = func(pcm, areas, offset, frames); err = func(pcm, areas, offset, frames);
if (err < 0) if (err < 0)
break; break;

View file

@ -113,19 +113,6 @@ typedef struct {
((hw)->mmap_status->tstamp) ((hw)->mmap_status->tstamp)
#endif /* DOC_HIDDEN */ #endif /* DOC_HIDDEN */
static inline int check_std_error(int error)
{
switch (error) {
case -EAGAIN:
case -EPIPE:
case -ESTRPIPE:
case -ENXIO:
case -ENOSYS:
return 0;
}
return 1;
}
struct timespec snd_pcm_hw_fast_tstamp(snd_pcm_t *pcm) struct timespec snd_pcm_hw_fast_tstamp(snd_pcm_t *pcm)
{ {
struct timespec res; struct timespec res;
@ -143,7 +130,7 @@ static int sync_ptr1(snd_pcm_hw_t *hw, unsigned int flags)
err = ioctl((hw)->fd, SNDRV_PCM_IOCTL_SYNC_PTR, (hw)->sync_ptr); err = ioctl((hw)->fd, SNDRV_PCM_IOCTL_SYNC_PTR, (hw)->sync_ptr);
if (err < 0) { if (err < 0) {
err = -errno; err = -errno;
SYSERR("SNDRV_PCM_IOCTL_SYNC_PTR failed"); SYSMSG("SNDRV_PCM_IOCTL_SYNC_PTR failed");
return err; return err;
} }
return 0; return 0;
@ -162,7 +149,7 @@ static int snd_pcm_hw_nonblock(snd_pcm_t *pcm, int nonblock)
if ((flags = fcntl(fd, F_GETFL)) < 0) { if ((flags = fcntl(fd, F_GETFL)) < 0) {
err = -errno; err = -errno;
SYSERR("F_GETFL failed"); SYSMSG("F_GETFL failed");
return err; return err;
} }
if (nonblock) if (nonblock)
@ -171,7 +158,7 @@ static int snd_pcm_hw_nonblock(snd_pcm_t *pcm, int nonblock)
flags &= ~O_NONBLOCK; flags &= ~O_NONBLOCK;
if (fcntl(fd, F_SETFL, flags) < 0) { if (fcntl(fd, F_SETFL, flags) < 0) {
err = -errno; err = -errno;
SYSERR("F_SETFL for O_NONBLOCK failed"); SYSMSG("F_SETFL for O_NONBLOCK failed");
return err; return err;
} }
return 0; return 0;
@ -185,7 +172,7 @@ static int snd_pcm_hw_async(snd_pcm_t *pcm, int sig, pid_t pid)
if ((flags = fcntl(fd, F_GETFL)) < 0) { if ((flags = fcntl(fd, F_GETFL)) < 0) {
err = -errno; err = -errno;
SYSERR("F_GETFL failed"); SYSMSG("F_GETFL failed");
return err; return err;
} }
if (sig >= 0) if (sig >= 0)
@ -194,19 +181,19 @@ static int snd_pcm_hw_async(snd_pcm_t *pcm, int sig, pid_t pid)
flags &= ~O_ASYNC; flags &= ~O_ASYNC;
if (fcntl(fd, F_SETFL, flags) < 0) { if (fcntl(fd, F_SETFL, flags) < 0) {
err = -errno; err = -errno;
SYSERR("F_SETFL for O_ASYNC failed"); SYSMSG("F_SETFL for O_ASYNC failed");
return err; return err;
} }
if (sig < 0) if (sig < 0)
return 0; return 0;
if (fcntl(fd, F_SETSIG, (long)sig) < 0) { if (fcntl(fd, F_SETSIG, (long)sig) < 0) {
err = -errno; err = -errno;
SYSERR("F_SETSIG failed"); SYSMSG("F_SETSIG failed");
return err; return err;
} }
if (fcntl(fd, F_SETOWN, (long)pid) < 0) { if (fcntl(fd, F_SETOWN, (long)pid) < 0) {
err = -errno; err = -errno;
SYSERR("F_SETOWN failed"); SYSMSG("F_SETOWN failed");
return err; return err;
} }
return 0; return 0;
@ -218,7 +205,7 @@ static int snd_pcm_hw_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
int fd = hw->fd, err; int fd = hw->fd, err;
if (ioctl(fd, SNDRV_PCM_IOCTL_INFO, info) < 0) { if (ioctl(fd, SNDRV_PCM_IOCTL_INFO, info) < 0) {
err = -errno; err = -errno;
SYSERR("SNDRV_PCM_IOCTL_INFO failed"); SYSMSG("SNDRV_PCM_IOCTL_INFO failed");
return err; return err;
} }
return 0; return 0;
@ -300,7 +287,7 @@ static int snd_pcm_hw_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
} else { } else {
if (hw_refine_call(hw, params) < 0) { if (hw_refine_call(hw, params) < 0) {
err = -errno; err = -errno;
// SYSERR("SNDRV_PCM_IOCTL_HW_REFINE failed"); // SYSMSG("SNDRV_PCM_IOCTL_HW_REFINE failed");
return err; return err;
} }
} }
@ -353,7 +340,7 @@ static int snd_pcm_hw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
if (hw_params_call(hw, params) < 0) { if (hw_params_call(hw, params) < 0) {
_err: _err:
err = -errno; err = -errno;
SYSERR("SNDRV_PCM_IOCTL_HW_PARAMS failed"); SYSMSG("SNDRV_PCM_IOCTL_HW_PARAMS failed");
return err; return err;
} }
} }
@ -379,7 +366,7 @@ static int snd_pcm_hw_hw_free(snd_pcm_t *pcm)
int fd = hw->fd, err; int fd = hw->fd, err;
if (ioctl(fd, SNDRV_PCM_IOCTL_HW_FREE) < 0) { if (ioctl(fd, SNDRV_PCM_IOCTL_HW_FREE) < 0) {
err = -errno; err = -errno;
SYSERR("SNDRV_PCM_IOCTL_HW_FREE failed"); SYSMSG("SNDRV_PCM_IOCTL_HW_FREE failed");
return err; return err;
} }
return 0; return 0;
@ -402,7 +389,7 @@ static int snd_pcm_hw_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
} }
if (ioctl(fd, SNDRV_PCM_IOCTL_SW_PARAMS, params) < 0) { if (ioctl(fd, SNDRV_PCM_IOCTL_SW_PARAMS, params) < 0) {
err = -errno; err = -errno;
SYSERR("SNDRV_PCM_IOCTL_SW_PARAMS failed"); SYSMSG("SNDRV_PCM_IOCTL_SW_PARAMS failed");
return err; return err;
} }
hw->mmap_control->avail_min = params->avail_min; hw->mmap_control->avail_min = params->avail_min;
@ -417,7 +404,7 @@ static int snd_pcm_hw_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info
i.channel = info->channel; i.channel = info->channel;
if (ioctl(fd, SNDRV_PCM_IOCTL_CHANNEL_INFO, &i) < 0) { if (ioctl(fd, SNDRV_PCM_IOCTL_CHANNEL_INFO, &i) < 0) {
err = -errno; err = -errno;
SYSERR("SNDRV_PCM_IOCTL_CHANNEL_INFO failed"); SYSMSG("SNDRV_PCM_IOCTL_CHANNEL_INFO failed");
return err; return err;
} }
info->channel = i.channel; info->channel = i.channel;
@ -439,7 +426,7 @@ static int snd_pcm_hw_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
int fd = hw->fd, err; int fd = hw->fd, err;
if (ioctl(fd, SNDRV_PCM_IOCTL_STATUS, status) < 0) { if (ioctl(fd, SNDRV_PCM_IOCTL_STATUS, status) < 0) {
err = -errno; err = -errno;
SYSERR("SNDRV_PCM_IOCTL_STATUS failed"); SYSMSG("SNDRV_PCM_IOCTL_STATUS failed");
return err; return err;
} }
if (SNDRV_PROTOCOL_VERSION(2, 0, 5) > hw->version) { if (SNDRV_PROTOCOL_VERSION(2, 0, 5) > hw->version) {
@ -486,8 +473,7 @@ static int snd_pcm_hw_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
} }
if (ioctl(fd, SNDRV_PCM_IOCTL_DELAY, delayp) < 0) { if (ioctl(fd, SNDRV_PCM_IOCTL_DELAY, delayp) < 0) {
err = -errno; err = -errno;
if (check_std_error(err)) SYSMSG("SNDRV_PCM_IOCTL_DELAY failed");
SYSERR("SNDRV_PCM_IOCTL_DELAY failed");
return err; return err;
} }
return 0; return 0;
@ -505,8 +491,7 @@ static int snd_pcm_hw_hwsync(snd_pcm_t *pcm)
} else { } else {
if (ioctl(fd, SNDRV_PCM_IOCTL_HWSYNC) < 0) { if (ioctl(fd, SNDRV_PCM_IOCTL_HWSYNC) < 0) {
err = -errno; err = -errno;
if (check_std_error(err)) SYSMSG("SNDRV_PCM_IOCTL_HWSYNC failed");
SYSERR("SNDRV_PCM_IOCTL_HWSYNC failed");
return err; return err;
} }
} }
@ -532,7 +517,7 @@ static int snd_pcm_hw_prepare(snd_pcm_t *pcm)
int fd = hw->fd, err; int fd = hw->fd, err;
if (ioctl(fd, SNDRV_PCM_IOCTL_PREPARE) < 0) { if (ioctl(fd, SNDRV_PCM_IOCTL_PREPARE) < 0) {
err = -errno; err = -errno;
SYSERR("SNDRV_PCM_IOCTL_PREPARE failed"); SYSMSG("SNDRV_PCM_IOCTL_PREPARE failed");
return err; return err;
} }
return sync_ptr(hw, SNDRV_PCM_SYNC_PTR_APPL); return sync_ptr(hw, SNDRV_PCM_SYNC_PTR_APPL);
@ -544,7 +529,7 @@ static int snd_pcm_hw_reset(snd_pcm_t *pcm)
int fd = hw->fd, err; int fd = hw->fd, err;
if (ioctl(fd, SNDRV_PCM_IOCTL_RESET) < 0) { if (ioctl(fd, SNDRV_PCM_IOCTL_RESET) < 0) {
err = -errno; err = -errno;
SYSERR("SNDRV_PCM_IOCTL_RESET failed"); SYSMSG("SNDRV_PCM_IOCTL_RESET failed");
return err; return err;
} }
return sync_ptr(hw, SNDRV_PCM_SYNC_PTR_APPL); return sync_ptr(hw, SNDRV_PCM_SYNC_PTR_APPL);
@ -560,7 +545,7 @@ static int snd_pcm_hw_start(snd_pcm_t *pcm)
#endif #endif
if (ioctl(hw->fd, SNDRV_PCM_IOCTL_START) < 0) { if (ioctl(hw->fd, SNDRV_PCM_IOCTL_START) < 0) {
err = -errno; err = -errno;
SYSERR("SNDRV_PCM_IOCTL_START failed"); SYSMSG("SNDRV_PCM_IOCTL_START failed");
#if 0 #if 0
if (err == -EBADFD) if (err == -EBADFD)
SNDERR("PCM state = %s", snd_pcm_state_name(snd_pcm_hw_state(pcm))); SNDERR("PCM state = %s", snd_pcm_state_name(snd_pcm_hw_state(pcm)));
@ -576,7 +561,7 @@ static int snd_pcm_hw_drop(snd_pcm_t *pcm)
int err; int err;
if (ioctl(hw->fd, SNDRV_PCM_IOCTL_DROP) < 0) { if (ioctl(hw->fd, SNDRV_PCM_IOCTL_DROP) < 0) {
err = -errno; err = -errno;
SYSERR("SNDRV_PCM_IOCTL_DROP failed"); SYSMSG("SNDRV_PCM_IOCTL_DROP failed");
return err; return err;
} }
return 0; return 0;
@ -588,8 +573,7 @@ static int snd_pcm_hw_drain(snd_pcm_t *pcm)
int err; int err;
if (ioctl(hw->fd, SNDRV_PCM_IOCTL_DRAIN) < 0) { if (ioctl(hw->fd, SNDRV_PCM_IOCTL_DRAIN) < 0) {
err = -errno; err = -errno;
if (check_std_error(err)) SYSMSG("SNDRV_PCM_IOCTL_DRAIN failed");
SYSERR("SNDRV_PCM_IOCTL_DRAIN failed");
return err; return err;
} }
return 0; return 0;
@ -601,8 +585,7 @@ static int snd_pcm_hw_pause(snd_pcm_t *pcm, int enable)
int err; int err;
if (ioctl(hw->fd, SNDRV_PCM_IOCTL_PAUSE, enable) < 0) { if (ioctl(hw->fd, SNDRV_PCM_IOCTL_PAUSE, enable) < 0) {
err = -errno; err = -errno;
if (check_std_error(err)) SYSMSG("SNDRV_PCM_IOCTL_PAUSE failed");
SYSERR("SNDRV_PCM_IOCTL_PAUSE failed");
return err; return err;
} }
return 0; return 0;
@ -614,8 +597,7 @@ static snd_pcm_sframes_t snd_pcm_hw_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t fra
int err; int err;
if (ioctl(hw->fd, SNDRV_PCM_IOCTL_REWIND, &frames) < 0) { if (ioctl(hw->fd, SNDRV_PCM_IOCTL_REWIND, &frames) < 0) {
err = -errno; err = -errno;
if (check_std_error(err)) SYSMSG("SNDRV_PCM_IOCTL_REWIND failed");
SYSERR("SNDRV_PCM_IOCTL_REWIND failed");
return err; return err;
} }
return frames; return frames;
@ -628,8 +610,7 @@ static snd_pcm_sframes_t snd_pcm_hw_forward(snd_pcm_t *pcm, snd_pcm_uframes_t fr
if (SNDRV_PROTOCOL_VERSION(2, 0, 4) <= hw->version) { if (SNDRV_PROTOCOL_VERSION(2, 0, 4) <= hw->version) {
if (ioctl(hw->fd, SNDRV_PCM_IOCTL_FORWARD, &frames) < 0) { if (ioctl(hw->fd, SNDRV_PCM_IOCTL_FORWARD, &frames) < 0) {
err = -errno; err = -errno;
if (check_std_error(err)) SYSMSG("SNDRV_PCM_IOCTL_FORWARD failed");
SYSERR("SNDRV_PCM_IOCTL_FORWARD failed");
return err; return err;
} }
return frames; return frames;
@ -669,8 +650,7 @@ static int snd_pcm_hw_resume(snd_pcm_t *pcm)
int fd = hw->fd, err; int fd = hw->fd, err;
if (ioctl(fd, SNDRV_PCM_IOCTL_RESUME) < 0) { if (ioctl(fd, SNDRV_PCM_IOCTL_RESUME) < 0) {
err = -errno; err = -errno;
if (check_std_error(err)) SYSMSG("SNDRV_PCM_IOCTL_RESUME failed");
SYSERR("SNDRV_PCM_IOCTL_RESUME failed");
return err; return err;
} }
return 0; return 0;
@ -768,7 +748,7 @@ static int snd_pcm_hw_mmap_status(snd_pcm_t *pcm)
err = ioctl(hw->fd, SNDRV_PCM_IOCTL_SYNC_PTR, &sync_ptr); err = ioctl(hw->fd, SNDRV_PCM_IOCTL_SYNC_PTR, &sync_ptr);
if (err < 0) { if (err < 0) {
err = -errno; err = -errno;
SYSERR("SNDRV_PCM_IOCTL_SYNC_PTR failed"); SYSMSG("SNDRV_PCM_IOCTL_SYNC_PTR failed");
return err; return err;
} }
hw->sync_ptr = calloc(1, sizeof(struct sndrv_pcm_sync_ptr)); hw->sync_ptr = calloc(1, sizeof(struct sndrv_pcm_sync_ptr));
@ -795,7 +775,7 @@ static int snd_pcm_hw_mmap_control(snd_pcm_t *pcm)
hw->fd, SNDRV_PCM_MMAP_OFFSET_CONTROL); hw->fd, SNDRV_PCM_MMAP_OFFSET_CONTROL);
if (ptr == MAP_FAILED || ptr == NULL) { if (ptr == MAP_FAILED || ptr == NULL) {
err = -errno; err = -errno;
SYSERR("control mmap failed"); SYSMSG("control mmap failed");
return err; return err;
} }
hw->mmap_control = ptr; hw->mmap_control = ptr;
@ -818,7 +798,7 @@ static int snd_pcm_hw_munmap_status(snd_pcm_t *pcm)
} else { } else {
if (munmap((void*)hw->mmap_status, page_align(sizeof(*hw->mmap_status))) < 0) { if (munmap((void*)hw->mmap_status, page_align(sizeof(*hw->mmap_status))) < 0) {
err = -errno; err = -errno;
SYSERR("status munmap failed"); SYSMSG("status munmap failed");
return err; return err;
} }
} }
@ -837,7 +817,7 @@ static int snd_pcm_hw_munmap_control(snd_pcm_t *pcm)
} else { } else {
if (munmap(hw->mmap_control, page_align(sizeof(*hw->mmap_control))) < 0) { if (munmap(hw->mmap_control, page_align(sizeof(*hw->mmap_control))) < 0) {
err = -errno; err = -errno;
SYSERR("control munmap failed"); SYSMSG("control munmap failed");
return err; return err;
} }
} }
@ -860,7 +840,7 @@ static int snd_pcm_hw_close(snd_pcm_t *pcm)
int err; int err;
if (close(hw->fd)) { if (close(hw->fd)) {
err = -errno; err = -errno;
SYSERR("close failed\n"); SYSMSG("close failed\n");
return err; return err;
} }
snd_pcm_hw_munmap_status(pcm); snd_pcm_hw_munmap_status(pcm);
@ -888,7 +868,6 @@ static snd_pcm_sframes_t snd_pcm_hw_mmap_commit(snd_pcm_t *pcm,
} while (size > 0); } while (size > 0);
return result; return result;
} else { } else {
snd_pcm_hw_t *hw = pcm->private_data;
assert(hw->shadow_appl_ptr); assert(hw->shadow_appl_ptr);
} }
} }
@ -917,7 +896,8 @@ static snd_pcm_sframes_t snd_pcm_hw_avail_update(snd_pcm_t *pcm)
hw->avail_update_flag = 0; hw->avail_update_flag = 0;
if (err < 0) if (err < 0)
return err; return err;
assert((snd_pcm_uframes_t)err == avail); if ((snd_pcm_uframes_t)err != avail)
SNDMSG("short read %ld for avail %ld", err, avail);
return err; return err;
} }
} }
@ -946,7 +926,10 @@ static void snd_pcm_hw_dump(snd_pcm_t *pcm, snd_output_t *out)
snd_pcm_hw_t *hw = pcm->private_data; snd_pcm_hw_t *hw = pcm->private_data;
char *name; char *name;
int err = snd_card_get_name(hw->card, &name); int err = snd_card_get_name(hw->card, &name);
assert(err >= 0); if (err < 0) {
SNDERR("cannot get card name");
return;
}
snd_output_printf(out, "Hardware PCM card %d '%s' device %d subdevice %d\n", snd_output_printf(out, "Hardware PCM card %d '%s' device %d subdevice %d\n",
hw->card, name, hw->device, hw->subdevice); hw->card, name, hw->device, hw->subdevice);
free(name); free(name);
@ -1021,7 +1004,7 @@ int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, const char *name,
memset(&info, 0, sizeof(info)); memset(&info, 0, sizeof(info));
if (ioctl(fd, SNDRV_PCM_IOCTL_INFO, &info) < 0) { if (ioctl(fd, SNDRV_PCM_IOCTL_INFO, &info) < 0) {
ret = -errno; ret = -errno;
SYSERR("SNDRV_PCM_IOCTL_INFO failed"); SYSMSG("SNDRV_PCM_IOCTL_INFO failed");
close(fd); close(fd);
return ret; return ret;
@ -1044,7 +1027,7 @@ int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, const char *name,
*/ */
if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) { if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) {
ret = -errno; ret = -errno;
SYSERR("fcntl FD_CLOEXEC failed"); SYSMSG("fcntl FD_CLOEXEC failed");
close(fd); close(fd);
return ret; return ret;
} }
@ -1052,7 +1035,7 @@ int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, const char *name,
if (ioctl(fd, SNDRV_PCM_IOCTL_PVERSION, &ver) < 0) { if (ioctl(fd, SNDRV_PCM_IOCTL_PVERSION, &ver) < 0) {
ret = -errno; ret = -errno;
SYSERR("SNDRV_PCM_IOCTL_PVERSION failed"); SYSMSG("SNDRV_PCM_IOCTL_PVERSION failed");
close(fd); close(fd);
return ret; return ret;
} }
@ -1063,7 +1046,7 @@ int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, const char *name,
int on = 1; int on = 1;
if (ioctl(fd, SNDRV_PCM_IOCTL_TSTAMP, &on) < 0) { if (ioctl(fd, SNDRV_PCM_IOCTL_TSTAMP, &on) < 0) {
ret = -errno; ret = -errno;
SNDERR("TSTAMP failed\n"); SNDMSG("TSTAMP failed\n");
return ret; return ret;
} }
} }
@ -1152,7 +1135,8 @@ int snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name,
filefmt = SNDRV_FILE_PCM_STREAM_CAPTURE; filefmt = SNDRV_FILE_PCM_STREAM_CAPTURE;
break; break;
default: default:
assert(0); SNDERR("invalid stream %d", stream);
return -EINVAL;
} }
sprintf(filename, filefmt, card, device); sprintf(filename, filefmt, card, device);
@ -1171,14 +1155,14 @@ int snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name,
fmode |= O_ASYNC; fmode |= O_ASYNC;
if ((fd = open(filename, fmode)) < 0) { if ((fd = open(filename, fmode)) < 0) {
ret = -errno; ret = -errno;
SYSERR("open %s failed", filename); SYSMSG("open %s failed", filename);
goto _err; goto _err;
} }
if (subdevice >= 0) { if (subdevice >= 0) {
memset(&info, 0, sizeof(info)); memset(&info, 0, sizeof(info));
if (ioctl(fd, SNDRV_PCM_IOCTL_INFO, &info) < 0) { if (ioctl(fd, SNDRV_PCM_IOCTL_INFO, &info) < 0) {
ret = -errno; ret = -errno;
SYSERR("SNDRV_PCM_IOCTL_INFO failed"); SYSMSG("SNDRV_PCM_IOCTL_INFO failed");
goto _err; goto _err;
} }
if (info.subdevice != (unsigned int) subdevice) { if (info.subdevice != (unsigned int) subdevice) {

View file

@ -105,7 +105,10 @@ static snd_pcm_sframes_t snd_pcm_mmap_write_areas(snd_pcm_t *pcm,
{ {
snd_pcm_uframes_t xfer = 0; snd_pcm_uframes_t xfer = 0;
assert(snd_pcm_mmap_playback_avail(pcm) >= size); if (snd_pcm_mmap_playback_avail(pcm) < size) {
SNDMSG("too short avail %ld to size %ld", snd_pcm_mmap_playback_avail(pcm), size);
return -EPIPE;
}
while (size > 0) { while (size > 0) {
const snd_pcm_channel_area_t *pcm_areas; const snd_pcm_channel_area_t *pcm_areas;
snd_pcm_uframes_t pcm_offset; snd_pcm_uframes_t pcm_offset;
@ -134,7 +137,10 @@ static snd_pcm_sframes_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm,
{ {
snd_pcm_uframes_t xfer = 0; snd_pcm_uframes_t xfer = 0;
assert(snd_pcm_mmap_capture_avail(pcm) >= size); if (snd_pcm_mmap_capture_avail(pcm) < size) {
SNDMSG("too short avail %ld to size %ld", snd_pcm_mmap_capture_avail(pcm), size);
return -EPIPE;
}
while (size > 0) { while (size > 0) {
const snd_pcm_channel_area_t *pcm_areas; const snd_pcm_channel_area_t *pcm_areas;
snd_pcm_uframes_t pcm_offset; snd_pcm_uframes_t pcm_offset;
@ -275,8 +281,8 @@ int snd_pcm_channel_info_shm(snd_pcm_t *pcm, snd_pcm_channel_info_t *info, int s
info->step = pcm->sample_bits; info->step = pcm->sample_bits;
break; break;
default: default:
assert(0); SNDMSG("invalid access type %d", pcm->access);
break; return -EINVAL;
} }
info->addr = 0; info->addr = 0;
info->type = SND_PCM_AREA_SHM; info->type = SND_PCM_AREA_SHM;
@ -290,8 +296,14 @@ int snd_pcm_mmap(snd_pcm_t *pcm)
int err; int err;
unsigned int c; unsigned int c;
assert(pcm); assert(pcm);
assert(pcm->setup); if (CHECK_SANITY(! pcm->setup)) {
assert(!pcm->mmap_channels); SNDMSG("PCM not set up");
return -EIO;
}
if (CHECK_SANITY(pcm->mmap_channels || pcm->running_areas)) {
SNDMSG("Already mmapped");
return -EBUSY;
}
err = pcm->ops->mmap(pcm); err = pcm->ops->mmap(pcm);
if (err < 0) if (err < 0)
return err; return err;
@ -300,7 +312,6 @@ int snd_pcm_mmap(snd_pcm_t *pcm)
pcm->mmap_channels = calloc(pcm->channels, sizeof(pcm->mmap_channels[0])); pcm->mmap_channels = calloc(pcm->channels, sizeof(pcm->mmap_channels[0]));
if (!pcm->mmap_channels) if (!pcm->mmap_channels)
return -ENOMEM; return -ENOMEM;
assert(!pcm->running_areas);
pcm->running_areas = calloc(pcm->channels, sizeof(pcm->running_areas[0])); pcm->running_areas = calloc(pcm->channels, sizeof(pcm->running_areas[0]));
if (!pcm->running_areas) { if (!pcm->running_areas) {
free(pcm->mmap_channels); free(pcm->mmap_channels);
@ -433,7 +444,10 @@ int snd_pcm_munmap(snd_pcm_t *pcm)
int err; int err;
unsigned int c; unsigned int c;
assert(pcm); assert(pcm);
assert(pcm->mmap_channels); if (CHECK_SANITY(! pcm->mmap_channels)) {
SNDMSG("Not mmapped");
return -ENXIO;
}
if (pcm->mmap_shadow) if (pcm->mmap_shadow)
return pcm->ops->munmap(pcm); return pcm->ops->munmap(pcm);
for (c = 0; c < pcm->channels; ++c) { for (c = 0; c < pcm->channels; ++c) {
@ -499,7 +513,8 @@ snd_pcm_sframes_t snd_pcm_write_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t size)
{ {
snd_pcm_uframes_t xfer = 0; snd_pcm_uframes_t xfer = 0;
snd_pcm_sframes_t err = 0; snd_pcm_sframes_t err = 0;
assert(size > 0); if (! size)
return 0;
while (xfer < size) { while (xfer < size) {
snd_pcm_uframes_t frames = size - xfer; snd_pcm_uframes_t frames = size - xfer;
snd_pcm_uframes_t offset = snd_pcm_mmap_hw_offset(pcm); snd_pcm_uframes_t offset = snd_pcm_mmap_hw_offset(pcm);
@ -532,9 +547,8 @@ snd_pcm_sframes_t snd_pcm_write_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t size)
break; break;
} }
default: default:
assert(0); SNDMSG("invalid access type %d", pcm->access);
err = -EINVAL; return -EINVAL;
break;
} }
if (err < 0) if (err < 0)
break; break;
@ -549,7 +563,8 @@ snd_pcm_sframes_t snd_pcm_read_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t size)
{ {
snd_pcm_uframes_t xfer = 0; snd_pcm_uframes_t xfer = 0;
snd_pcm_sframes_t err = 0; snd_pcm_sframes_t err = 0;
assert(size > 0); if (! size)
return 0;
while (xfer < size) { while (xfer < size) {
snd_pcm_uframes_t frames = size - xfer; snd_pcm_uframes_t frames = size - xfer;
snd_pcm_uframes_t offset = snd_pcm_mmap_hw_offset(pcm); snd_pcm_uframes_t offset = snd_pcm_mmap_hw_offset(pcm);
@ -581,9 +596,8 @@ snd_pcm_sframes_t snd_pcm_read_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t size)
frames = err; frames = err;
} }
default: default:
assert(0); SNDMSG("invalid access type %d", pcm->access);
err = -EINVAL; return -EINVAL;
break;
} }
if (err < 0) if (err < 0)
break; break;

View file

@ -373,7 +373,11 @@ static snd_pcm_sframes_t snd_pcm_plugin_write_areas(snd_pcm_t *pcm,
break; break;
frames = plugin->write(pcm, areas, offset, frames, frames = plugin->write(pcm, areas, offset, frames,
slave_areas, slave_offset, &slave_frames); slave_areas, slave_offset, &slave_frames);
assert(slave_frames <= snd_pcm_mmap_playback_avail(slave)); if (CHECK_SANITY(slave_frames > snd_pcm_mmap_playback_avail(slave))) {
SNDMSG("write overflow %ld > %ld", slave_frames,
snd_pcm_mmap_playback_avail(slave));
return -EPIPE;
}
snd_atomic_write_begin(&plugin->watom); snd_atomic_write_begin(&plugin->watom);
snd_pcm_mmap_appl_forward(pcm, frames); snd_pcm_mmap_appl_forward(pcm, frames);
result = snd_pcm_mmap_commit(slave, slave_offset, slave_frames); result = snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
@ -415,7 +419,11 @@ static snd_pcm_sframes_t snd_pcm_plugin_read_areas(snd_pcm_t *pcm,
break; break;
frames = plugin->read(pcm, areas, offset, frames, frames = plugin->read(pcm, areas, offset, frames,
slave_areas, slave_offset, &slave_frames); slave_areas, slave_offset, &slave_frames);
assert(slave_frames <= snd_pcm_mmap_capture_avail(slave)); if (CHECK_SANITY(slave_frames > snd_pcm_mmap_capture_avail(slave))) {
SNDMSG("read overflow %ld > %ld", slave_frames,
snd_pcm_mmap_playback_avail(slave));
return -EPIPE;
}
snd_atomic_write_begin(&plugin->watom); snd_atomic_write_begin(&plugin->watom);
snd_pcm_mmap_appl_forward(pcm, frames); snd_pcm_mmap_appl_forward(pcm, frames);
result = snd_pcm_mmap_commit(slave, slave_offset, slave_frames); result = snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
@ -531,7 +539,10 @@ snd_pcm_sframes_t snd_pcm_plugin_mmap_commit(snd_pcm_t *pcm,
slave_size -= frames; slave_size -= frames;
xfer += frames; xfer += frames;
} }
assert(size == 0); if (CHECK_SANITY(size)) {
SNDMSG("short commit: %ld", size);
return -EPIPE;
}
return xfer; return xfer;
} }

View file

@ -166,7 +166,10 @@ static void snd_pcm_rate_expand(const snd_pcm_channel_area_t *dst_areas,
src_frames1++; src_frames1++;
states->u.linear.init = 2; /* get a new sample */ states->u.linear.init = 2; /* get a new sample */
//printf("new_src_pos = %i\n", (src - (char *)snd_pcm_channel_area_addr(src_area, src_offset)) / src_step); //printf("new_src_pos = %i\n", (src - (char *)snd_pcm_channel_area_addr(src_area, src_offset)) / src_step);
assert(src_frames1 <= src_frames); if (CHECK_SANITY(src_frames1 > src_frames)) {
SNDERR("src_frames overflow");
break;
}
} }
} }
if (dst_frames != dst_frames1) { if (dst_frames != dst_frames1) {
@ -243,7 +246,10 @@ static void snd_pcm_rate_shrink(const snd_pcm_channel_area_t *dst_areas,
after_put: after_put:
dst += dst_step; dst += dst_step;
dst_frames1++; dst_frames1++;
assert(dst_frames1 <= dst_frames); if (CHECK_SANITY(dst_frames1 > dst_frames)) {
SNDERR("dst_frames overflow");
break;
}
} }
old_sample = new_sample; old_sample = new_sample;
} }
@ -501,8 +507,10 @@ static int snd_pcm_rate_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
/* pitch is get_increment */ /* pitch is get_increment */
} }
rate->pitch = (((u_int64_t)dst_rate * LINEAR_DIV) + (src_rate / 2)) / src_rate; rate->pitch = (((u_int64_t)dst_rate * LINEAR_DIV) + (src_rate / 2)) / src_rate;
assert(!rate->states); if (CHECK_SANITY(rate->states || rate->pareas)) {
assert(!rate->pareas); SNDMSG("rate plugin already in use");
return -EBUSY;
}
rate->states = malloc(channels * sizeof(*rate->states)); rate->states = malloc(channels * sizeof(*rate->states));
if (rate->states == NULL) if (rate->states == NULL)
return -ENOMEM; return -ENOMEM;
@ -616,7 +624,11 @@ static int snd_pcm_rate_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
} }
} }
} while (1); } while (1);
assert((snd_pcm_uframes_t)snd_pcm_rate_client_frames(pcm, slave->period_size ) == pcm->period_size ); if ((snd_pcm_uframes_t)snd_pcm_rate_client_frames(pcm, slave->period_size ) != pcm->period_size) {
SNDERR("invalid slave period_size %ld for pcm period_size %ld",
slave->period_size, pcm->period_size);
return -EIO;
}
} else { } else {
rate->pitch = (((u_int64_t)pcm->period_size * LINEAR_DIV) + (slave->period_size/2) ) / slave->period_size; rate->pitch = (((u_int64_t)pcm->period_size * LINEAR_DIV) + (slave->period_size/2) ) / slave->period_size;
do { do {
@ -639,7 +651,11 @@ static int snd_pcm_rate_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
} }
} }
} while (1); } while (1);
assert((snd_pcm_uframes_t)snd_pcm_rate_slave_frames(pcm, pcm->period_size ) == slave->period_size ); if ((snd_pcm_uframes_t)snd_pcm_rate_slave_frames(pcm, pcm->period_size ) != slave->period_size) {
SNDERR("invalid pcm period_size %ld for slave period_size",
pcm->period_size, slave->period_size);
return -EIO;
}
} }
recalc(pcm, &sparams->avail_min); recalc(pcm, &sparams->avail_min);
rate->orig_avail_min = sparams->avail_min; rate->orig_avail_min = sparams->avail_min;
@ -1044,7 +1060,10 @@ static int snd_pcm_rate_commit_next_period(snd_pcm_t *pcm, snd_pcm_uframes_t app
result = snd_pcm_mmap_begin(rate->slave, &slave_areas, &slave_offset, &slave_frames); result = snd_pcm_mmap_begin(rate->slave, &slave_areas, &slave_offset, &slave_frames);
if (result < 0) if (result < 0)
return result; return result;
assert(slave_offset == 0); if (slave_offset) {
SNDERR("non-zero slave_offset %ld", slave_offset);
return -EIO;
}
snd_pcm_areas_copy(slave_areas, slave_offset, snd_pcm_areas_copy(slave_areas, slave_offset,
rate->sareas, xfer, rate->sareas, xfer,
pcm->channels, cont, pcm->channels, cont,
@ -1124,7 +1143,10 @@ static int snd_pcm_rate_grab_next_period(snd_pcm_t *pcm, snd_pcm_uframes_t hw_of
result = snd_pcm_mmap_begin(rate->slave, &slave_areas, &slave_offset, &slave_frames); result = snd_pcm_mmap_begin(rate->slave, &slave_areas, &slave_offset, &slave_frames);
if (result < 0) if (result < 0)
return result; return result;
assert(slave_offset == 0); if (slave_offset) {
SNDERR("non-zero slave_offset %ld", slave_offset);
return -EIO;
}
snd_pcm_areas_copy(rate->sareas, xfer, snd_pcm_areas_copy(rate->sareas, xfer,
slave_areas, slave_offset, slave_areas, slave_offset,
pcm->channels, cont, pcm->channels, cont,

View file

@ -238,8 +238,13 @@ static snd_pcm_uframes_t _snd_pcm_share_missing(snd_pcm_t *pcm)
missing = 1; missing = 1;
} }
err = snd_pcm_mmap_commit(spcm, snd_pcm_mmap_offset(spcm), frames); err = snd_pcm_mmap_commit(spcm, snd_pcm_mmap_offset(spcm), frames);
assert(err == frames); if (err < 0) {
slave_avail -= frames; SYSMSG("snd_pcm_mmap_commit error");
return INT_MAX;
}
if (err != frames)
SYSMSG("commit returns %ld for size %ld", err, frames);
slave_avail -= err;
} else { } else {
if (safety_missing == 0) if (safety_missing == 0)
missing = 1; missing = 1;
@ -278,8 +283,8 @@ static snd_pcm_uframes_t _snd_pcm_share_missing(snd_pcm_t *pcm)
running = 1; running = 1;
break; break;
default: default:
assert(0); SNDERR("invalid shared PCM state %d", share->state);
break; return INT_MAX;
} }
update_poll: update_poll:
@ -357,10 +362,16 @@ static void *snd_pcm_share_thread(void *data)
pfd[0].fd = slave->poll[0]; pfd[0].fd = slave->poll[0];
pfd[0].events = POLLIN; pfd[0].events = POLLIN;
err = snd_pcm_poll_descriptors(spcm, &pfd[1], 1); err = snd_pcm_poll_descriptors(spcm, &pfd[1], 1);
assert(err == 1); if (err != 1) {
SNDERR("invalid poll descriptors %d", err);
return NULL;
}
Pthread_mutex_lock(&slave->mutex); Pthread_mutex_lock(&slave->mutex);
err = pipe(slave->poll); err = pipe(slave->poll);
assert(err >= 0); if (err < 0) {
SYSERR("can't create a pipe");
return NULL;
}
while (slave->open_count > 0) { while (slave->open_count > 0) {
snd_pcm_uframes_t missing; snd_pcm_uframes_t missing;
// printf("begin min_missing\n"); // printf("begin min_missing\n");
@ -383,7 +394,10 @@ static void *snd_pcm_share_thread(void *data)
if ((snd_pcm_uframes_t)avail_min != spcm->avail_min) { if ((snd_pcm_uframes_t)avail_min != spcm->avail_min) {
snd_pcm_sw_params_set_avail_min(spcm, &slave->sw_params, avail_min); snd_pcm_sw_params_set_avail_min(spcm, &slave->sw_params, avail_min);
err = snd_pcm_sw_params(spcm, &slave->sw_params); err = snd_pcm_sw_params(spcm, &slave->sw_params);
assert(err >= 0); if (err < 0) {
SYSERR("snd_pcm_sw_params error");
return NULL;
}
} }
slave->polling = 1; slave->polling = 1;
Pthread_mutex_unlock(&slave->mutex); Pthread_mutex_unlock(&slave->mutex);
@ -433,7 +447,10 @@ static void _snd_pcm_share_update(snd_pcm_t *pcm)
int err; int err;
snd_pcm_sw_params_set_avail_min(spcm, &slave->sw_params, avail_min); snd_pcm_sw_params_set_avail_min(spcm, &slave->sw_params, avail_min);
err = snd_pcm_sw_params(spcm, &slave->sw_params); err = snd_pcm_sw_params(spcm, &slave->sw_params);
assert(err >= 0); if (err < 0) {
SYSERR("snd_pcm_sw_params error");
return;
}
} }
} }
} }
@ -818,7 +835,14 @@ static snd_pcm_sframes_t _snd_pcm_share_mmap_commit(snd_pcm_t *pcm,
if (frames > 0) { if (frames > 0) {
snd_pcm_sframes_t err; snd_pcm_sframes_t err;
err = snd_pcm_mmap_commit(spcm, snd_pcm_mmap_offset(spcm), frames); err = snd_pcm_mmap_commit(spcm, snd_pcm_mmap_offset(spcm), frames);
assert(err == frames); if (err < 0) {
SYSMSG("snd_pcm_mmap_commit error");
return err;
}
if (err != frames) {
SYSMSG("commit returns %ld for size %ld", err, frames);
return err;
}
} }
_snd_pcm_share_update(pcm); _snd_pcm_share_update(pcm);
} }