xref: /AOO41X/main/sal/osl/unx/semaphor.c (revision 647f063d49501903f1667b75f5634541fc603283)
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