mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-11-04 13:30:08 -05:00
Check timer version for read-block workaround
Check the timer protocl version whether to use poll for a workaround of read-block problems.
This commit is contained in:
parent
0d0e1a55c2
commit
48bff53b36
2 changed files with 27 additions and 11 deletions
|
|
@ -419,11 +419,8 @@ int snd_pcm_direct_async(snd_pcm_t *pcm, int sig, pid_t pid)
|
||||||
/* empty the timer read queue */
|
/* empty the timer read queue */
|
||||||
void snd_pcm_direct_clear_timer_queue(snd_pcm_direct_t *dmix)
|
void snd_pcm_direct_clear_timer_queue(snd_pcm_direct_t *dmix)
|
||||||
{
|
{
|
||||||
struct pollfd fds[4];
|
if (dmix->timer_need_poll) {
|
||||||
int fdn = snd_timer_poll_descriptors(dmix->timer, fds, 4);
|
while (poll(&dmix->timer_fd, 1, 0) > 0) {
|
||||||
|
|
||||||
while (poll(fds, fdn, 0) > 0) {
|
|
||||||
/* rbuf might be overwriten by multiple plugins */
|
|
||||||
/* we don't need the value */
|
/* we don't need the value */
|
||||||
if (dmix->tread) {
|
if (dmix->tread) {
|
||||||
snd_timer_tread_t rbuf;
|
snd_timer_tread_t rbuf;
|
||||||
|
|
@ -433,6 +430,17 @@ void snd_pcm_direct_clear_timer_queue(snd_pcm_direct_t *dmix)
|
||||||
snd_timer_read(dmix->timer, &rbuf, sizeof(rbuf));
|
snd_timer_read(dmix->timer, &rbuf, sizeof(rbuf));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (dmix->tread) {
|
||||||
|
snd_timer_tread_t rbuf;
|
||||||
|
while (snd_timer_read(dmix->timer, &rbuf, sizeof(rbuf)) > 0)
|
||||||
|
;
|
||||||
|
} else {
|
||||||
|
snd_timer_read_t rbuf;
|
||||||
|
while (snd_timer_read(dmix->timer, &rbuf, sizeof(rbuf)) > 0)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_direct_timer_stop(snd_pcm_direct_t *dmix)
|
int snd_pcm_direct_timer_stop(snd_pcm_direct_t *dmix)
|
||||||
|
|
@ -859,10 +867,10 @@ int snd_pcm_direct_initialize_poll_fd(snd_pcm_direct_t *dmix)
|
||||||
snd_pcm_info_t *info;
|
snd_pcm_info_t *info;
|
||||||
snd_timer_params_t *params;
|
snd_timer_params_t *params;
|
||||||
char name[128];
|
char name[128];
|
||||||
struct pollfd fd;
|
|
||||||
int capture = dmix->type == SND_PCM_TYPE_DSNOOP ? 1 : 0;
|
int capture = dmix->type == SND_PCM_TYPE_DSNOOP ? 1 : 0;
|
||||||
|
|
||||||
dmix->tread = 0;
|
dmix->tread = 0;
|
||||||
|
dmix->timer_need_poll = 0;
|
||||||
snd_pcm_info_alloca(&info);
|
snd_pcm_info_alloca(&info);
|
||||||
snd_timer_params_alloca(¶ms);
|
snd_timer_params_alloca(¶ms);
|
||||||
ret = snd_pcm_info(dmix->spcm, info);
|
ret = snd_pcm_info(dmix->spcm, info);
|
||||||
|
|
@ -886,8 +894,8 @@ int snd_pcm_direct_initialize_poll_fd(snd_pcm_direct_t *dmix)
|
||||||
SNDERR("unable to use timer with fd more than one!!!", name);
|
SNDERR("unable to use timer with fd more than one!!!", name);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
snd_timer_poll_descriptors(dmix->timer, &fd, 1);
|
snd_timer_poll_descriptors(dmix->timer, &dmix->timer_fd, 1);
|
||||||
dmix->poll_fd = fd.fd;
|
dmix->poll_fd = dmix->timer_fd.fd;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A hack to avoid Oops in the older kernel
|
* A hack to avoid Oops in the older kernel
|
||||||
|
|
@ -902,6 +910,12 @@ int snd_pcm_direct_initialize_poll_fd(snd_pcm_direct_t *dmix)
|
||||||
if (ioctl(dmix->poll_fd, SNDRV_TIMER_IOCTL_TREAD, &dmix->tread) < 0)
|
if (ioctl(dmix->poll_fd, SNDRV_TIMER_IOCTL_TREAD, &dmix->tread) < 0)
|
||||||
dmix->tread = 0;
|
dmix->tread = 0;
|
||||||
}
|
}
|
||||||
|
/* In older versions, check via poll before read() is needed
|
||||||
|
* because of the confliction between TIMER_START and
|
||||||
|
* FIONBIO ioctls.
|
||||||
|
*/
|
||||||
|
if (ver < SNDRV_PROTOCOL_VERSION(2, 0, 4))
|
||||||
|
dmix->timer_need_poll = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
snd_timer_params_set_auto_start(params, 1);
|
snd_timer_params_set_auto_start(params, 1);
|
||||||
|
|
|
||||||
|
|
@ -95,8 +95,10 @@ struct snd_pcm_direct {
|
||||||
int server, client;
|
int server, client;
|
||||||
int comm_fd; /* communication file descriptor (socket) */
|
int comm_fd; /* communication file descriptor (socket) */
|
||||||
int hw_fd; /* hardware file descriptor */
|
int hw_fd; /* hardware file descriptor */
|
||||||
|
struct pollfd timer_fd;
|
||||||
int poll_fd;
|
int poll_fd;
|
||||||
int tread;
|
int tread;
|
||||||
|
int timer_need_poll;
|
||||||
int server_fd;
|
int server_fd;
|
||||||
pid_t server_pid;
|
pid_t server_pid;
|
||||||
snd_timer_t *timer; /* timer used as poll_fd */
|
snd_timer_t *timer; /* timer used as poll_fd */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue