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