00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 #ifndef _lock_ops_h
00066 #define _lock_ops_h
00067
00068
00069 #ifdef FAST_LOCK
00070 #include "fastlock.h"
00071
00072 typedef fl_lock_t gen_lock_t;
00073
00074
00075 #define lock_destroy(lock)
00076
00077 inline static gen_lock_t* lock_init(gen_lock_t* lock)
00078 {
00079 init_lock(*lock);
00080 return lock;
00081 }
00082
00083 #define lock_get(lock) get_lock(lock)
00084 #define lock_release(lock) release_lock(lock)
00085
00086 #elif defined USE_PTHREAD_MUTEX
00087 #include <pthread.h>
00088
00089 typedef pthread_mutex_t gen_lock_t;
00090
00091 #define lock_destroy(lock)
00092
00093 inline static gen_lock_t* lock_init(gen_lock_t* lock)
00094 {
00095 if (pthread_mutex_init(lock, 0)==0) return lock;
00096 else return 0;
00097 }
00098
00099 #define lock_get(lock) pthread_mutex_lock(lock)
00100 #define lock_release(lock) pthread_mutex_unlock(lock)
00101
00102
00103
00104 #elif defined USE_POSIX_SEM
00105 #include <semaphore.h>
00106
00107 typedef sem_t gen_lock_t;
00108
00109 #define lock_destroy(lock)
00110
00111 inline static gen_lock_t* lock_init(gen_lock_t* lock)
00112 {
00113 if (sem_init(lock, 1, 1)<0) return 0;
00114 return lock;
00115 }
00116
00117 #define lock_get(lock) sem_wait(lock)
00118 #define lock_release(lock) sem_post(lock)
00119
00120
00121 #elif defined USE_SYSV_SEM
00122 #include <sys/ipc.h>
00123 #include <sys/sem.h>
00124
00125 #include <errno.h>
00126 #include <string.h>
00127 #include <sys/types.h>
00128 #include <unistd.h>
00129 #include "dprint.h"
00130 #include "globals.h"
00131
00132 #if ((defined(HAVE_UNION_SEMUN) || defined(__GNU_LIBRARY__) )&& !defined(_SEM_SEMUN_UNDEFINED))
00133
00134
00135 #else
00136
00137 union semun {
00138 int val;
00139 struct semid_ds *buf;
00140 unsigned short int *array;
00141 struct seminfo *__buf;
00142 };
00143 #endif
00144
00145 typedef int gen_lock_t;
00146
00147
00148
00149
00150 inline static gen_lock_t* lock_init(gen_lock_t* lock)
00151 {
00152 union semun su;
00153 int euid;
00154
00155 euid=geteuid();
00156 if (uid && uid!=euid)
00157 seteuid(uid);
00158 *lock=semget(IPC_PRIVATE, 1, 0700);
00159 if (uid && uid!=euid)
00160 seteuid(euid);
00161 if (*lock==-1) return 0;
00162 su.val=1;
00163 if (semctl(*lock, 0, SETVAL, su)==-1){
00164
00165 return 0;
00166 }
00167 return lock;
00168 }
00169
00170 inline static void lock_destroy(gen_lock_t* lock)
00171 {
00172 union semun su;
00173
00174 su.val = 0;
00175 semctl(*lock, 0, IPC_RMID, su);
00176 }
00177
00178
00179 inline static void lock_get(gen_lock_t* lock)
00180 {
00181 struct sembuf sop;
00182
00183 sop.sem_num=0;
00184 sop.sem_op=-1;
00185 sop.sem_flg=0;
00186 tryagain:
00187 if (semop(*lock, &sop, 1)==-1){
00188 if (errno==EINTR){
00189 LM_DBG("signal received while waiting for on a mutex\n");
00190 goto tryagain;
00191 }else{
00192 LM_CRIT("%s (%d)\n", strerror(errno), errno);
00193 }
00194 }
00195 }
00196
00197 inline static void lock_release(gen_lock_t* lock)
00198 {
00199 struct sembuf sop;
00200
00201 sop.sem_num=0;
00202 sop.sem_op=1;
00203 sop.sem_flg=0;
00204 tryagain:
00205 if (semop(*lock, &sop, 1)==-1){
00206 if (errno==EINTR){
00207
00208 LM_DBG("signal received while releasing a mutex\n");
00209 goto tryagain;
00210 }else{
00211 LM_CRIT("%s (%d)\n", strerror(errno), errno);
00212 }
00213 }
00214 }
00215
00216
00217 #else
00218 #error "no locking method selected"
00219 #endif
00220
00221
00222
00223
00224 #if defined(FAST_LOCK) || defined(USE_PTHREAD_MUTEX) || defined(USE_POSIX_SEM)
00225 #define GEN_LOCK_T_PREFERED
00226
00227 struct gen_lock_set_t_ {
00228 long size;
00229 gen_lock_t* locks;
00230 };
00231 typedef struct gen_lock_set_t_ gen_lock_set_t;
00232
00233
00234 #define lock_set_destroy(lock_set)
00235
00236 inline static gen_lock_set_t* lock_set_init(gen_lock_set_t* s)
00237 {
00238 int r;
00239 for (r=0; r<s->size; r++) if (lock_init(&s->locks[r])==0) return 0;
00240 return s;
00241 }
00242
00243
00244 #define lock_set_get(set, i) lock_get(&set->locks[i])
00245 #define lock_set_release(set, i) lock_release(&set->locks[i])
00246
00247 #elif defined(USE_SYSV_SEM)
00248 #undef GEN_LOCK_T_PREFERED
00249
00250 struct gen_lock_set_t_ {
00251 int size;
00252 int semid;
00253 };
00254
00255
00256 typedef struct gen_lock_set_t_ gen_lock_set_t;
00257 inline static gen_lock_set_t* lock_set_init(gen_lock_set_t* s)
00258 {
00259 union semun su;
00260 int r;
00261 int euid;
00262
00263 euid=geteuid();
00264 if (uid && uid!=euid)
00265 seteuid(uid);
00266 s->semid=semget(IPC_PRIVATE, s->size, 0700);
00267 if (uid && uid!=euid)
00268 seteuid(euid);
00269 if (s->semid==-1){
00270 LM_CRIT("semget (..., %d, 0700) failed: %s\n",
00271 s->size, strerror(errno));
00272 return 0;
00273 }
00274 su.val=1;
00275 for (r=0; r<s->size; r++){
00276 if (semctl(s->semid, r, SETVAL, su)==-1){
00277 LM_CRIT("semctl failed on sem %d: %s\n",
00278 r, strerror(errno));
00279 su.val = 0;
00280 semctl(s->semid, 0, IPC_RMID, su);
00281 return 0;
00282 }
00283 }
00284 return s;
00285 }
00286
00287 inline static void lock_set_destroy(gen_lock_set_t* s)
00288 {
00289 union semun su;
00290
00291 su.val = 0;
00292 semctl(s->semid, 0, IPC_RMID, su);
00293 }
00294
00295 inline static void lock_set_get(gen_lock_set_t* s, int n)
00296 {
00297 struct sembuf sop;
00298 sop.sem_num=n;
00299 sop.sem_op=-1;
00300 sop.sem_flg=0;
00301 tryagain:
00302 if (semop(s->semid, &sop, 1)==-1){
00303 if (errno==EINTR){
00304 LM_DBG("signal received while waiting on a mutex\n");
00305 goto tryagain;
00306 }else{
00307 LM_CRIT("%s (%d)\n", strerror(errno), errno);
00308 }
00309 }
00310 }
00311
00312 inline static void lock_set_release(gen_lock_set_t* s, int n)
00313 {
00314 struct sembuf sop;
00315 sop.sem_num=n;
00316 sop.sem_op=1;
00317 sop.sem_flg=0;
00318 tryagain:
00319 if (semop(s->semid, &sop, 1)==-1){
00320 if (errno==EINTR){
00321
00322 LM_DBG("signal received while releasing mutex\n");
00323 goto tryagain;
00324 }else{
00325 LM_CRIT("%s (%d)\n", strerror(errno), errno);
00326 }
00327 }
00328 }
00329 #else
00330 #error "no lock set method selected"
00331 #endif
00332
00333
00334 #endif