mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-31 22:25:35 -04:00
Missing fixes to make shm on share works. Useable PCM sharing is in!
This commit is contained in:
parent
8fb9fab748
commit
633815a591
3 changed files with 43 additions and 21 deletions
|
|
@ -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);
|
cchannel = strtol(m->id, &p, 10);
|
||||||
if (errno || *p || cchannel < 0)
|
if (errno || *p || cchannel < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if ((unsigned)cchannel > channels_count)
|
if ((unsigned)cchannel >= channels_count)
|
||||||
channels_count = cchannel + 1;
|
channels_count = cchannel + 1;
|
||||||
}
|
}
|
||||||
if (channels_count == 0)
|
if (channels_count == 0)
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/poll.h>
|
#include <sys/poll.h>
|
||||||
|
#include <sys/shm.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include "pcm_local.h"
|
#include "pcm_local.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
|
@ -139,7 +140,8 @@ void *snd_pcm_share_slave_thread(void *data)
|
||||||
err = sigaction(SIGIO, &act, NULL);
|
err = sigaction(SIGIO, &act, NULL);
|
||||||
assert(err == 0);
|
assert(err == 0);
|
||||||
while (1) {
|
while (1) {
|
||||||
pause();
|
int sig;
|
||||||
|
sigwait(&act.sa_mask, &sig);
|
||||||
snd_pcm_share_interrupt(slave);
|
snd_pcm_share_interrupt(slave);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -279,7 +281,10 @@ static int snd_pcm_share_close(snd_pcm_t *pcm)
|
||||||
slave->setup_count--;
|
slave->setup_count--;
|
||||||
slave->open_count--;
|
slave->open_count--;
|
||||||
if (slave->open_count == 0) {
|
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);
|
err = snd_pcm_close(slave->pcm);
|
||||||
list_del(&slave->list);
|
list_del(&slave->list);
|
||||||
pthread_mutex_unlock(&slave->mutex);
|
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_t *share = pcm->private;
|
||||||
snd_pcm_share_slave_t *slave = share->slave;
|
snd_pcm_share_slave_t *slave = share->slave;
|
||||||
snd_pcm_mmap_info_t *i;
|
snd_pcm_mmap_info_t *i;
|
||||||
|
size_t count;
|
||||||
int err;
|
int err;
|
||||||
pthread_mutex_lock(&slave->mutex);
|
pthread_mutex_lock(&slave->mutex);
|
||||||
if (slave->mmap_count == 0) {
|
if (slave->mmap_count == 0) {
|
||||||
|
|
@ -385,21 +391,28 @@ static int snd_pcm_share_mmap(snd_pcm_t *pcm)
|
||||||
slave->mmap_count++;
|
slave->mmap_count++;
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&slave->mutex);
|
pthread_mutex_unlock(&slave->mutex);
|
||||||
pcm->mmap_info_count = slave->pcm->mmap_info_count + 1;
|
count = slave->pcm->mmap_info_count;
|
||||||
pcm->mmap_info = malloc(pcm->mmap_info_count * sizeof(*pcm->mmap_info));
|
i = malloc((count + 1) * sizeof(*i));
|
||||||
if (!pcm->mmap_info)
|
if (!i)
|
||||||
return -ENOMEM;
|
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->type = SND_PCM_MMAP_USER;
|
||||||
i->size = snd_pcm_frames_to_bytes(pcm, pcm->setup.buffer_size);
|
i->size = snd_pcm_frames_to_bytes(pcm, pcm->setup.buffer_size);
|
||||||
share->stopped_data = malloc(i->size);
|
i->u.user.shmid = shmget(IPC_PRIVATE, i->size, 0666);
|
||||||
if (share->stopped_data == 0) {
|
if (i->u.user.shmid < 0) {
|
||||||
free(pcm->mmap_info);
|
SYSERR("shmget failed");
|
||||||
pcm->mmap_info = 0;
|
free(i);
|
||||||
return -ENOMEM;
|
return -errno;
|
||||||
}
|
}
|
||||||
i->addr = share->stopped_data;
|
i->addr = shmat(i->u.user.shmid, 0, 0);
|
||||||
|
if (i->addr == (void*) -1) {
|
||||||
|
SYSERR("shmat failed");
|
||||||
|
free(i);
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -418,10 +431,17 @@ static int snd_pcm_share_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&slave->mutex);
|
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;
|
pcm->mmap_info_count = 0;
|
||||||
|
free(pcm->mmap_info);
|
||||||
pcm->mmap_info = 0;
|
pcm->mmap_info = 0;
|
||||||
free(share->stopped_data);
|
|
||||||
return 0;
|
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);
|
ERR("Invalid client channel in binding: %s", n->id);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if ((unsigned)cchannel > channels_count)
|
if ((unsigned)cchannel >= channels_count)
|
||||||
channels_count = cchannel + 1;
|
channels_count = cchannel + 1;
|
||||||
}
|
}
|
||||||
if (channels_count == 0) {
|
if (channels_count == 0) {
|
||||||
|
|
|
||||||
|
|
@ -416,14 +416,16 @@ static int snd_pcm_shm_munmap(snd_pcm_t *pcm)
|
||||||
snd_pcm_mmap_info_t *i = &pcm->mmap_info[k];
|
snd_pcm_mmap_info_t *i = &pcm->mmap_info[k];
|
||||||
if (i->type == SND_PCM_MMAP_KERNEL) {
|
if (i->type == SND_PCM_MMAP_KERNEL) {
|
||||||
err = munmap(i->addr, i->size);
|
err = munmap(i->addr, i->size);
|
||||||
if (err < 0)
|
if (err < 0) {
|
||||||
SYSERR("munmap failed");
|
SYSERR("munmap failed");
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
err = shmdt(i->addr);
|
err = shmdt(i->addr);
|
||||||
if (err < 0)
|
if (err < 0) {
|
||||||
SYSERR("shmdt failed");
|
SYSERR("shmdt failed");
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pcm->mmap_info_count = 0;
|
pcm->mmap_info_count = 0;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue