From: Jaroslav Kysela Date: Sat, 26 Apr 2003 08:26:05 +0000 (+0000) Subject: initial version X-Git-Tag: v1.0.3~181 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=7f8f72108c9e49b45ef98ddca4f44bcac88d04ca;p=alsa-lib.git initial version --- diff --git a/src/shmarea.c b/src/shmarea.c new file mode 100644 index 00000000..53a6533b --- /dev/null +++ b/src/shmarea.c @@ -0,0 +1,93 @@ +/* + * IPC SHM area manager + * Copyright (c) 2003 by Jaroslav Kysela + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include "list.h" + +struct snd_shm_area { + struct list_head list; + int shmid; + void *ptr; + int share; +}; + +static LIST_HEAD(shm_areas); + +struct snd_shm_area *snd_shm_area_create(int shmid, void *ptr) +{ + struct snd_shm_area *area = malloc(sizeof(*area)); + if (area) { + area->shmid = shmid; + area->ptr = ptr; + area->share = 1; + list_add_tail(&area->list, &shm_areas); + } + return area; +} + +struct snd_shm_area *snd_shm_area_share(struct snd_shm_area *area) +{ + if (area == NULL) + return NULL; + area->share++; + return area; +} + +static void _x_destroy(struct snd_shm_area *area) +{ + struct shmid_ds buf; + + shmdt(area->ptr); + if (shmctl(area->shmid, IPC_STAT, &buf) >= 0) { + if (buf.shm_nattch == 0) + shmctl(area->shmid, IPC_RMID, NULL); + } +} + +int snd_shm_area_destroy(struct snd_shm_area *area) +{ + if (area == NULL) + return -ENOENT; + if (--area->share) + return 0; + list_del(&area->list); + _x_destroy(area); + free(area); + return 0; +} + +void snd_shm_area_destructor(void) __attribute__ ((destructor)); + +void snd_shm_area_destructor(void) +{ + struct list_head *pos; + struct snd_shm_area *area; + + list_for_each(pos, &shm_areas) { + area = list_entry(pos, struct snd_shm_area, list); + _x_destroy(area); + } +}