Cleanups in IPC stuff.

Cleanups in snd_pcm_close().
Added initial code for dmix plugin:
  - only skeleton, but all major problems should be solved
This commit is contained in:
Jaroslav Kysela 2003-02-04 14:48:51 +00:00
parent 74859a4646
commit 8720faaccb
10 changed files with 1132 additions and 59 deletions

View file

@ -8,7 +8,7 @@ libpcm_la_SOURCES = atomic.c mask.c interval.c \
pcm_rate.c pcm_plug.c pcm_misc.c pcm_mmap.c pcm_multi.c \
pcm_shm.c pcm_file.c pcm_null.c pcm_share.c \
pcm_meter.c pcm_hooks.c pcm_lfloat.c pcm_ladspa.c \
pcm_symbols.c
pcm_dmix.c pcm_symbols.c
noinst_HEADERS = pcm_local.h pcm_plugin.h mask.h mask_inline.h \
interval.h interval_inline.h plugin_ops.h ladspa.h

View file

@ -672,16 +672,7 @@ int snd_pcm_close(snd_pcm_t *pcm)
err = pcm->ops->close(pcm->op_arg);
if (err < 0)
return err;
if (pcm->name)
free(pcm->name);
if (pcm->hw.link_dst)
free(pcm->hw.link_dst);
if (pcm->appl.link_dst)
free(pcm->appl.link_dst);
if (pcm->dl_handle)
snd_dlclose(pcm->dl_handle);
free(pcm);
return 0;
return snd_pcm_free(pcm);
}
/**
@ -1875,6 +1866,21 @@ int snd_pcm_new(snd_pcm_t **pcmp, snd_pcm_type_t type, const char *name,
return 0;
}
int snd_pcm_free(snd_pcm_t *pcm)
{
assert(pcm);
if (pcm->name)
free(pcm->name);
if (pcm->hw.link_dst)
free(pcm->hw.link_dst);
if (pcm->appl.link_dst)
free(pcm->appl.link_dst);
if (pcm->dl_handle)
snd_dlclose(pcm->dl_handle);
free(pcm);
return 0;
}
int snd_pcm_open_slave(snd_pcm_t **pcmp, snd_config_t *root,
snd_config_t *conf, snd_pcm_stream_t stream,
int mode)
@ -5782,11 +5788,7 @@ int snd_pcm_mmap_begin(snd_pcm_t *pcm,
snd_pcm_uframes_t f;
snd_pcm_uframes_t avail;
assert(pcm && areas && offset && frames);
if (pcm->stopped_areas &&
snd_pcm_state(pcm) != SND_PCM_STATE_RUNNING)
*areas = pcm->stopped_areas;
else
*areas = pcm->running_areas;
*areas = snd_pcm_mmap_areas(pcm);
*offset = *pcm->appl.ptr % pcm->buffer_size;
cont = pcm->buffer_size - *offset;
f = *frames;

1086
src/pcm/pcm_dmix.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -111,6 +111,7 @@ typedef struct _snd_pcm_channel_info {
union {
struct {
int shmid;
int remove;
} shm;
struct {
int fd;
@ -214,6 +215,7 @@ struct _snd_pcm {
int snd_pcm_new(snd_pcm_t **pcmp, snd_pcm_type_t type, const char *name,
snd_pcm_stream_t stream, int mode);
int snd_pcm_free(snd_pcm_t *pcm);
void snd_pcm_areas_from_buf(snd_pcm_t *pcm, snd_pcm_channel_area_t *areas, void *buf);
void snd_pcm_areas_from_bufs(snd_pcm_t *pcm, snd_pcm_channel_area_t *areas, void **bufs);
@ -709,6 +711,8 @@ int snd_pcm_open_slave(snd_pcm_t **pcmp, snd_config_t *root,
int mode);
int snd_pcm_conf_generic_id(const char *id);
int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, const char *name, int fd, int mmap_emulation);
#define SND_PCM_HW_PARBIT_ACCESS (1U << SND_PCM_HW_PARAM_ACCESS)
#define SND_PCM_HW_PARBIT_FORMAT (1U << SND_PCM_HW_PARAM_FORMAT)
#define SND_PCM_HW_PARBIT_SUBFORMAT (1U << SND_PCM_HW_PARAM_SUBFORMAT)

View file

@ -282,6 +282,7 @@ int snd_pcm_channel_info_shm(snd_pcm_t *pcm, snd_pcm_channel_info_t *info,
info->addr = 0;
info->type = SND_PCM_AREA_SHM;
info->u.shm.shmid = shmid;
info->u.shm.remove = 0;
return 0;
}
@ -361,6 +362,7 @@ int snd_pcm_mmap(snd_pcm_t *pcm)
return -errno;
}
i->u.shm.shmid = id;
i->u.shm.remove = 1;
}
ptr = shmat(i->u.shm.shmid, 0, 0);
if (ptr == (void*) -1) {
@ -438,6 +440,14 @@ int snd_pcm_munmap(snd_pcm_t *pcm)
SYSERR("shmdt failed");
return -errno;
}
if (i->u.shm.remove) {
if (shmctl(i->u.shm.shmid, IPC_RMID, 0) < 0) {
SYSERR("shmctl IPC_RMID failed");
return -errno;
}
i->u.shm.shmid = -1;
i->u.shm.remove = 0;
}
break;
default:
assert(0);

View file

@ -41,7 +41,6 @@ const char *_snd_module_pcm_null = "";
typedef struct {
snd_timestamp_t trigger_tstamp;
snd_pcm_state_t state;
int shmid;
snd_pcm_uframes_t appl_ptr;
snd_pcm_uframes_t hw_ptr;
int poll_fd;
@ -81,7 +80,7 @@ static int snd_pcm_null_info(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_info_t * i
static int snd_pcm_null_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info)
{
snd_pcm_null_t *null = pcm->private_data;
return snd_pcm_channel_info_shm(pcm, info, null->shmid);
return snd_pcm_channel_info_shm(pcm, info, -1);
}
static int snd_pcm_null_status(snd_pcm_t *pcm, snd_pcm_status_t * status)
@ -273,28 +272,13 @@ static int snd_pcm_null_sw_params(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_pa
return 0;
}
static int snd_pcm_null_mmap(snd_pcm_t *pcm)
static int snd_pcm_null_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
{
snd_pcm_null_t *null = pcm->private_data;
if (!(pcm->info & SND_PCM_INFO_MMAP)) {
size_t size = snd_pcm_frames_to_bytes(pcm, pcm->buffer_size);
int id = shmget(IPC_PRIVATE, size, 0666);
if (id < 0) {
SYSERR("shmget failed");
return -errno;
}
null->shmid = id;
}
return 0;
}
static int snd_pcm_null_munmap(snd_pcm_t *pcm)
static int snd_pcm_null_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
{
snd_pcm_null_t *null = pcm->private_data;
if (shmctl(null->shmid, IPC_RMID, 0) < 0) {
SYSERR("shmctl IPC_RMID failed");
return -errno;
}
return 0;
}

View file

@ -178,8 +178,7 @@ int snd_pcm_plugin_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
int snd_pcm_plugin_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *info)
{
snd_pcm_plugin_t *plugin = pcm->private_data;
return snd_pcm_channel_info_shm(pcm, info, plugin->shmid);
return snd_pcm_channel_info_shm(pcm, info, -1);
}
snd_pcm_state_t snd_pcm_plugin_state(snd_pcm_t *pcm)
@ -569,26 +568,13 @@ snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
}
}
int snd_pcm_plugin_mmap(snd_pcm_t *pcm)
int snd_pcm_plugin_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
{
snd_pcm_plugin_t *plug = pcm->private_data;
size_t size = snd_pcm_frames_to_bytes(pcm, (snd_pcm_sframes_t) pcm->buffer_size);
int id = shmget(IPC_PRIVATE, size, 0666);
if (id < 0) {
SYSERR("shmget failed");
return -errno;
}
plug->shmid = id;
return 0;
}
int snd_pcm_plugin_munmap(snd_pcm_t *pcm)
int snd_pcm_plugin_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
{
snd_pcm_plugin_t *plug = pcm->private_data;
if (shmctl(plug->shmid, IPC_RMID, 0) < 0) {
SYSERR("shmctl IPC_RMID failed");
return -errno;
}
return 0;
}

View file

@ -47,7 +47,6 @@ typedef struct {
snd_pcm_sframes_t (*client_frames)(snd_pcm_t *pcm, snd_pcm_sframes_t frames);
snd_pcm_sframes_t (*slave_frames)(snd_pcm_t *pcm, snd_pcm_sframes_t frames);
int (*init)(snd_pcm_t *pcm);
int shmid;
snd_pcm_uframes_t appl_ptr, hw_ptr;
snd_atomic_write_t watom;
} snd_pcm_plugin_t;

View file

@ -1322,7 +1322,7 @@ int snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, const char *sname,
}
err = socketpair(AF_LOCAL, SOCK_STREAM, 0, sd);
if (err < 0) {
free(pcm);
snd_pcm_free(pcm);
free(share->slave_channels);
free(share);
return -errno;
@ -1348,7 +1348,7 @@ int snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, const char *sname,
err = -errno;
close(sd[0]);
close(sd[1]);
free(pcm);
snd_pcm_free(pcm);
free(share->slave_channels);
free(share);
return err;
@ -1369,7 +1369,7 @@ int snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, const char *sname,
Pthread_mutex_unlock(&snd_pcm_share_slaves_mutex);
close(sd[0]);
close(sd[1]);
free(pcm);
snd_pcm_free(pcm);
free(share->slave_channels);
free(share);
return err;
@ -1382,7 +1382,7 @@ int snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, const char *sname,
snd_pcm_close(spcm);
close(sd[0]);
close(sd[1]);
free(pcm);
snd_pcm_free(pcm);
free(share->slave_channels);
free(share);
return err;
@ -1412,7 +1412,7 @@ int snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, const char *sname,
Pthread_mutex_unlock(&slave->mutex);
close(sd[0]);
close(sd[1]);
free(pcm);
snd_pcm_free(pcm);
free(share->slave_channels);
free(share);
return -EBUSY;

View file

@ -38,6 +38,7 @@ extern const char *_snd_module_pcm_share;
extern const char *_snd_module_pcm_shm;
extern const char *_snd_module_pcm_lfloat;
extern const char *_snd_module_pcm_ladspa;
extern const char *_snd_module_pcm_dmix;
static const char **snd_pcm_open_objects[] = {
&_snd_module_pcm_adpcm,
@ -57,7 +58,8 @@ static const char **snd_pcm_open_objects[] = {
&_snd_module_pcm_share,
&_snd_module_pcm_shm,
&_snd_module_pcm_lfloat,
&_snd_module_pcm_ladspa
&_snd_module_pcm_ladspa,
&_snd_module_pcm_dmix
};
void *snd_pcm_open_symbols(void)