1/* 2 * IPC SHM area manager 3 * Copyright (c) 2003 by Jaroslav Kysela <perex@perex.cz> 4 * 5 * This library is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU Lesser General Public License as 7 * published by the Free Software Foundation; either version 2.1 of 8 * the License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 * 19 */ 20 21/** 22 * \file shmarea.c 23 * \ingroup Global 24 * \brief shared memory helpers 25 * \author Jaroslav Kysela <perex@perex.cz> 26 * \date 2001 27 * 28 * Shared memory helpers 29 */ 30 31#include "config.h" 32 33/* These funcs are only used by pcm_mmap when sys/shm.h is available. */ 34#ifdef HAVE_SYS_SHM_H 35 36#include <stdio.h> 37#include <stdlib.h> 38#if HAVE_MALLOC_H 39#include <malloc.h> 40#endif 41#include <string.h> 42#include <errno.h> 43#include <poll.h> 44#include <sys/mman.h> 45#include <sys/shm.h> 46#include "list.h" 47 48#ifndef DOC_HIDDEN 49struct snd_shm_area { 50 struct list_head list; 51 int shmid; 52 void *ptr; 53 int share; 54}; 55#endif 56 57static LIST_HEAD(shm_areas); 58 59/** 60 * \brief Create a shm area record 61 * \param shmid IPC SHM ID 62 * \param ptr the shared area pointer 63 * \return The allocated shm area record, NULL if fail 64 * 65 * Allocates a shared area record with the given SHM ID and pointer. 66 * The record has a reference counter, which is initialized to 1 by this function. 67 */ 68struct snd_shm_area *snd_shm_area_create(int shmid, void *ptr) 69{ 70 struct snd_shm_area *area = malloc(sizeof(*area)); 71 if (area) { 72 area->shmid = shmid; 73 area->ptr = ptr; 74 area->share = 1; 75 list_add_tail(&area->list, &shm_areas); 76 } 77 return area; 78} 79 80/** 81 * \brief Increase the reference counter of shm area record 82 * \param area shm area record 83 * \return the shm area record (identical with the argument) 84 * 85 * Increases the reference counter of the given shared area record. 86 */ 87struct snd_shm_area *snd_shm_area_share(struct snd_shm_area *area) 88{ 89 if (area == NULL) 90 return NULL; 91 area->share++; 92 return area; 93} 94 95/** 96 * \brief Release the shared area record 97 * \param area the shared are record 98 * \return 0 if successful, or a negative error code 99 * 100 * Decreases the reference counter of the given shared area record, and 101 * releases the resources automaticall if it reaches to 0. 102 */ 103int snd_shm_area_destroy(struct snd_shm_area *area) 104{ 105 if (area == NULL) 106 return -ENOENT; 107 if (--area->share) 108 return 0; 109 list_del(&area->list); 110 shmdt(area->ptr); 111 free(area); 112 return 0; 113} 114 115#ifndef DOC_HIDDEN 116void snd_shm_area_destructor(void) __attribute__ ((destructor)); 117 118void snd_shm_area_destructor(void) 119{ 120 struct list_head *pos; 121 struct snd_shm_area *area; 122 123 list_for_each(pos, &shm_areas) { 124 area = list_entry(pos, struct snd_shm_area, list); 125 shmdt(area->ptr); 126 } 127} 128#endif /* DOC_HIDDEN */ 129 130#endif 131