1b8755146c9cd069e43eb80c1bf182b7ab373b64
[sip-router] / locking.h
1 /* $Id$ */
2 /*
3  *
4  * Copyright (C) 2001-2003 Fhg Fokus
5  *
6  * This file is part of ser, a free SIP server.
7  *
8  * ser is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version
12  *
13  * For a license to use the ser software under conditions
14  * other than those described here, or to purchase support for this
15  * software, please contact iptel.org by e-mail at the following addresses:
16  *    info@iptel.org
17  *
18  * ser is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License 
24  * along with this program; if not, write to the Free Software 
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  */
27
28 /*
29  *   ser locking library
30  *
31  *  2002-12-16 created by andrei
32  *
33  *
34 Implements:
35
36         lock_t* lock_alloc();                    - allocates a lock in shared mem.
37         lock_t* lock_init(lock_t* lock);         - inits the lock
38         void    lock_destroy(lock_t* lock);      - removes the lock (e.g sysv rmid)
39         void    lock_dealloc(lock_t* lock);      - deallocates the lock's shared m.
40         void    lock_get(lock_t* lock);          - lock (mutex down)
41         void    lock_release(lock_t* lock);      - unlock (mutex up)
42 */
43
44 #ifndef _locking_h
45 #define _locking_h
46
47 #include "mem/mem.h"
48 #ifdef SHM_MEM
49 #include "mem/shm_mem.h"
50 #else
51 #error "locking requires shared memroy support"
52 #endif
53
54 #ifdef FAST_LOCK
55 #include "fastlock.h"
56
57 typedef fl_lock_t lock_t;
58
59 #define lock_alloc() shm_malloc(sizeof(lock_t))
60 #define lock_destroy(lock) /* do nothing */ 
61 #define lock_dealloc(lock) shm_free(lock)
62
63 inline static lock_t* lock_init(lock_t* lock)
64 {
65         init_lock(*lock);
66         return lock;
67 }
68
69 #define lock_get(lock) get_lock(lock)
70 #define lock_release(lock) release_lock(lock)
71
72
73
74 #elif defined USE_PTHREAD_MUTEX
75 #include <pthread.h>
76
77 typedef pthread_mutex_t lock_t;
78
79 #define lock_alloc() shm_malloc(sizeof(lock_t))
80 #define lock_destroy(lock) /* do nothing */ 
81 #define lock_dealloc(lock) shm_free(lock)
82
83 inline static lock_t* lock_init(lock_t* lock)
84 {
85         if (pthread_mutex_init(lock, 0)==0) return lock;
86         else return 0;
87 }
88
89 #define lock_get(lock) pthread_mutex_lock(lock)
90 #define lock_release(lock) pthread_mutex_unlock(lock)
91
92
93
94 #elif defined USE_POSIX_SEM
95 #include <semaphore.h>
96
97 typedef sem_t lock_t;
98
99 #define lock_alloc() shm_malloc(sizeof(lock_t))
100 #define lock_destroy(lock) /* do nothing */ 
101 #define lock_dealloc(lock) shm_free(lock)
102
103 inline static lock_t* lock_init(lock_t* lock)
104 {
105         if (sem_init(lock, 1, 1)<0) return 0;
106         return lock;
107 }
108
109 #define lock_get(lock) sem_wait(lock)
110 #define lock_release(lock) sem_post(lock)
111
112
113 #elif defined USE_SYSV_SEM
114 #include <sys/ipc.h>
115 #include <sys/sem.h>
116
117 #if ((defined(HAVE_UNION_SEMUN) || defined(__GNU_LIBRARY__) )&& !defined(_SEM_SEMUN_UNDEFINED)) 
118         
119         /* union semun is defined by including sem.h */
120 #else
121         /* according to X/OPEN we have to define it ourselves */
122         union semun {
123                 int val;                      /* value for SETVAL */
124                 struct semid_ds *buf;         /* buffer for IPC_STAT, IPC_SET */
125                 unsigned short int *array;    /* array for GETALL, SETALL */
126                 struct seminfo *__buf;        /* buffer for IPC_INFO */
127         };
128 #endif
129
130 typedef int lock_t;
131
132 #define lock_alloc() shm_malloc(sizeof(lock_t))
133 #define lock_dealloc(lock) shm_free(lock)
134
135
136 inline static lock_t* lock_init(lock_t* lock)
137 {
138         union semun su;
139         
140         *lock=semget(IPC_PRIVATE, 1, 0700);
141         if (*lock==-1) return 0;
142         su.val=1;
143         if (semctl(*lock, 0, SETVAL, su)==-1){
144                 /* init error*/
145                 return 0;
146         }
147         return lock;
148 }
149
150 inline static void lock_destroy(lock_t* lock)
151 {
152         semctl(*lock, 0, IPC_RMID, (union semun)(int)0);
153 }
154
155 #define lock_dealloc(lock) shm_free(lock)
156
157 inline static void lock_get(lock_t* lock)
158 {
159         struct sembuf sop;
160
161         sop.sem_num=0;
162         sop.sem_op=-1; /* down */
163         sop.sem_flg=0; /*SEM_UNDO*/
164         semop(*lock, &sop, 1);
165 }
166
167 inline static void lock_release(lock_t* lock)
168 {
169         struct sembuf sop;
170         
171         sop.sem_num=0;
172         sop.sem_op=1; /* up */
173         sop.sem_flg=0; /* SEM_UNDO*/
174         semop(*lock, &sop, 1);
175 }
176
177 #else
178 #error "no locking method selected"
179 #endif
180
181
182
183 #endif