and added files
[bcm963xx.git] / userapps / opensource / libosip2 / src / osip2 / port_sema.c
1 /*
2   The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-)
3   Copyright (C) 2001,2002,2003  Aymeric MOIZARD jack@atosc.org
4   
5   This library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9   
10   This library is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   Lesser General Public License for more details.
14   
15   You should have received a copy of the GNU Lesser General Public
16   License along with this library; if not, write to the Free Software
17   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19
20 #ifdef OSIP_MT
21
22 #include <stdlib.h>
23 #include <stdio.h>
24
25 #include <osip2/internal.h>
26
27 #include <osip2/internal.h>
28 #include <osip2/osip_mt.h>
29
30 #if !defined(__VXWORKS_OS__) && !defined(WIN32) && !defined(_WIN32_WCE) && !defined(__PSOS__)
31 #if defined(HAVE_PTHREAD) || defined(HAVE_PTH_PTHREAD_H)
32
33 struct osip_mutex *
34 osip_mutex_init ()
35 {
36   osip_mutex_t *mut = (osip_mutex_t *) osip_malloc (sizeof (osip_mutex_t));
37
38   if (mut == NULL)
39     return NULL;
40   pthread_mutex_init (mut, NULL);
41   return (struct osip_mutex *) mut;
42 }
43
44 void
45 osip_mutex_destroy (struct osip_mutex *_mut)
46 {
47   osip_mutex_t *mut = (osip_mutex_t *) _mut;
48   if (mut == NULL)
49     return;
50   pthread_mutex_destroy (mut);
51   osip_free (mut);
52 }
53
54 int
55 osip_mutex_lock (struct osip_mutex *_mut)
56 {
57   osip_mutex_t *mut = (osip_mutex_t *) _mut;
58   if (mut == NULL)
59     return -1;
60   return pthread_mutex_lock (mut);
61 }
62
63 int
64 osip_mutex_unlock (struct osip_mutex *_mut)
65 {
66   osip_mutex_t *mut = (osip_mutex_t *) _mut;
67   if (mut == NULL)
68     return -1;
69   return pthread_mutex_unlock (mut);
70 }
71
72 #else
73 #error NO thread implementation found
74 #endif
75
76 #if defined (HAVE_SEMAPHORE_H) && !defined(__APPLE_CC__)
77
78 /* Counting Semaphore is initialized to value */
79 struct osip_sem *
80 osip_sem_init (unsigned int value)
81 {
82   osip_sem_t *sem = (osip_sem_t *) osip_malloc (sizeof (osip_sem_t));
83
84   if (sem_init (sem, 0, value) == 0)
85     return (struct osip_sem *) sem;
86   osip_free (sem);
87   return NULL;
88 }
89
90 int
91 osip_sem_destroy (struct osip_sem *_sem)
92 {
93   osip_sem_t *sem = (osip_sem_t *) _sem;
94   if (sem == NULL)
95     return 0;
96   sem_destroy (sem);
97   osip_free (sem);
98   return 0;
99 }
100
101 int
102 osip_sem_post (struct osip_sem *_sem)
103 {
104   osip_sem_t *sem = (osip_sem_t *) _sem;
105   if (sem == NULL)
106     return -1;
107   return sem_post (sem);
108 }
109
110 int
111 osip_sem_wait (struct osip_sem *_sem)
112 {
113   osip_sem_t *sem = (osip_sem_t *) _sem;
114   if (sem == NULL)
115     return -1;
116   return sem_wait (sem);
117 }
118
119 int
120 osip_sem_trywait (struct osip_sem *_sem)
121 {
122   osip_sem_t *sem = (osip_sem_t *) _sem;
123   if (sem == NULL)
124     return -1;
125   return sem_trywait (sem);
126 }
127
128 #elif defined (HAVE_SYS_SEM_H)
129 /* support for semctl, semop, semget */
130
131 #define SEM_PERM 0600
132
133 struct osip_sem *
134 osip_sem_init (unsigned int value)
135 {
136   union semun val;
137   int i;
138   osip_sem_t *sem = (osip_sem_t *) osip_malloc (sizeof (osip_sem_t));
139
140   sem->semid = semget (IPC_PRIVATE, 1, IPC_CREAT | SEM_PERM);
141   if (sem->semid == -1)
142     {
143       perror ("semget error");
144       osip_free (sem);
145       return NULL;
146     }
147   val.val = (int) value;
148   i = semctl (sem->semid, 0, SETVAL, val);
149   if (i != 0)
150     {
151       perror ("semctl error");
152       osip_free (sem);
153       return NULL;
154     }
155   return (struct osip_sem *) sem;
156 }
157
158 int
159 osip_sem_destroy (struct osip_sem *_sem)
160 {
161   union semun val;
162   osip_sem_t *sem = (osip_sem_t *) _sem;
163   if (sem == NULL)
164     return 0;
165   val.val = 0;
166   semctl (sem->semid, 0, IPC_RMID, val);
167   osip_free (sem);
168   return 0;
169 }
170
171 int
172 osip_sem_post (struct osip_sem *_sem)
173 {
174   struct sembuf sb;
175   osip_sem_t *sem = (osip_sem_t *) _sem;
176
177   if (sem == NULL)
178     return -1;
179   sb.sem_num = 0;
180   sb.sem_op = 1;
181   sb.sem_flg = 0;
182   return semop (sem->semid, &sb, 1);
183 }
184
185 int
186 osip_sem_wait (struct osip_sem *_sem)
187 {
188   struct sembuf sb;
189   osip_sem_t *sem = (osip_sem_t *) _sem;
190
191   if (sem == NULL)
192     return -1;
193   sb.sem_num = 0;
194   sb.sem_op = -1;
195   sb.sem_flg = 0;
196   return semop (sem->semid, &sb, 1);
197 }
198
199 int
200 osip_sem_trywait (struct osip_sem *_sem)
201 {
202   struct sembuf sb;
203   osip_sem_t *sem = (osip_sem_t *) _sem;
204
205   if (sem == NULL)
206     return -1;
207   sb.sem_num = 0;
208   sb.sem_op = -1;
209   sb.sem_flg = IPC_NOWAIT;
210   return semop (sem->semid, &sb, 1);
211 }
212 #endif
213 #endif
214
215 /* use VxWorks implementation */
216 #ifdef __VXWORKS_OS__
217 struct osip_mutex *
218 osip_mutex_init ()
219 {
220   return (struct osip_mutex *) semMCreate (0);
221 }
222
223 void
224 osip_mutex_destroy (struct osip_mutex *_mut)
225 {
226   osip_mutex_t *mut = (osip_mutex_t *) _mut;
227   if (mut == NULL)
228     return;
229   semDelete (mut);
230 }
231
232 int
233 osip_mutex_lock (struct osip_mutex *_mut)
234 {
235   osip_mutex_t *mut = (osip_mutex_t *) mut;
236   if (mut == NULL)
237     return -1;
238   return semTake (mut, WAIT_FOREVER);
239 }
240
241 int
242 osip_mutex_unlock (struct osip_mutex *_mut)
243 {
244   osip_mutex_t *mut = (osip_mutex_t *) _mut;
245   if (mut == NULL)
246     return -1;
247   return semGive (mut);
248 }
249
250 struct osip_sem *
251 osip_sem_init (unsigned int value)
252 {
253   SEM_ID initsem;
254   osip_sem_t *x;
255
256   x = (osip_sem_t *) osip_malloc (sizeof (osip_sem_t));
257   if (x == NULL)
258     return NULL;
259   initsem = semCCreate (SEM_Q_FIFO, value);
260   x->semId = initsem;
261   x->refCnt = value;
262   x->sem_name = NULL;
263   return (struct osip_sem *) x;
264 }
265
266 int
267 osip_sem_destroy (struct osip_sem *_sem)
268 {
269   osip_sem_t *sem = (osip_sem_t *) _sem;
270   if (sem == NULL)
271     return 0;
272   semDelete (sem->semId);
273   osip_free (sem);
274   return 0;
275 }
276
277 int
278 osip_sem_post (struct osip_sem *_sem)
279 {
280   osip_sem_t *sem = (osip_sem_t *) _sem;
281   if (sem == NULL)
282     return -1;
283   return semGive (sem->semId);
284 }
285
286 int
287 osip_sem_wait (struct osip_sem *_sem)
288 {
289   osip_sem_t *sem = (osip_sem_t *) _sem;
290   if (sem == NULL)
291     return -1;
292   return semTake (sem->semId, WAIT_FOREVER);
293 }
294
295 int
296 osip_sem_trywait (struct osip_sem *_sem)
297 {
298   osip_sem_t *sem = (osip_sem_t *) _sem;
299   if (sem == NULL)
300     return -1;
301   return semTake (sem->semId, NO_WAIT);
302 }
303 #endif
304
305 #if defined (WIN32) || defined (_WIN32_WCE)
306
307 #include <limits.h>
308 struct osip_mutex *
309 osip_mutex_init ()
310 {
311   osip_mutex_t *mut = (osip_mutex_t *) osip_malloc (sizeof (osip_mutex_t));
312
313   if ((mut->h = CreateMutex (NULL, FALSE, NULL)) != NULL)
314     return (struct osip_mutex *) (mut);
315   osip_free (mut);
316   return (NULL);
317 }
318
319 void
320 osip_mutex_destroy (struct osip_mutex *_mut)
321 {
322   osip_mutex_t *mut = (osip_mutex_t *) _mut;
323   if (mut == NULL)
324     return;
325   CloseHandle (mut->h);
326   osip_free (mut);
327 }
328
329 int
330 osip_mutex_lock (struct osip_mutex *_mut)
331 {
332   DWORD err;
333   osip_mutex_t *mut = (osip_mutex_t *) _mut;
334
335   if (mut == NULL)
336     return -1;
337   if ((err = WaitForSingleObject (mut->h, INFINITE)) == WAIT_OBJECT_0)
338     return (0);
339   return (EBUSY);
340 }
341
342 int
343 osip_mutex_unlock (struct osip_mutex *_mut)
344 {
345   osip_mutex_t *mut = (osip_mutex_t *) _mut;
346   if (mut == NULL)
347     return -1;
348   ReleaseMutex (mut->h);
349   return (0);
350 }
351
352 struct osip_sem *
353 osip_sem_init (unsigned int value)
354 {
355   osip_sem_t *sem = (osip_sem_t *) osip_malloc (sizeof (osip_sem_t));
356
357   if ((sem->h = CreateSemaphore (NULL, value, LONG_MAX, NULL)) != NULL)
358     return (struct osip_sem *) (sem);
359   osip_free (sem);
360   return (NULL);
361 }
362
363 int
364 osip_sem_destroy (struct osip_sem *_sem)
365 {
366   osip_sem_t *sem = (osip_sem_t *) _sem;
367   if (sem == NULL)
368     return 0;
369   CloseHandle (sem->h);
370   osip_free (sem);
371   return (0);
372 }
373
374 int
375 osip_sem_post (struct osip_sem *_sem)
376 {
377   osip_sem_t *sem = (osip_sem_t *) _sem;
378   if (sem == NULL)
379     return -1;
380   ReleaseSemaphore (sem->h, 1, NULL);
381   return (0);
382 }
383
384 int
385 osip_sem_wait (struct osip_sem *_sem)
386 {
387   DWORD err;
388   osip_sem_t *sem = (osip_sem_t *) _sem;
389
390   if (sem == NULL)
391     return -1;
392   if ((err = WaitForSingleObject (sem->h, INFINITE)) == WAIT_OBJECT_0)
393     return (0);
394   if (err == WAIT_TIMEOUT)
395     return (EBUSY);
396   return (EBUSY);
397 }
398
399 int
400 osip_sem_trywait (struct osip_sem *_sem)
401 {
402   DWORD err;
403   osip_sem_t *sem = (osip_sem_t *) _sem;
404
405   if (sem == NULL)
406     return -1;
407   if ((err = WaitForSingleObject (sem->h, 0)) == WAIT_OBJECT_0)
408     return (0);
409   return (EBUSY);
410 }
411 #endif
412
413 #ifdef __PSOS__
414 struct osip_mutex *
415 osip_mutex_init ()
416 {
417   osip_mutex_t *mut = (osip_mutex_t *) osip_malloc (sizeof (osip_mutex_t));
418
419   if (sm_create ("mut", 1, 0, &mut->id) == 0)
420     return (struct osip_mutex *) (mut);
421   osip_free (mut);
422   return (NULL);
423 }
424
425 void
426 osip_mutex_destroy (struct osip_mutex *_mut)
427 {
428   osip_mutex_t *mut = (osip_mutex_t *) _mut;
429   if (mut)
430     {
431       sm_delete (mut->id);
432       osip_free (mut);
433     }
434 }
435
436 int
437 osip_mutex_lock (struct osip_mutex *_mut)
438 {
439   osip_mutex_t *mut = (osip_mutex_t *) _mut;
440   if (mut)
441     {
442       if (sm_p (mut->id, SM_WAIT, 0) != 0)
443         return (-1);
444     }
445   return (0);
446 }
447
448 int
449 osip_mutex_unlock (struct osip_mutex *_mut)
450 {
451   osip_mutex_t *mut = (osip_mutex_t *) _mut;
452   if (mut)
453     {
454       sm_v (mut->id);
455     }
456
457   return (0);
458 }
459
460 struct osip_sem *
461 osip_sem_init (unsigned int value)
462 {
463   osip_sem_t *sem = (osip_sem_t *) osip_malloc (sizeof (osip_sem_t));
464
465   if (sm_create ("sem", value, 0, &sem->id) == 0)
466     return (struct osip_sem *) (sem);
467   osip_free (sem);
468   return (NULL);
469 }
470
471 int
472 osip_sem_destroy (struct osip_sem *_sem)
473 {
474   osip_sem_t *sem = (osip_sem_t *) _sem;
475   if (sem == NULL)
476     return 0;
477   sm_delete (sem->id);
478   osip_free (sem);
479   return (0);
480 }
481
482 int
483 osip_sem_post (struct osip_sem *_sem)
484 {
485   osip_sem_t *sem = (osip_sem_t *) _sem;
486   if (sem == NULL)
487     return -1;
488   return (sm_v (sem->id));
489 }
490
491 int
492 osip_sem_wait (struct osip_sem *_sem)
493 {
494   osip_sem_t *sem = (osip_sem_t *) _sem;
495   if (sem == NULL)
496     return -1;
497   if (sm_p (sem->id, SM_WAIT, 0) != 0)
498     return (-1);
499   return (0);
500 }
501
502 int
503 osip_sem_trywait (struct osip_sem *_sem)
504 {
505   osip_sem_t *sem = (osip_sem_t *) _sem;
506   if (sem == NULL)
507     return -1;
508   if (sm_p (sem->id, SM_NOWAIT, 0) != 0)
509     return (-1);
510   return (0);
511 }
512 #endif
513
514 #endif