• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
49 struct snd_shm_area {
50 	struct list_head list;
51 	int shmid;
52 	void *ptr;
53 	int share;
54 };
55 #endif
56 
57 static 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  */
snd_shm_area_create(int shmid,void * ptr)68 struct 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  */
snd_shm_area_share(struct snd_shm_area * area)87 struct 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  */
snd_shm_area_destroy(struct snd_shm_area * area)103 int 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
116 void snd_shm_area_destructor(void) __attribute__ ((destructor));
117 
snd_shm_area_destructor(void)118 void 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