OSDN Git Service

Fix timer read from 32bit user-space on 64bit kernel
authorTakashi Iwai <tiwai@suse.de>
Tue, 21 Mar 2006 10:39:49 +0000 (10:39 +0000)
committerTakashi Iwai <tiwai@suse.de>
Tue, 21 Mar 2006 10:39:49 +0000 (10:39 +0000)
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.

src/pcm/pcm_direct.c

index 22ac542..8154488 100644 (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);
 }
 
-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 */
 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) {
                        /* we don't need the value */
                        if (dmix->tread) {
-                               snd_timer_tread_t rbuf;
-                               snd_timer_read(dmix->timer, &rbuf, sizeof(rbuf));
-                               process_timer_event(dmix, &rbuf);
+                               snd_timer_tread_t rbuf[4];
+                               snd_timer_read(dmix->timer, rbuf, sizeof(rbuf));
                        } else {
                                snd_timer_read_t 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 {
                if (dmix->tread) {
-                       snd_timer_tread_t rbuf;
-                       while (snd_timer_read(dmix->timer, &rbuf, sizeof(rbuf)) > 0)
-                               process_timer_event(dmix, &rbuf);
+                       snd_timer_tread_t rbuf[4];
+                       int len;
+                       while ((len = snd_timer_read(dmix->timer, rbuf,
+                                                    sizeof(rbuf))) > 0 &&
+                              len != sizeof(rbuf[0]))
+                               ;
                } else {
                        snd_timer_read_t rbuf;
                        while (snd_timer_read(dmix->timer, &rbuf, sizeof(rbuf)) > 0)