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