/* * sum ring buffer shared memory area */ static int shm_sum_create_or_connect(snd_pcm_direct_t *dmix) { struct shmid_ds buf; int tmpid, err; size_t size; size = dmix->shmptr->s.channels * dmix->shmptr->s.buffer_size * sizeof(signed int); retryshm: dmix->u.dmix.shmid_sum = shmget(dmix->ipc_key + 1, size, IPC_CREAT | dmix->ipc_perm); err = -errno; if (dmix->u.dmix.shmid_sum < 0){ if (errno == EINVAL) if ((tmpid = shmget(dmix->ipc_key + 1, 0, dmix->ipc_perm)) != -1) if (!shmctl(tmpid, IPC_STAT, &buf)) if (!buf.shm_nattch) /* no users so destroy the segment */ if (!shmctl(tmpid, IPC_RMID, NULL)) goto retryshm; return err; } dmix->u.dmix.sum_buffer = shmat(dmix->u.dmix.shmid_sum, 0, 0); if (dmix->u.dmix.sum_buffer == (void *) -1) { shm_sum_discard(dmix); return -errno; } mlock(dmix->u.dmix.sum_buffer, size); return 0; }
static void dmix_server_free(snd_pcm_direct_t *dmix) { /* remove the memory region */ shm_sum_create_or_connect(dmix); shm_sum_discard(dmix); }