Fix timer read from 32bit user-space on 64bit kernel

snd_timer_tread struct is a bad design for 32/64bit compatibility,
and reading this struct on 32bit program returns zero.  This results
in tight poll looping (bug#1938, #1945).

For avoiding this bug, now more bigger buffer is read to cover the
64bit tread struct, too.  Also this optimizes the read without
checking -EAGAIN in the case both user-space and kernel have the same
tread size.
This commit is contained in:
Takashi Iwai 2006-03-21 10:39:49 +00:00
parent 24a3cfc236
commit 91066a98b9

View file

@ -497,14 +497,6 @@ int snd_pcm_direct_async(snd_pcm_t *pcm, int sig, pid_t pid)
return snd_timer_async(dmix->timer, sig, pid); return snd_timer_async(dmix->timer, sig, pid);
} }
static inline void process_timer_event(snd_pcm_direct_t *dmix ATTRIBUTE_UNUSED,
snd_timer_tread_t *te ATTRIBUTE_UNUSED)
{
#if 0
printf("te->event = %i\n", te->event);
#endif
}
/* 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)
{ {
@ -512,9 +504,8 @@ void snd_pcm_direct_clear_timer_queue(snd_pcm_direct_t *dmix)
while (poll(&dmix->timer_fd, 1, 0) > 0) { while (poll(&dmix->timer_fd, 1, 0) > 0) {
/* 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[4];
snd_timer_read(dmix->timer, &rbuf, sizeof(rbuf)); snd_timer_read(dmix->timer, rbuf, sizeof(rbuf));
process_timer_event(dmix, &rbuf);
} else { } else {
snd_timer_read_t rbuf; snd_timer_read_t rbuf;
snd_timer_read(dmix->timer, &rbuf, sizeof(rbuf)); snd_timer_read(dmix->timer, &rbuf, sizeof(rbuf));
@ -522,9 +513,12 @@ void snd_pcm_direct_clear_timer_queue(snd_pcm_direct_t *dmix)
} }
} else { } else {
if (dmix->tread) { if (dmix->tread) {
snd_timer_tread_t rbuf; snd_timer_tread_t rbuf[4];
while (snd_timer_read(dmix->timer, &rbuf, sizeof(rbuf)) > 0) int len;
process_timer_event(dmix, &rbuf); while ((len = snd_timer_read(dmix->timer, rbuf,
sizeof(rbuf))) > 0 &&
len != sizeof(rbuf[0]))
;
} else { } else {
snd_timer_read_t rbuf; snd_timer_read_t rbuf;
while (snd_timer_read(dmix->timer, &rbuf, sizeof(rbuf)) > 0) while (snd_timer_read(dmix->timer, &rbuf, sizeof(rbuf)) > 0)