From 84c40f4970b0656e529250b49c041abb70ed9d25 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Fri, 5 Mar 2004 18:36:19 +0000 Subject: [PATCH] =?utf8?q?Michel=20D=C3=A4nzer=20=20Ap?= =?utf8?q?parently=20these=20changes=20from=20pcm=5Fdirect.c=20revisions?= =?utf8?q?=201.12=20and=201.14=20were=20accidentally=20reverted=20in=20rev?= =?utf8?q?ision=201.15.=20Please=20reapply.?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- src/pcm/pcm_direct.c | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/src/pcm/pcm_direct.c b/src/pcm/pcm_direct.c index 3b748d36..a3e40e5f 100644 --- a/src/pcm/pcm_direct.c +++ b/src/pcm/pcm_direct.c @@ -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; -- 2.47.1