]> git.alsa-project.org Git - alsa-lib.git/commitdiff
Michel Dänzer <michel@daenzer.net>
authorJaroslav Kysela <perex@perex.cz>
Fri, 5 Mar 2004 18:36:19 +0000 (18:36 +0000)
committerJaroslav Kysela <perex@perex.cz>
Fri, 5 Mar 2004 18:36:19 +0000 (18:36 +0000)
Apparently these changes from pcm_direct.c revisions 1.12 and 1.14 were
accidentally reverted in revision 1.15. Please reapply.

src/pcm/pcm_direct.c

index 3b748d36180ae0de3f675385d45b037edc887fa3..a3e40e5fa32d11902c1b05dee2ad1ba94dc11d54 100644 (file)
@@ -100,11 +100,21 @@ int snd_pcm_direct_semaphore_up(snd_pcm_direct_t *dmix, int sem_num)
 int snd_pcm_direct_shm_create_or_connect(snd_pcm_direct_t *dmix)
 {
        struct shmid_ds buf;
-       int ret = 0;
+       int tmpid, err;
        
+retryget:
        dmix->shmid = shmget(dmix->ipc_key, sizeof(snd_pcm_direct_share_t), IPC_CREAT | 0666);
-       if (dmix->shmid < 0)
-               return -errno;
+       err = -errno;
+       if (dmix->shmid < 0){
+               if (errno == EINVAL)
+               if ((tmpid = shmget(dmix->ipc_key, 0, 0666)) != -1)
+               if (!shmctl(tmpid, IPC_STAT, &buf))
+               if (!buf.shm_nattch)
+               /* no users so destroy the segment */
+               if (!shmctl(tmpid, IPC_RMID, NULL))
+                   goto retryget;
+               return err;
+       }
        dmix->shmptr = shmat(dmix->shmid, 0, 0);
        if (dmix->shmptr == (void *) -1) {
                snd_pcm_direct_shm_discard(dmix);
@@ -117,9 +127,9 @@ int snd_pcm_direct_shm_create_or_connect(snd_pcm_direct_t *dmix)
        }
        if (buf.shm_nattch == 1) {      /* we're the first user, clear the segment */
                memset(dmix->shmptr, 0, sizeof(snd_pcm_direct_share_t));
-               ret = 1;
+               return 1;
        }
-       return ret;
+       return 0;
 }
 
 int snd_pcm_direct_shm_discard(snd_pcm_direct_t *dmix)
@@ -409,15 +419,23 @@ int snd_pcm_direct_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned in
 {
        snd_pcm_direct_t *dmix = pcm->private_data;
        unsigned short events;
-       static snd_timer_read_t rbuf[5];        /* can be overwriten by multiple plugins, we don't need the value */
+       /* rbuf might be overwriten by multiple plugins */
+       /* we don't need the value */
+       static snd_timer_read_t rbuf[5];
 
        assert(pfds && nfds == 1 && revents);
        events = pfds[0].revents;
        if (events & POLLIN) {
-               events |= POLLOUT;
-               events &= ~POLLIN;
+               int empty = 0;
+               if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
+                       events |= POLLOUT;
+                       events &= ~POLLIN;
+                       empty = snd_pcm_mmap_playback_avail(pcm) < pcm->avail_min;
+               } else {
+                       empty = snd_pcm_mmap_capture_avail(pcm) < pcm->avail_min;
+               }
                /* empty the timer read queue */
-               while (snd_timer_read(dmix->timer, &rbuf, sizeof(rbuf)) == sizeof(rbuf)) ;
+               while (empty && snd_timer_read(dmix->timer, &rbuf, sizeof(rbuf)) == sizeof(rbuf)) ;
        }
        *revents = events;
        return 0;