OSDN Git Service

Add MS7619SE
[uclinux-h8/uClinux-dist.git] / lib / osip2 / 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
31 #if !defined(__VXWORKS_OS__) && !defined(__PSOS__) && \
32         !defined(WIN32) && !defined(_WIN32_WCE) && !defined(HAVE_PTHREAD_WIN32) && \
33     !defined(HAVE_PTHREAD) && !defined(HAVE_PTH_PTHREAD_H)
34 #error No thread implementation found!
35 #endif
36
37 #if defined(HAVE_PTHREAD) || defined(HAVE_PTH_PTHREAD_H) || defined(HAVE_PTHREAD_WIN32)
38
39 struct osip_mutex *
40 osip_mutex_init ()
41 {
42   osip_mutex_t *mut = (osip_mutex_t *) osip_malloc (sizeof (osip_mutex_t));
43
44   if (mut == NULL)
45     return NULL;
46   pthread_mutex_init (mut, NULL);
47   return (struct osip_mutex *) mut;
48 }
49
50 void
51 osip_mutex_destroy (struct osip_mutex *_mut)
52 {
53   osip_mutex_t *mut = (osip_mutex_t *) _mut;
54   if (mut == NULL)
55     return;
56   pthread_mutex_destroy (mut);
57   osip_free (mut);
58 }
59
60 int
61 osip_mutex_lock (struct osip_mutex *_mut)
62 {
63   osip_mutex_t *mut = (osip_mutex_t *) _mut;
64   if (mut == NULL)
65     return -1;
66   return pthread_mutex_lock (mut);
67 }
68
69 int
70 osip_mutex_unlock (struct osip_mutex *_mut)
71 {
72   osip_mutex_t *mut = (osip_mutex_t *) _mut;
73   if (mut == NULL)
74     return -1;
75   return pthread_mutex_unlock (mut);
76 }
77
78 #endif
79
80 #if (defined(HAVE_SEMAPHORE_H) && !defined(__APPLE_CC__)) || defined(HAVE_PTHREAD_WIN32)
81
82 /* Counting Semaphore is initialized to value */
83 struct osip_sem *
84 osip_sem_init (unsigned int value)
85 {
86   osip_sem_t *sem = (osip_sem_t *) osip_malloc (sizeof (osip_sem_t));
87   if (sem == NULL)
88     return NULL;
89
90   if (sem_init (sem, 0, value) == 0)
91     return (struct osip_sem *) sem;
92   osip_free (sem);
93   return NULL;
94 }
95
96 int
97 osip_sem_destroy (struct osip_sem *_sem)
98 {
99   osip_sem_t *sem = (osip_sem_t *) _sem;
100   if (sem == NULL)
101     return 0;
102   sem_destroy (sem);
103   osip_free (sem);
104   return 0;
105 }
106
107 int
108 osip_sem_post (struct osip_sem *_sem)
109 {
110   osip_sem_t *sem = (osip_sem_t *) _sem;
111   if (sem == NULL)
112     return -1;
113   return sem_post (sem);
114 }
115
116 int
117 osip_sem_wait (struct osip_sem *_sem)
118 {
119   osip_sem_t *sem = (osip_sem_t *) _sem;
120   if (sem == NULL)
121     return -1;
122   return sem_wait (sem);
123 }
124
125 int
126 osip_sem_trywait (struct osip_sem *_sem)
127 {
128   osip_sem_t *sem = (osip_sem_t *) _sem;
129   if (sem == NULL)
130     return -1;
131   return sem_trywait (sem);
132 }
133
134 #elif defined (HAVE_SYS_SEM_H)
135 /* support for semctl, semop, semget */
136
137 #define SEM_PERM 0600
138
139 struct osip_sem *
140 osip_sem_init (unsigned int value)
141 {
142   union semun val;
143   int i;
144   osip_sem_t *sem = (osip_sem_t *) osip_malloc (sizeof (osip_sem_t));
145
146   if (sem == NULL)
147     return NULL;
148
149   sem->semid = semget (IPC_PRIVATE, 1, IPC_CREAT | SEM_PERM);
150   if (sem->semid == -1)
151     {
152       perror ("semget error");
153       osip_free (sem);
154       return NULL;
155     }
156   val.val = (int) value;
157   i = semctl (sem->semid, 0, SETVAL, val);
158   if (i != 0)
159     {
160       perror ("semctl error");
161       osip_free (sem);
162       return NULL;
163     }
164   return (struct osip_sem *) sem;
165 }
166
167 int
168 osip_sem_destroy (struct osip_sem *_sem)
169 {
170   union semun val;
171   osip_sem_t *sem = (osip_sem_t *) _sem;
172   if (sem == NULL)
173     return 0;
174   val.val = 0;
175   semctl (sem->semid, 0, IPC_RMID, val);
176   osip_free (sem);
177   return 0;
178 }
179
180 int
181 osip_sem_post (struct osip_sem *_sem)
182 {
183   struct sembuf sb;
184   osip_sem_t *sem = (osip_sem_t *) _sem;
185
186   if (sem == NULL)
187     return -1;
188   sb.sem_num = 0;
189   sb.sem_op = 1;
190   sb.sem_flg = 0;
191   return semop (sem->semid, &sb, 1);
192 }
193
194 int
195 osip_sem_wait (struct osip_sem *_sem)
196 {
197   struct sembuf sb;
198   osip_sem_t *sem = (osip_sem_t *) _sem;
199
200   if (sem == NULL)
201     return -1;
202   sb.sem_num = 0;
203   sb.sem_op = -1;
204   sb.sem_flg = 0;
205   return semop (sem->semid, &sb, 1);
206 }
207
208 int
209 osip_sem_trywait (struct osip_sem *_sem)
210 {
211   struct sembuf sb;
212   osip_sem_t *sem = (osip_sem_t *) _sem;
213
214   if (sem == NULL)
215     return -1;
216   sb.sem_num = 0;
217   sb.sem_op = -1;
218   sb.sem_flg = IPC_NOWAIT;
219   return semop (sem->semid, &sb, 1);
220 }
221
222 #endif
223
224
225 /* use VxWorks implementation */
226 #ifdef __VXWORKS_OS__
227
228 struct osip_mutex *
229 osip_mutex_init ()
230 {
231   return (struct osip_mutex *) semMCreate (SEM_Q_FIFO|SEM_DELETE_SAFE);
232 }
233
234 void
235 osip_mutex_destroy (struct osip_mutex *_mut)
236 {
237   osip_mutex_t *mut = (osip_mutex_t *) _mut;
238   if (mut == NULL)
239     return;
240   semDelete (mut);
241 }
242
243 int
244 osip_mutex_lock (struct osip_mutex *_mut)
245 {
246   osip_mutex_t *mut = (osip_mutex_t *) _mut;
247   if (mut == NULL)
248     return -1;
249   return semTake (mut, WAIT_FOREVER);
250 }
251
252 int
253 osip_mutex_unlock (struct osip_mutex *_mut)
254 {
255   osip_mutex_t *mut = (osip_mutex_t *) _mut;
256   if (mut == NULL)
257     return -1;
258   return semGive (mut);
259 }
260
261 struct osip_sem *
262 osip_sem_init (unsigned int value)
263 {
264   SEM_ID initsem;
265   osip_sem_t *x;
266
267   x = (osip_sem_t *) osip_malloc (sizeof (osip_sem_t));
268   if (x == NULL)
269     return NULL;
270   initsem = semCCreate (SEM_Q_FIFO, value);
271   x->semId = initsem;
272   x->refCnt = value;
273   x->sem_name = NULL;
274   return (struct osip_sem *) x;
275 }
276
277 int
278 osip_sem_destroy (struct osip_sem *_sem)
279 {
280   osip_sem_t *sem = (osip_sem_t *) _sem;
281   if (sem == NULL)
282     return 0;
283   semDelete (sem->semId);
284   osip_free (sem);
285   return 0;
286 }
287
288 int
289 osip_sem_post (struct osip_sem *_sem)
290 {
291   osip_sem_t *sem = (osip_sem_t *) _sem;
292   if (sem == NULL)
293     return -1;
294   return semGive (sem->semId);
295 }
296
297 int
298 osip_sem_wait (struct osip_sem *_sem)
299 {
300   osip_sem_t *sem = (osip_sem_t *) _sem;
301   if (sem == NULL)
302     return -1;
303   return semTake (sem->semId, WAIT_FOREVER);
304 }
305
306 int
307 osip_sem_trywait (struct osip_sem *_sem)
308 {
309   osip_sem_t *sem = (osip_sem_t *) _sem;
310   if (sem == NULL)
311     return -1;
312   return semTake (sem->semId, NO_WAIT);
313 }
314
315 #endif
316
317
318 #if (defined(WIN32) || defined(_WIN32_WCE)) && !defined(HAVE_PTHREAD_WIN32)
319
320 #include <limits.h>
321
322 struct osip_mutex *
323 osip_mutex_init ()
324 {
325   osip_mutex_t *mut = (osip_mutex_t *) osip_malloc (sizeof (osip_mutex_t));
326   if (mut == NULL)
327     return NULL;
328   if ((mut->h = CreateMutex (NULL, FALSE, NULL)) != NULL)
329     return (struct osip_mutex *) (mut);
330   osip_free (mut);
331   return (NULL);
332 }
333
334 void
335 osip_mutex_destroy (struct osip_mutex *_mut)
336 {
337   osip_mutex_t *mut = (osip_mutex_t *) _mut;
338   if (mut == NULL)
339     return;
340   CloseHandle (mut->h);
341   osip_free (mut);
342 }
343
344 int
345 osip_mutex_lock (struct osip_mutex *_mut)
346 {
347   DWORD err;
348   osip_mutex_t *mut = (osip_mutex_t *) _mut;
349
350   if (mut == NULL)
351     return -1;
352   if ((err = WaitForSingleObject (mut->h, INFINITE)) == WAIT_OBJECT_0)
353     return (0);
354   return (EBUSY);
355 }
356
357 int
358 osip_mutex_unlock (struct osip_mutex *_mut)
359 {
360   osip_mutex_t *mut = (osip_mutex_t *) _mut;
361   if (mut == NULL)
362     return -1;
363   ReleaseMutex (mut->h);
364   return (0);
365 }
366
367 struct osip_sem *
368 osip_sem_init (unsigned int value)
369 {
370   osip_sem_t *sem = (osip_sem_t *) osip_malloc (sizeof (osip_sem_t));
371   if (sem == NULL)
372     return NULL;
373
374   if ((sem->h = CreateSemaphore (NULL, value, LONG_MAX, NULL)) != NULL)
375     return (struct osip_sem *) (sem);
376   osip_free (sem);
377   return (NULL);
378 }
379
380 int
381 osip_sem_destroy (struct osip_sem *_sem)
382 {
383   osip_sem_t *sem = (osip_sem_t *) _sem;
384   if (sem == NULL)
385     return 0;
386   CloseHandle (sem->h);
387   osip_free (sem);
388   return (0);
389 }
390
391 int
392 osip_sem_post (struct osip_sem *_sem)
393 {
394   osip_sem_t *sem = (osip_sem_t *) _sem;
395   if (sem == NULL)
396     return -1;
397   ReleaseSemaphore (sem->h, 1, NULL);
398   return (0);
399 }
400
401 int
402 osip_sem_wait (struct osip_sem *_sem)
403 {
404   DWORD err;
405   osip_sem_t *sem = (osip_sem_t *) _sem;
406
407   if (sem == NULL)
408     return -1;
409   if ((err = WaitForSingleObject (sem->h, INFINITE)) == WAIT_OBJECT_0)
410     return (0);
411   if (err == WAIT_TIMEOUT)
412     return (EBUSY);
413   return (EBUSY);
414 }
415
416 int
417 osip_sem_trywait (struct osip_sem *_sem)
418 {
419   DWORD err;
420   osip_sem_t *sem = (osip_sem_t *) _sem;
421
422   if (sem == NULL)
423     return -1;
424   if ((err = WaitForSingleObject (sem->h, 0)) == WAIT_OBJECT_0)
425     return (0);
426   return (EBUSY);
427 }
428 #endif
429
430 #ifdef __PSOS__
431 struct osip_mutex *
432 osip_mutex_init ()
433 {
434   osip_mutex_t *mut = (osip_mutex_t *) osip_malloc (sizeof (osip_mutex_t));
435
436   if (sm_create ("mut", 1, 0, &mut->id) == 0)
437     return (struct osip_mutex *) (mut);
438   osip_free (mut);
439   return (NULL);
440 }
441
442 void
443 osip_mutex_destroy (struct osip_mutex *_mut)
444 {
445   osip_mutex_t *mut = (osip_mutex_t *) _mut;
446   if (mut)
447     {
448       sm_delete (mut->id);
449       osip_free (mut);
450     }
451 }
452
453 int
454 osip_mutex_lock (struct osip_mutex *_mut)
455 {
456   osip_mutex_t *mut = (osip_mutex_t *) _mut;
457   if (mut)
458     {
459       if (sm_p (mut->id, SM_WAIT, 0) != 0)
460         return (-1);
461     }
462   return (0);
463 }
464
465 int
466 osip_mutex_unlock (struct osip_mutex *_mut)
467 {
468   osip_mutex_t *mut = (osip_mutex_t *) _mut;
469   if (mut)
470     {
471       sm_v (mut->id);
472     }
473
474   return (0);
475 }
476
477 struct osip_sem *
478 osip_sem_init (unsigned int value)
479 {
480   osip_sem_t *sem = (osip_sem_t *) osip_malloc (sizeof (osip_sem_t));
481
482   if (sm_create ("sem", value, 0, &sem->id) == 0)
483     return (struct osip_sem *) (sem);
484   osip_free (sem);
485   return (NULL);
486 }
487
488 int
489 osip_sem_destroy (struct osip_sem *_sem)
490 {
491   osip_sem_t *sem = (osip_sem_t *) _sem;
492   if (sem == NULL)
493     return 0;
494   sm_delete (sem->id);
495   osip_free (sem);
496   return (0);
497 }
498
499 int
500 osip_sem_post (struct osip_sem *_sem)
501 {
502   osip_sem_t *sem = (osip_sem_t *) _sem;
503   if (sem == NULL)
504     return -1;
505   return (sm_v (sem->id));
506 }
507
508 int
509 osip_sem_wait (struct osip_sem *_sem)
510 {
511   osip_sem_t *sem = (osip_sem_t *) _sem;
512   if (sem == NULL)
513     return -1;
514   if (sm_p (sem->id, SM_WAIT, 0) != 0)
515     return (-1);
516   return (0);
517 }
518
519 int
520 osip_sem_trywait (struct osip_sem *_sem)
521 {
522   osip_sem_t *sem = (osip_sem_t *) _sem;
523   if (sem == NULL)
524     return -1;
525   if (sm_p (sem->id, SM_NOWAIT, 0) != 0)
526     return (-1);
527   return (0);
528 }
529
530 #endif
531
532 #endif /* #ifdef OSIP_MT */