From 633815a591934f0a9f6639d7c2c2a36e73ec92ce Mon Sep 17 00:00:00 2001 From: Abramo Bagnara Date: Sun, 15 Oct 2000 07:12:13 +0000 Subject: [PATCH] Missing fixes to make shm on share works. Useable PCM sharing is in! --- src/pcm/pcm_multi.c | 2 +- src/pcm/pcm_share.c | 52 +++++++++++++++++++++++++++++++-------------- src/pcm/pcm_shm.c | 10 +++++---- 3 files changed, 43 insertions(+), 21 deletions(-) diff --git a/src/pcm/pcm_multi.c b/src/pcm/pcm_multi.c index cd41dd31..e8541c20 100644 --- a/src/pcm/pcm_multi.c +++ b/src/pcm/pcm_multi.c @@ -633,7 +633,7 @@ int _snd_pcm_multi_open(snd_pcm_t **pcmp, char *name, snd_config_t *conf, cchannel = strtol(m->id, &p, 10); if (errno || *p || cchannel < 0) return -EINVAL; - if ((unsigned)cchannel > channels_count) + if ((unsigned)cchannel >= channels_count) channels_count = cchannel + 1; } if (channels_count == 0) diff --git a/src/pcm/pcm_share.c b/src/pcm/pcm_share.c index d20221ca..7fd46e29 100644 --- a/src/pcm/pcm_share.c +++ b/src/pcm/pcm_share.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "pcm_local.h" #include "list.h" @@ -139,7 +140,8 @@ void *snd_pcm_share_slave_thread(void *data) err = sigaction(SIGIO, &act, NULL); assert(err == 0); while (1) { - pause(); + int sig; + sigwait(&act.sa_mask, &sig); snd_pcm_share_interrupt(slave); } return NULL; @@ -279,7 +281,10 @@ static int snd_pcm_share_close(snd_pcm_t *pcm) slave->setup_count--; slave->open_count--; if (slave->open_count == 0) { - pthread_kill(slave->thread, SIGTERM); + err = pthread_cancel(slave->thread); + assert(err == 0); + err = pthread_join(slave->thread, 0); + assert(err == 0); err = snd_pcm_close(slave->pcm); list_del(&slave->list); pthread_mutex_unlock(&slave->mutex); @@ -372,6 +377,7 @@ static int snd_pcm_share_mmap(snd_pcm_t *pcm) snd_pcm_share_t *share = pcm->private; snd_pcm_share_slave_t *slave = share->slave; snd_pcm_mmap_info_t *i; + size_t count; int err; pthread_mutex_lock(&slave->mutex); if (slave->mmap_count == 0) { @@ -385,21 +391,28 @@ static int snd_pcm_share_mmap(snd_pcm_t *pcm) slave->mmap_count++; } pthread_mutex_unlock(&slave->mutex); - pcm->mmap_info_count = slave->pcm->mmap_info_count + 1; - pcm->mmap_info = malloc(pcm->mmap_info_count * sizeof(*pcm->mmap_info)); - if (!pcm->mmap_info) + count = slave->pcm->mmap_info_count; + i = malloc((count + 1) * sizeof(*i)); + if (!i) return -ENOMEM; - memcpy(pcm->mmap_info, slave->pcm->mmap_info, slave->pcm->mmap_info_count * sizeof(*pcm->mmap_info)); - i = &pcm->mmap_info[slave->pcm->mmap_info_count]; i->type = SND_PCM_MMAP_USER; i->size = snd_pcm_frames_to_bytes(pcm, pcm->setup.buffer_size); - share->stopped_data = malloc(i->size); - if (share->stopped_data == 0) { - free(pcm->mmap_info); - pcm->mmap_info = 0; - return -ENOMEM; + i->u.user.shmid = shmget(IPC_PRIVATE, i->size, 0666); + if (i->u.user.shmid < 0) { + SYSERR("shmget failed"); + free(i); + return -errno; + } + i->addr = shmat(i->u.user.shmid, 0, 0); + if (i->addr == (void*) -1) { + SYSERR("shmat failed"); + free(i); + return -errno; } - i->addr = share->stopped_data; + share->stopped_data = i->addr; + memcpy(i + 1, slave->pcm->mmap_info, count * sizeof(*pcm->mmap_info)); + pcm->mmap_info_count = count + 1; + pcm->mmap_info = i; return 0; } @@ -418,10 +431,17 @@ static int snd_pcm_share_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED) } } pthread_mutex_unlock(&slave->mutex); - free(pcm->mmap_info); + if (shmdt(pcm->mmap_info->addr) < 0) { + SYSERR("shmdt failed"); + return -errno; + } + if (shmctl(pcm->mmap_info->u.user.shmid, IPC_RMID, 0) < 0) { + SYSERR("shmctl IPC_RMID failed"); + return -errno; + } pcm->mmap_info_count = 0; + free(pcm->mmap_info); pcm->mmap_info = 0; - free(share->stopped_data); return 0; } @@ -1172,7 +1192,7 @@ int _snd_pcm_share_open(snd_pcm_t **pcmp, char *name, snd_config_t *conf, ERR("Invalid client channel in binding: %s", n->id); return -EINVAL; } - if ((unsigned)cchannel > channels_count) + if ((unsigned)cchannel >= channels_count) channels_count = cchannel + 1; } if (channels_count == 0) { diff --git a/src/pcm/pcm_shm.c b/src/pcm/pcm_shm.c index ced92da2..c8dca3f5 100644 --- a/src/pcm/pcm_shm.c +++ b/src/pcm/pcm_shm.c @@ -416,14 +416,16 @@ static int snd_pcm_shm_munmap(snd_pcm_t *pcm) snd_pcm_mmap_info_t *i = &pcm->mmap_info[k]; if (i->type == SND_PCM_MMAP_KERNEL) { err = munmap(i->addr, i->size); - if (err < 0) + if (err < 0) { SYSERR("munmap failed"); - return -errno; + return -errno; + } } else { err = shmdt(i->addr); - if (err < 0) + if (err < 0) { SYSERR("shmdt failed"); - return -errno; + return -errno; + } } } pcm->mmap_info_count = 0; -- 2.47.1