mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-07 13:30:03 -05:00
properly reinitialize pollfd array after resume
git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1590 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
parent
54b9f55d2e
commit
df9522cb8c
2 changed files with 54 additions and 27 deletions
|
|
@ -685,6 +685,7 @@ static void thread_func(void *userdata) {
|
|||
|
||||
goto fail;
|
||||
}
|
||||
/* pa_log("got alsa event"); */
|
||||
} else
|
||||
revents = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -93,6 +93,14 @@ struct userdata {
|
|||
char *device_name;
|
||||
|
||||
int use_mmap;
|
||||
|
||||
struct pollfd *pollfd;
|
||||
int n_alsa_fds;
|
||||
};
|
||||
|
||||
enum {
|
||||
POLLFD_ASYNCQ,
|
||||
POLLFD_ALSA_BASE
|
||||
};
|
||||
|
||||
static const char* const valid_modargs[] = {
|
||||
|
|
@ -220,6 +228,31 @@ static pa_usec_t source_get_latency(struct userdata *u) {
|
|||
return r;
|
||||
}
|
||||
|
||||
static int build_pollfd(struct userdata *u) {
|
||||
int err;
|
||||
|
||||
pa_assert(u);
|
||||
pa_assert(u->pcm_handle);
|
||||
|
||||
if ((u->n_alsa_fds = snd_pcm_poll_descriptors_count(u->pcm_handle)) < 0) {
|
||||
pa_log("snd_pcm_poll_descriptors_count() failed: %s", snd_strerror(u->n_alsa_fds));
|
||||
return -1;
|
||||
}
|
||||
|
||||
pa_xfree(u->pollfd);
|
||||
u->pollfd = pa_xnew0(struct pollfd, POLLFD_ALSA_BASE + u->n_alsa_fds);
|
||||
|
||||
u->pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->asyncmsgq);
|
||||
u->pollfd[POLLFD_ASYNCQ].events = POLLIN;
|
||||
|
||||
if ((err = snd_pcm_poll_descriptors(u->pcm_handle, u->pollfd+POLLFD_ALSA_BASE, u->n_alsa_fds)) < 0) {
|
||||
pa_log("snd_pcm_poll_descriptors() failed: %s", snd_strerror(err));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int suspend(struct userdata *u) {
|
||||
pa_assert(u);
|
||||
pa_assert(u->pcm_handle);
|
||||
|
|
@ -279,6 +312,9 @@ static int unsuspend(struct userdata *u) {
|
|||
pa_log("Failed to set software parameters: %s", snd_strerror(err));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (build_pollfd(u) < 0)
|
||||
goto fail;
|
||||
|
||||
snd_pcm_start(u->pcm_handle);
|
||||
|
||||
|
|
@ -467,14 +503,9 @@ static int source_set_mute_cb(pa_source *s) {
|
|||
}
|
||||
|
||||
static void thread_func(void *userdata) {
|
||||
enum {
|
||||
POLLFD_ASYNCQ,
|
||||
POLLFD_ALSA_BASE
|
||||
};
|
||||
|
||||
struct userdata *u = userdata;
|
||||
struct pollfd *pollfd = NULL;
|
||||
int n_alsa_fds, err;
|
||||
int err;
|
||||
unsigned short revents = 0;
|
||||
snd_pcm_status_t *status;
|
||||
|
||||
|
|
@ -483,20 +514,8 @@ static void thread_func(void *userdata) {
|
|||
|
||||
pa_log_debug("Thread starting up");
|
||||
|
||||
if ((n_alsa_fds = snd_pcm_poll_descriptors_count(u->pcm_handle)) < 0) {
|
||||
pa_log("snd_pcm_poll_descriptors_count() failed: %s", snd_strerror(n_alsa_fds));
|
||||
if (build_pollfd(u) < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pollfd = pa_xnew0(struct pollfd, POLLFD_ALSA_BASE + n_alsa_fds);
|
||||
|
||||
pollfd[POLLFD_ASYNCQ].fd = pa_asyncmsgq_get_fd(u->asyncmsgq);
|
||||
pollfd[POLLFD_ASYNCQ].events = POLLIN;
|
||||
|
||||
if ((err = snd_pcm_poll_descriptors(u->pcm_handle, pollfd+POLLFD_ALSA_BASE, n_alsa_fds)) < 0) {
|
||||
pa_log("snd_pcm_poll_descriptors() failed: %s", snd_strerror(err));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
pa_msgobject *object;
|
||||
|
|
@ -607,15 +626,14 @@ static void thread_func(void *userdata) {
|
|||
continue;
|
||||
|
||||
/* pa_log("polling for %i", POLLFD_ALSA_BASE + (PA_SOURCE_OPENED(u->source->thread_info.state) ? n_alsa_fds : 0)); */
|
||||
r = poll(pollfd, POLLFD_ALSA_BASE + (PA_SOURCE_OPENED(u->source->thread_info.state) ? n_alsa_fds : 0), -1);
|
||||
/*pa_log("polling got dsp=%i amq=%i (%i)", r > 0 ? pollfd[POLLFD_DSP].revents : 0, r > 0 ? pollfd[POLLFD_ASYNCQ].revents : 0, r); */
|
||||
r = poll(u->pollfd, POLLFD_ALSA_BASE + (PA_SOURCE_OPENED(u->source->thread_info.state) ? u->n_alsa_fds : 0), -1);
|
||||
/* pa_log("poll end"); */
|
||||
|
||||
pa_asyncmsgq_after_poll(u->asyncmsgq);
|
||||
|
||||
if (r < 0) {
|
||||
if (errno == EINTR) {
|
||||
pollfd[POLLFD_ASYNCQ].revents = 0;
|
||||
u->pollfd[POLLFD_ASYNCQ].revents = 0;
|
||||
revents = 0;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -627,16 +645,26 @@ static void thread_func(void *userdata) {
|
|||
pa_assert(r > 0);
|
||||
|
||||
if (PA_SOURCE_OPENED(u->source->thread_info.state)) {
|
||||
if ((err = snd_pcm_poll_descriptors_revents(u->pcm_handle, pollfd + POLLFD_ALSA_BASE, n_alsa_fds, &revents)) < 0) {
|
||||
if ((err = snd_pcm_poll_descriptors_revents(u->pcm_handle, u->pollfd + POLLFD_ALSA_BASE, u->n_alsa_fds, &revents)) < 0) {
|
||||
pa_log("snd_pcm_poll_descriptors_revents() failed: %s", snd_strerror(err));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (revents & (POLLERR|POLLNVAL|POLLHUP)) {
|
||||
if (revents & POLLERR)
|
||||
pa_log_warn("Got POLLERR from ALSA");
|
||||
if (revents & POLLNVAL)
|
||||
pa_log_warn("Got POLLNVAL from ALSA");
|
||||
if (revents & POLLHUP)
|
||||
pa_log_warn("Got POLLHUP from ALSA");
|
||||
|
||||
goto fail;
|
||||
}
|
||||
/* pa_log("got alsa event"); */
|
||||
} else
|
||||
revents = 0;
|
||||
|
||||
pa_assert((pollfd[POLLFD_ASYNCQ].revents & ~POLLIN) == 0);
|
||||
pa_assert((u->pollfd[POLLFD_ASYNCQ].revents & ~POLLIN) == 0);
|
||||
}
|
||||
|
||||
fail:
|
||||
|
|
@ -647,11 +675,8 @@ fail:
|
|||
|
||||
finish:
|
||||
pa_log_debug("Thread shutting down");
|
||||
|
||||
pa_xfree(pollfd);
|
||||
}
|
||||
|
||||
|
||||
int pa__init(pa_core *c, pa_module*m) {
|
||||
|
||||
pa_modargs *ma = NULL;
|
||||
|
|
@ -898,6 +923,7 @@ void pa__done(pa_core *c, pa_module*m) {
|
|||
snd_pcm_close(u->pcm_handle);
|
||||
}
|
||||
|
||||
pa_xfree(u->pollfd);
|
||||
pa_xfree(u->device_name);
|
||||
pa_xfree(u);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue