xref: /aoo41x/main/sal/osl/unx/semaphor.c (revision 647f063d)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 
25 #include "system.h"
26 
27 #include <osl/semaphor.h>
28 #include <osl/diagnose.h>
29 
30 #ifndef OSL_USE_SYS_V_SEMAPHORE
31 
32 /* This is the (default) POSIX thread-local semaphore variant */
33 
34 /*
35 	Implemetation notes:
36 	The void* represented by oslSemaphore is used
37 	as a pointer to an sem_t struct
38 */
39 
40 /*****************************************************************************/
41 /* osl_createSemaphore  */
42 /*****************************************************************************/
43 
osl_createSemaphore(sal_uInt32 initialCount)44 oslSemaphore SAL_CALL osl_createSemaphore(sal_uInt32 initialCount)
45 {
46 	int ret = 0;
47 	oslSemaphore Semaphore;
48 
49 	Semaphore= malloc(sizeof(sem_t));
50 
51 	OSL_ASSERT(Semaphore);		/* ptr valid? */
52 
53 	if ( Semaphore == 0 )
54 	{
55 		return 0;
56 	}
57 
58 	/* unnamed semaphore, not shared between processes */
59 
60    	ret= sem_init((sem_t*)Semaphore, 0, initialCount);
61 
62 	/* create failed? */
63 	if (ret != 0)
64 	{
65 	    OSL_TRACE("osl_createSemaphore failed. Errno: %d; %s\n",
66 				  errno,
67 				  strerror(errno));
68 
69 	    free(Semaphore);
70 	    Semaphore = NULL;
71 	}
72 
73 	return Semaphore;
74 }
75 
76 /*****************************************************************************/
77 /* osl_destroySemaphore  */
78 /*****************************************************************************/
osl_destroySemaphore(oslSemaphore Semaphore)79 void SAL_CALL osl_destroySemaphore(oslSemaphore Semaphore)
80 {
81 	if(Semaphore)			/* ptr valid? */
82 	{
83 		sem_destroy((sem_t*)Semaphore);
84 	    free(Semaphore);
85 	}
86 }
87 
88 /*****************************************************************************/
89 /* osl_acquireSemaphore  */
90 /*****************************************************************************/
osl_acquireSemaphore(oslSemaphore Semaphore)91 sal_Bool SAL_CALL osl_acquireSemaphore(oslSemaphore Semaphore) {
92 
93 	OSL_ASSERT(Semaphore != 0);	/* abort in debug mode */
94 
95 	if (Semaphore != 0)		/* be tolerant in release mode */
96 	{
97 	    return (sem_wait((sem_t*)Semaphore) == 0);
98 	}
99 
100 	return sal_False;
101 }
102 
103 /*****************************************************************************/
104 /* osl_tryToAcquireSemaphore  */
105 /*****************************************************************************/
osl_tryToAcquireSemaphore(oslSemaphore Semaphore)106 sal_Bool SAL_CALL osl_tryToAcquireSemaphore(oslSemaphore Semaphore) {
107 
108 	OSL_ASSERT(Semaphore != 0);	/* abort in debug mode */
109 	if (Semaphore != 0)		/* be tolerant in release mode */
110 	{
111 	    return (sem_trywait((sem_t*)Semaphore) == 0);
112 	}
113 
114 	return sal_False;
115 }
116 
117 /*****************************************************************************/
118 /* osl_releaseSemaphore  */
119 /*****************************************************************************/
osl_releaseSemaphore(oslSemaphore Semaphore)120 sal_Bool SAL_CALL osl_releaseSemaphore(oslSemaphore Semaphore) {
121 
122 	OSL_ASSERT(Semaphore != 0);		/* abort in debug mode */
123 
124 	if (Semaphore != 0)			/* be tolerant in release mode */
125 	{
126 	    return (sem_post((sem_t*)Semaphore) == 0);
127 	}
128 
129 	return sal_False;
130 }
131 
132 #else /* OSL_USE_SYS_V_SEMAPHORE */
133 
134 /*******************************************************************************/
135 
136 /* This is the SYS V private semaphore variant */
137 
138 /*
139 	Implemetation notes:
140 	The void* represented by oslSemaphore is used
141 	as a pointer to an osl_TSemImpl struct
142 */
143 
144 
145 #if defined(NETBSD)
146 union semun {
147         int     val;            /* value for SETVAL */
148         struct  semid_ds *buf;  /* buffer for IPC_STAT & IPC_SET */
149         u_short *array;         /* array for GETALL & SETALL */
150 };
151 #endif
152 
153 typedef struct _osl_TSemImpl
154 {
155   int m_Id;
156 
157 } osl_TSemImpl;
158 
159 /*****************************************************************************/
160 /* osl_createSemaphore  */
161 /*****************************************************************************/
osl_createSemaphore(sal_uInt32 initialCount)162 oslSemaphore SAL_CALL osl_createSemaphore(sal_uInt32 initialCount)
163 {
164 	union semun arg;
165 
166 	oslSemaphore Semaphore;
167 	osl_TSemImpl* pSem;
168 
169 	Semaphore= malloc(sizeof(osl_TSemImpl));
170 	OSL_POSTCOND(Semaphore, "malloc failed\n");		/* ptr valid? */
171 
172 	pSem= (osl_TSemImpl*)Semaphore;
173 
174 
175 	/* unnamed (private) semaphore */
176 
177    	pSem->m_Id= semget(IPC_PRIVATE, 1, 0666 | IPC_CREAT);
178 
179 
180 	/* create failed? */
181 	if (pSem->m_Id < 0)
182 	{
183 	    OSL_TRACE("osl_createSemaphore failed (semget). Errno: %d; %s\n",
184 			   errno,
185 			   strerror(errno));
186 
187 	    free(Semaphore);
188 	    return 0;
189 	}
190 
191     /* set initial count */
192 
193     arg.val= initialCount;
194 
195 	if(semctl(pSem->m_Id, 0, SETVAL, arg) < 0)
196 	{
197 	    OSL_TRACE("osl_createSemaphore failed (semctl(SETVAL)). Errno: %d; %s\n",
198 			   errno,
199 			   strerror(errno));
200 
201 		if(semctl(pSem->m_Id, 0, IPC_RMID, arg) < 0)
202 		{
203 		    OSL_TRACE("semctl(IPC_RMID) failed. Errno: %d; %s\n", errno, strerror(errno));
204 	    }
205 
206 		free(Semaphore);
207 		return 0;
208 	}
209 
210 
211 	return Semaphore;
212 }
213 
214 /*****************************************************************************/
215 /* osl_destroySemaphore  */
216 /*****************************************************************************/
osl_destroySemaphore(oslSemaphore Semaphore)217 void SAL_CALL osl_destroySemaphore(oslSemaphore Semaphore) {
218 
219 	if(Semaphore)			/* ptr valid? */
220 	{
221 		union semun arg;
222 
223 	    osl_TSemImpl* pSem= (osl_TSemImpl*)Semaphore;
224 
225 		if(semctl(pSem->m_Id, 0, IPC_RMID, arg) < 0)
226 
227 		{
228 		    OSL_TRACE("osl_destroySemaphore failed. (semctl(IPC_RMID)). Errno: %d; %s\n",
229 				   errno,
230 				   strerror(errno));
231 	    }
232 
233 	    free(Semaphore);
234 	}
235 }
236 
237 /*****************************************************************************/
238 /* osl_acquireSemaphore  */
239 /*****************************************************************************/
osl_acquireSemaphore(oslSemaphore Semaphore)240 sal_Bool SAL_CALL osl_acquireSemaphore(oslSemaphore Semaphore) {
241 
242 	/* abort in debug mode */
243 	OSL_PRECOND(Semaphore != 0, "Semaphore not created\n");
244 
245 
246 	if (Semaphore != 0)		/* be tolerant in release mode */
247 	{
248 	    struct sembuf op;
249 		osl_TSemImpl* pSem= (osl_TSemImpl*)Semaphore;
250 
251 		op.sem_num= 0;
252 		op.sem_op= -1;
253 		op.sem_flg= SEM_UNDO;
254 
255 		return semop(pSem->m_Id, &op, 1) >= 0;
256 
257 	}
258 
259 	return sal_False;
260 }
261 
262 /*****************************************************************************/
263 /* osl_tryToAcquireSemaphore  */
264 /*****************************************************************************/
osl_tryToAcquireSemaphore(oslSemaphore Semaphore)265 sal_Bool SAL_CALL osl_tryToAcquireSemaphore(oslSemaphore Semaphore) {
266 
267 	/* abort in debug mode */
268 	OSL_PRECOND(Semaphore != 0, "Semaphore not created\n");
269 
270 	if (Semaphore != 0)		/* be tolerant in release mode */
271 	{
272 	    struct sembuf op;
273 		osl_TSemImpl* pSem= (osl_TSemImpl*)Semaphore;
274 
275 		op.sem_num= 0;
276 		op.sem_op= -1;
277 		op.sem_flg= SEM_UNDO | IPC_NOWAIT;
278 
279 		return semop(pSem->m_Id, &op, 1) >= 0;
280 	}
281 
282 	return sal_False;
283 }
284 
285 /*****************************************************************************/
286 /* osl_releaseSemaphore  */
287 /*****************************************************************************/
osl_releaseSemaphore(oslSemaphore Semaphore)288 sal_Bool SAL_CALL osl_releaseSemaphore(oslSemaphore Semaphore)
289 {
290 
291 	/* abort in debug mode */
292 	OSL_PRECOND(Semaphore != 0, "Semaphore not created\n");
293 
294 	if (Semaphore != 0)			/* be tolerant in release mode */
295 	{
296 	    struct sembuf op;
297 		osl_TSemImpl* pSem= (osl_TSemImpl*)Semaphore;
298 
299 		op.sem_num= 0;
300 		op.sem_op= 1;
301 		op.sem_flg= SEM_UNDO;
302 
303 		return semop(pSem->m_Id, &op, 1) >= 0;
304 	}
305 
306 	return sal_False;
307 }
308 
309 #endif /* OSL_USE_SYS_V_SEMAPHORE */
310 
311