Added snd_*_poll_descriptors_revents functions.

This commit is contained in:
Jaroslav Kysela 2001-11-30 17:36:45 +00:00
parent 23ab0b3509
commit ddb7209e9a
15 changed files with 195 additions and 36 deletions

View file

@ -201,6 +201,7 @@ int snd_async_add_ctl_handler(snd_async_handler_t **handler, snd_ctl_t *ctl,
snd_ctl_t *snd_async_handler_get_ctl(snd_async_handler_t *handler); snd_ctl_t *snd_async_handler_get_ctl(snd_async_handler_t *handler);
int snd_ctl_poll_descriptors_count(snd_ctl_t *ctl); int snd_ctl_poll_descriptors_count(snd_ctl_t *ctl);
int snd_ctl_poll_descriptors(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int space); int snd_ctl_poll_descriptors(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int space);
int snd_ctl_poll_descriptors_revents(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
int snd_ctl_subscribe_events(snd_ctl_t *ctl, int subscribe); int snd_ctl_subscribe_events(snd_ctl_t *ctl, int subscribe);
int snd_ctl_card_info(snd_ctl_t *ctl, snd_ctl_card_info_t *info); int snd_ctl_card_info(snd_ctl_t *ctl, snd_ctl_card_info_t *info);
int snd_ctl_elem_list(snd_ctl_t *ctl, snd_ctl_elem_list_t * list); int snd_ctl_elem_list(snd_ctl_t *ctl, snd_ctl_elem_list_t * list);

View file

@ -81,6 +81,7 @@ typedef struct _snd_hwdep snd_hwdep_t;
int snd_hwdep_open(snd_hwdep_t **hwdep, const char *name, int mode); int snd_hwdep_open(snd_hwdep_t **hwdep, const char *name, int mode);
int snd_hwdep_close(snd_hwdep_t *hwdep); int snd_hwdep_close(snd_hwdep_t *hwdep);
int snd_hwdep_poll_descriptors(snd_hwdep_t *hwdep, struct pollfd *pfds, unsigned int space); int snd_hwdep_poll_descriptors(snd_hwdep_t *hwdep, struct pollfd *pfds, unsigned int space);
int snd_hwdep_poll_descriptors_revents(snd_hwdep_t *hwdep, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
int snd_hwdep_nonblock(snd_hwdep_t *hwdep, int nonblock); int snd_hwdep_nonblock(snd_hwdep_t *hwdep, int nonblock);
int snd_hwdep_info(snd_hwdep_t *hwdep, snd_hwdep_info_t * info); int snd_hwdep_info(snd_hwdep_t *hwdep, snd_hwdep_info_t * info);
int snd_hwdep_ioctl(snd_hwdep_t *hwdep, unsigned int request, void * arg); int snd_hwdep_ioctl(snd_hwdep_t *hwdep, unsigned int request, void * arg);

View file

@ -90,6 +90,7 @@ int snd_mixer_attach(snd_mixer_t *mixer, const char *name);
int snd_mixer_detach(snd_mixer_t *mixer, const char *name); int snd_mixer_detach(snd_mixer_t *mixer, const char *name);
int snd_mixer_poll_descriptors_count(snd_mixer_t *mixer); int snd_mixer_poll_descriptors_count(snd_mixer_t *mixer);
int snd_mixer_poll_descriptors(snd_mixer_t *mixer, struct pollfd *pfds, unsigned int space); int snd_mixer_poll_descriptors(snd_mixer_t *mixer, struct pollfd *pfds, unsigned int space);
int snd_mixer_poll_descriptors_revents(snd_mixer_t *mixer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
int snd_mixer_load(snd_mixer_t *mixer); int snd_mixer_load(snd_mixer_t *mixer);
void snd_mixer_free(snd_mixer_t *mixer); void snd_mixer_free(snd_mixer_t *mixer);
int snd_mixer_wait(snd_mixer_t *mixer, int timeout); int snd_mixer_wait(snd_mixer_t *mixer, int timeout);

View file

@ -362,6 +362,7 @@ snd_pcm_type_t snd_pcm_type(snd_pcm_t *pcm);
snd_pcm_stream_t snd_pcm_stream(snd_pcm_t *pcm); snd_pcm_stream_t snd_pcm_stream(snd_pcm_t *pcm);
int snd_pcm_poll_descriptors_count(snd_pcm_t *pcm); int snd_pcm_poll_descriptors_count(snd_pcm_t *pcm);
int snd_pcm_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space); int snd_pcm_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space);
int snd_pcm_poll_descriptors_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
int snd_pcm_nonblock(snd_pcm_t *pcm, int nonblock); int snd_pcm_nonblock(snd_pcm_t *pcm, int nonblock);
int snd_async_add_pcm_handler(snd_async_handler_t **handler, snd_pcm_t *pcm, int snd_async_add_pcm_handler(snd_async_handler_t **handler, snd_pcm_t *pcm,
snd_async_callback_t callback, void *private_data); snd_async_callback_t callback, void *private_data);
@ -710,7 +711,7 @@ void snd_pcm_subformat_mask_copy(snd_pcm_subformat_mask_t *dst, const snd_pcm_su
void snd_pcm_subformat_mask_none(snd_pcm_subformat_mask_t *mask); void snd_pcm_subformat_mask_none(snd_pcm_subformat_mask_t *mask);
void snd_pcm_subformat_mask_any(snd_pcm_subformat_mask_t *mask); void snd_pcm_subformat_mask_any(snd_pcm_subformat_mask_t *mask);
int snd_pcm_subformat_mask_test(const snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val); int snd_pcm_subformat_mask_test(const snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val);
int snd_pcm_subformat_mask_empty(const snd_pcm_format_mask_t *mask); int snd_pcm_subformat_mask_empty(const snd_pcm_subformat_mask_t *mask);
void snd_pcm_subformat_mask_set(snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val); void snd_pcm_subformat_mask_set(snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val);
void snd_pcm_subformat_mask_reset(snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val); void snd_pcm_subformat_mask_reset(snd_pcm_subformat_mask_t *mask, snd_pcm_subformat_t val);

View file

@ -84,6 +84,7 @@ int snd_rawmidi_open_lconf(snd_rawmidi_t **in_rmidi, snd_rawmidi_t **out_rmidi,
int snd_rawmidi_close(snd_rawmidi_t *rmidi); int snd_rawmidi_close(snd_rawmidi_t *rmidi);
int snd_rawmidi_poll_descriptors_count(snd_rawmidi_t *rmidi); int snd_rawmidi_poll_descriptors_count(snd_rawmidi_t *rmidi);
int snd_rawmidi_poll_descriptors(snd_rawmidi_t *rmidi, struct pollfd *pfds, unsigned int space); int snd_rawmidi_poll_descriptors(snd_rawmidi_t *rmidi, struct pollfd *pfds, unsigned int space);
int snd_rawmidi_poll_descriptors_revents(snd_rawmidi_t *rawmidi, struct pollfd *pfds, unsigned int nfds, unsigned short *revent);
int snd_rawmidi_nonblock(snd_rawmidi_t *rmidi, int nonblock); int snd_rawmidi_nonblock(snd_rawmidi_t *rmidi, int nonblock);
size_t snd_rawmidi_info_sizeof(void); size_t snd_rawmidi_info_sizeof(void);
/** \hideinitializer /** \hideinitializer

View file

@ -90,6 +90,7 @@ snd_seq_type_t snd_seq_type(snd_seq_t *seq);
int snd_seq_close(snd_seq_t *handle); int snd_seq_close(snd_seq_t *handle);
int snd_seq_poll_descriptors_count(snd_seq_t *handle, short events); int snd_seq_poll_descriptors_count(snd_seq_t *handle, short events);
int snd_seq_poll_descriptors(snd_seq_t *handle, struct pollfd *pfds, unsigned int space, short events); int snd_seq_poll_descriptors(snd_seq_t *handle, struct pollfd *pfds, unsigned int space, short events);
int snd_seq_poll_descriptors_revents(snd_seq_t *seq, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
int snd_seq_nonblock(snd_seq_t *handle, int nonblock); int snd_seq_nonblock(snd_seq_t *handle, int nonblock);
int snd_seq_client_id(snd_seq_t *handle); int snd_seq_client_id(snd_seq_t *handle);

View file

@ -110,6 +110,7 @@ int snd_timer_open_lconf(snd_timer_t **handle, const char *name, int mode, snd_c
int snd_timer_close(snd_timer_t *handle); int snd_timer_close(snd_timer_t *handle);
int snd_timer_poll_descriptors_count(snd_timer_t *handle); int snd_timer_poll_descriptors_count(snd_timer_t *handle);
int snd_timer_poll_descriptors(snd_timer_t *handle, struct pollfd *pfds, unsigned int space); int snd_timer_poll_descriptors(snd_timer_t *handle, struct pollfd *pfds, unsigned int space);
int snd_timer_poll_descriptors_revents(snd_timer_t *timer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
int snd_timer_info(snd_timer_t *handle, snd_timer_info_t *timer); int snd_timer_info(snd_timer_t *handle, snd_timer_info_t *timer);
int snd_timer_params(snd_timer_t *handle, snd_timer_params_t *params); int snd_timer_params(snd_timer_t *handle, snd_timer_params_t *params);
int snd_timer_status(snd_timer_t *handle, snd_timer_status_t *status); int snd_timer_status(snd_timer_t *handle, snd_timer_status_t *status);

View file

@ -160,15 +160,33 @@ int snd_ctl_poll_descriptors_count(snd_ctl_t *ctl)
*/ */
int snd_ctl_poll_descriptors(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int space) int snd_ctl_poll_descriptors(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int space)
{ {
assert(ctl); assert(ctl && pfds);
if (space > 0) { if (space > 0) {
pfds->fd = ctl->poll_fd; pfds->fd = ctl->poll_fd;
pfds->events = POLLIN; pfds->events = POLLIN|POLLERR;
return 1; return 1;
} }
return 0; return 0;
} }
/**
* \brief get returned events from poll descriptors
* \param ctl CTL handle
* \param pfds array of poll descriptors
* \param nfds count of poll descriptors
* \param revents returned events
* \return zero if success, otherwise a negative error code
*/
int snd_ctl_poll_descriptors_revents(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
{
assert(ctl && pfds && revents);
if (nfds == 1) {
*revents = pfds->revents;
return 0;
}
return -EINVAL;
}
/** /**
* \brief Ask to be informed about events (poll, #snd_ctl_async, #snd_ctl_read) * \brief Ask to be informed about events (poll, #snd_ctl_async, #snd_ctl_read)
* \param ctl CTL handle * \param ctl CTL handle

View file

@ -260,13 +260,13 @@ int snd_hwdep_poll_descriptors(snd_hwdep_t *hwdep, struct pollfd *pfds, unsigned
pfds->fd = hwdep->poll_fd; pfds->fd = hwdep->poll_fd;
switch (hwdep->mode & O_ACCMODE) { switch (hwdep->mode & O_ACCMODE) {
case O_WRONLY: case O_WRONLY:
pfds->events = POLLOUT; pfds->events = POLLOUT|POLLERR;
break; break;
case O_RDONLY: case O_RDONLY:
pfds->events = POLLIN; pfds->events = POLLIN|POLLERR;
break; break;
case O_RDWR: case O_RDWR:
pfds->events = POLLOUT|POLLIN; pfds->events = POLLOUT|POLLIN|POLLERR;
break; break;
default: default:
return -EIO; return -EIO;
@ -276,6 +276,24 @@ int snd_hwdep_poll_descriptors(snd_hwdep_t *hwdep, struct pollfd *pfds, unsigned
return 0; return 0;
} }
/**
* \brief get returned events from poll descriptors
* \param hwdep HwDep handle
* \param pfds array of poll descriptors
* \param nfds count of poll descriptors
* \param revents returned events
* \return zero if success, otherwise a negative error code
*/
int snd_hwdep_poll_descriptors_revents(snd_hwdep_t *hwdep, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
{
assert(hwdep && pfds && revents);
if (nfds == 1) {
*revents = pfds->revents;
return 0;
}
return -EINVAL;
}
/** /**
* \brief set nonblock mode * \brief set nonblock mode
* \param hwdep HwDep handle * \param hwdep HwDep handle

View file

@ -599,6 +599,28 @@ int snd_mixer_poll_descriptors(snd_mixer_t *mixer, struct pollfd *pfds, unsigned
return count; return count;
} }
/**
* \brief get returned events from poll descriptors
* \param mixer Mixer handle
* \param pfds array of poll descriptors
* \param nfds count of poll descriptors
* \param revents returned events
* \return zero if success, otherwise a negative error code
*/
int snd_mixer_poll_descriptors_revents(snd_mixer_t *mixer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
{
unsigned int idx;
unsigned short res;
assert(mixer && pfds && revents);
if (nfds == 0)
return -EINVAL;
res = 0;
for (idx = 0; idx < nfds; idx++)
res |= pfds->revents & (POLLIN|POLLERR);
*revents = res;
return 0;
}
/** /**
* \brief Wait for a mixer to become ready (i.e. at least one event pending) * \brief Wait for a mixer to become ready (i.e. at least one event pending)
* \param mixer Mixer handle * \param mixer Mixer handle

View file

@ -1003,14 +1003,33 @@ int snd_pcm_poll_descriptors_count(snd_pcm_t *pcm)
*/ */
int snd_pcm_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space) int snd_pcm_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space)
{ {
assert(pcm); assert(pcm && pfds);
if (space >= 1) { if (space >= 1 && pfds) {
pfds->fd = pcm->poll_fd; pfds->fd = pcm->poll_fd;
pfds->events = pcm->stream == SND_PCM_STREAM_PLAYBACK ? POLLOUT : POLLIN; pfds->events = pcm->stream == SND_PCM_STREAM_PLAYBACK ? (POLLOUT|POLLERR) : (POLLIN|POLLERR);
} } else
return 0;
return 1; return 1;
} }
/**
* \brief get returned events from poll descriptors
* \param pcm PCM handle
* \param pfds array of poll descriptors
* \param nfds count of poll descriptors
* \param revents returned events
* \return zero if success, otherwise a negative error code
*/
int snd_pcm_poll_descriptors_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
{
assert(pcm && pfds && revents);
if (nfds == 1) {
*revents = pfds->revents;
return 0;
}
return -EINVAL;
}
#ifndef DOC_HIDDEN #ifndef DOC_HIDDEN
#define STATE(v) [SND_PCM_STATE_##v] = #v #define STATE(v) [SND_PCM_STATE_##v] = #v
#define STREAM(v) [SND_PCM_STREAM_##v] = #v #define STREAM(v) [SND_PCM_STREAM_##v] = #v

View file

@ -313,12 +313,30 @@ int snd_rawmidi_poll_descriptors(snd_rawmidi_t *rawmidi, struct pollfd *pfds, un
assert(rawmidi); assert(rawmidi);
if (space >= 1) { if (space >= 1) {
pfds->fd = rawmidi->poll_fd; pfds->fd = rawmidi->poll_fd;
pfds->events = rawmidi->stream == SND_RAWMIDI_STREAM_OUTPUT ? POLLOUT : POLLIN; pfds->events = rawmidi->stream == SND_RAWMIDI_STREAM_OUTPUT ? (POLLOUT|POLLERR) : (POLLIN|POLLERR);
return 1; return 1;
} }
return 0; return 0;
} }
/**
* \brief get returned events from poll descriptors
* \param pcm rawmidi RawMidi handle
* \param pfds array of poll descriptors
* \param nfds count of poll descriptors
* \param revents returned events
* \return zero if success, otherwise a negative error code
*/
int snd_rawmidi_poll_descriptors_revents(snd_rawmidi_t *rawmidi, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
{
assert(rawmidi && pfds && revents);
if (nfds == 1) {
*revents = pfds->revents;
return 0;
}
return -EINVAL;
}
/** /**
* \brief set nonblock mode * \brief set nonblock mode
* \param rawmidi RawMidi handle * \param rawmidi RawMidi handle

View file

@ -305,11 +305,11 @@ int snd_seq_poll_descriptors(snd_seq_t *seq, struct pollfd *pfds, unsigned int s
assert(seq); assert(seq);
if ((events & POLLIN) && space >= 1) { if ((events & POLLIN) && space >= 1) {
assert(seq->streams & SND_SEQ_OPEN_INPUT); assert(seq->streams & SND_SEQ_OPEN_INPUT);
revents |= POLLIN; revents |= POLLIN|POLLERR;
} }
if ((events & POLLOUT) && space >= 1) { if ((events & POLLOUT) && space >= 1) {
assert(seq->streams & SND_SEQ_OPEN_INPUT); assert(seq->streams & SND_SEQ_OPEN_INPUT);
revents |= POLLOUT; revents |= POLLOUT|POLLERR;
} }
if (!revents) if (!revents)
return 0; return 0;
@ -318,6 +318,24 @@ int snd_seq_poll_descriptors(snd_seq_t *seq, struct pollfd *pfds, unsigned int s
return 1; return 1;
} }
/**
* \brief get returned events from poll descriptors
* \param seq sequencer handle
* \param pfds array of poll descriptors
* \param nfds count of poll descriptors
* \param revents returned events
* \return zero if success, otherwise a negative error code
*/
int snd_seq_poll_descriptors_revents(snd_seq_t *seq, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
{
assert(seq && pfds && revents);
if (nfds == 1) {
*revents = pfds->revents;
return 0;
}
return -EINVAL;
}
/** /**
* \brief Set nonblock mode * \brief Set nonblock mode
* \param seq sequencer handle * \param seq sequencer handle

View file

@ -261,13 +261,13 @@ int snd_timer_poll_descriptors(snd_timer_t *timer, struct pollfd *pfds, unsigned
pfds->fd = timer->poll_fd; pfds->fd = timer->poll_fd;
switch (timer->mode & O_ACCMODE) { switch (timer->mode & O_ACCMODE) {
case O_WRONLY: case O_WRONLY:
pfds->events = POLLOUT; pfds->events = POLLOUT|POLLERR;
break; break;
case O_RDONLY: case O_RDONLY:
pfds->events = POLLIN; pfds->events = POLLIN|POLLERR;
break; break;
case O_RDWR: case O_RDWR:
pfds->events = POLLOUT|POLLIN; pfds->events = POLLOUT|POLLIN|POLLERR;
break; break;
default: default:
return -EIO; return -EIO;
@ -277,6 +277,24 @@ int snd_timer_poll_descriptors(snd_timer_t *timer, struct pollfd *pfds, unsigned
return 0; return 0;
} }
/**
* \brief get returned events from poll descriptors
* \param timer timer handle
* \param pfds array of poll descriptors
* \param nfds count of poll descriptors
* \param revents returned events
* \return zero if success, otherwise a negative error code
*/
int snd_timer_poll_descriptors_revents(snd_timer_t *timer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
{
assert(timer && pfds && revents);
if (nfds == 1) {
*revents = pfds->revents;
return 0;
}
return -EINVAL;
}
/** /**
* \brief set nonblock mode * \brief set nonblock mode
* \param timer timer handle * \param timer timer handle

View file

@ -226,22 +226,17 @@ static int write_loop(snd_pcm_t *handle,
* Transfer method - write and wait for room in buffer using poll * Transfer method - write and wait for room in buffer using poll
*/ */
static int wait_for_poll(struct pollfd *ufds, int count) static int wait_for_poll(snd_pcm_t *handle, struct pollfd *ufds, unsigned int count)
{ {
int i; unsigned short revents;
unsigned int events;
while (1) { while (1) {
poll(ufds, count, -1); poll(ufds, count, -1);
for (i = 0; i < count; i++) { snd_pcm_poll_descriptors_revents(handle, ufds, count, &revents);
events = ufds[i].revents; if (revents & POLLERR)
if (events & POLLERR) { return -EIO;
printf("Poll - POLLERR detected\n"); if (revents & POLLOUT)
return -EIO; return 0;
}
if (events & POLLOUT)
return 0;
}
} }
} }
@ -252,7 +247,7 @@ static int write_and_poll_loop(snd_pcm_t *handle,
struct pollfd *ufds; struct pollfd *ufds;
double phase = 0; double phase = 0;
signed short *ptr; signed short *ptr;
int err, count, cptr; int err, count, cptr, init;
count = snd_pcm_poll_descriptors_count (handle); count = snd_pcm_poll_descriptors_count (handle);
if (count <= 0) { if (count <= 0) {
@ -270,11 +265,24 @@ static int write_and_poll_loop(snd_pcm_t *handle,
return err; return err;
} }
init = 1;
while (1) { while (1) {
err = wait_for_poll(ufds, count); if (!init) {
if (err < 0) { err = wait_for_poll(handle, ufds, count);
printf("Wait for poll failed\n"); if (err < 0) {
return err; if (snd_pcm_state(handle) == SND_PCM_STATE_XRUN ||
snd_pcm_state(handle) == SND_PCM_STATE_SUSPENDED) {
err = snd_pcm_state(handle) == SND_PCM_STATE_XRUN ? -EPIPE : -ESTRPIPE;
if (xrun_recovery(handle, err) < 0) {
printf("Write error: %s\n", snd_strerror(err));
exit(EXIT_FAILURE);
}
init = 1;
} else {
printf("Wait for poll failed\n");
return err;
}
}
} }
generate_sine(areas, 0, period_size, &phase); generate_sine(areas, 0, period_size, &phase);
@ -287,18 +295,31 @@ static int write_and_poll_loop(snd_pcm_t *handle,
printf("Write error: %s\n", snd_strerror(err)); printf("Write error: %s\n", snd_strerror(err));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
init = 1;
break; /* skip one period */ break; /* skip one period */
} }
if (snd_pcm_state(handle) == SND_PCM_STATE_RUNNING)
init = 0;
ptr += err * channels; ptr += err * channels;
cptr -= err; cptr -= err;
if (cptr == 0) if (cptr == 0)
break; break;
/* it is possible, that initial buffer cannot store */ /* it is possible, that initial buffer cannot store */
/* all data from last period, so wait awhile */ /* all data from last period, so wait awhile */
err = wait_for_poll(ufds, count); err = wait_for_poll(handle, ufds, count);
if (err < 0) { if (err < 0) {
printf("Wait for poll failed\n"); if (snd_pcm_state(handle) == SND_PCM_STATE_XRUN ||
return err; snd_pcm_state(handle) == SND_PCM_STATE_SUSPENDED) {
err = snd_pcm_state(handle) == SND_PCM_STATE_XRUN ? -EPIPE : -ESTRPIPE;
if (xrun_recovery(handle, err) < 0) {
printf("Write error: %s\n", snd_strerror(err));
exit(EXIT_FAILURE);
}
init = 1;
} else {
printf("Wait for poll failed\n");
return err;
}
} }
} }
} }