xref: /trunk/main/sal/osl/unx/semaphor.c (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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