00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef _ASTERISK_LOCK_H
00024 #define _ASTERISK_LOCK_H
00025
00026 #include <pthread.h>
00027 #include <netdb.h>
00028 #include <time.h>
00029 #include <sys/param.h>
00030
00031 #include "asterisk/logger.h"
00032
00033 #define AST_PTHREADT_NULL (pthread_t) -1
00034 #define AST_PTHREADT_STOP (pthread_t) -2
00035
00036 #ifdef __APPLE__
00037
00038 #define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
00039 #define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP { 0x4d555458, \
00040 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
00041 0x20 } }
00042 #endif
00043
00044 #ifdef BSD
00045 #ifdef __GNUC__
00046 #define AST_MUTEX_INIT_W_CONSTRUCTORS
00047 #else
00048 #define AST_MUTEX_INIT_ON_FIRST_USE
00049 #endif
00050 #endif
00051
00052
00053
00054 #if defined(__CYGWIN__)
00055 #define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
00056 #define PTHREAD_MUTEX_INIT_VALUE (ast_mutex_t)18
00057 #define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE_NP
00058 #elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
00059 #define PTHREAD_MUTEX_INIT_VALUE PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
00060 #define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE_NP
00061 #else
00062 #define PTHREAD_MUTEX_INIT_VALUE PTHREAD_MUTEX_INITIALIZER
00063 #define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE
00064 #endif
00065
00066 #ifdef SOLARIS
00067 #define AST_MUTEX_INIT_W_CONSTRUCTORS
00068 #endif
00069
00070 #ifdef DEBUG_THREADS
00071
00072 #define __ast_mutex_logger(...) { if (canlog) ast_log(LOG_ERROR, __VA_ARGS__); else fprintf(stderr, __VA_ARGS__); }
00073
00074 #ifdef THREAD_CRASH
00075 #define DO_THREAD_CRASH do { *((int *)(0)) = 1; } while(0)
00076 #endif
00077
00078 #include <errno.h>
00079 #include <string.h>
00080 #include <stdio.h>
00081 #include <unistd.h>
00082
00083 #define AST_MUTEX_INIT_VALUE { PTHREAD_MUTEX_INIT_VALUE, { NULL }, { 0 }, 0, { NULL }, { 0 } }
00084
00085 #define AST_MAX_REENTRANCY 10
00086
00087 struct ast_mutex_info {
00088 pthread_mutex_t mutex;
00089 const char *file[AST_MAX_REENTRANCY];
00090 int lineno[AST_MAX_REENTRANCY];
00091 int reentrancy;
00092 const char *func[AST_MAX_REENTRANCY];
00093 pthread_t thread[AST_MAX_REENTRANCY];
00094 };
00095
00096 typedef struct ast_mutex_info ast_mutex_t;
00097
00098 typedef pthread_cond_t ast_cond_t;
00099
00100 static pthread_mutex_t empty_mutex;
00101
00102 static void __attribute__((constructor)) init_empty_mutex(void)
00103 {
00104 memset(&empty_mutex, 0, sizeof(empty_mutex));
00105 }
00106
00107 static inline int __ast_pthread_mutex_init_attr(const char *filename, int lineno, const char *func,
00108 const char *mutex_name, ast_mutex_t *t,
00109 pthread_mutexattr_t *attr)
00110 {
00111 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
00112 int canlog = strcmp(filename, "logger.c");
00113
00114 if ((t->mutex) != ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
00115 if ((t->mutex) != (empty_mutex)) {
00116 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is already initialized.\n",
00117 filename, lineno, func, mutex_name);
00118 __ast_mutex_logger("%s line %d (%s): Error: previously initialization of mutex '%s'.\n",
00119 t->file, t->lineno, t->func, mutex_name);
00120 #ifdef THREAD_CRASH
00121 DO_THREAD_CRASH;
00122 #endif
00123 return 0;
00124 }
00125 }
00126 #endif
00127
00128 t->file[0] = filename;
00129 t->lineno[0] = lineno;
00130 t->func[0] = func;
00131 t->thread[0] = 0;
00132 t->reentrancy = 0;
00133
00134 return pthread_mutex_init(&t->mutex, attr);
00135 }
00136
00137 static inline int __ast_pthread_mutex_init(const char *filename, int lineno, const char *func,
00138 const char *mutex_name, ast_mutex_t *t)
00139 {
00140 static pthread_mutexattr_t attr;
00141
00142 pthread_mutexattr_init(&attr);
00143 pthread_mutexattr_settype(&attr, AST_MUTEX_KIND);
00144
00145 return __ast_pthread_mutex_init_attr(filename, lineno, func, mutex_name, t, &attr);
00146 }
00147
00148 static inline int __ast_pthread_mutex_destroy(const char *filename, int lineno, const char *func,
00149 const char *mutex_name, ast_mutex_t *t)
00150 {
00151 int res;
00152 int canlog = strcmp(filename, "logger.c");
00153
00154 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
00155 if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
00156 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
00157 filename, lineno, func, mutex_name);
00158 }
00159 #endif
00160
00161 res = pthread_mutex_trylock(&t->mutex);
00162 switch (res) {
00163 case 0:
00164 pthread_mutex_unlock(&t->mutex);
00165 break;
00166 case EINVAL:
00167 __ast_mutex_logger("%s line %d (%s): Error: attempt to destroy invalid mutex '%s'.\n",
00168 filename, lineno, func, mutex_name);
00169 break;
00170 case EBUSY:
00171 __ast_mutex_logger("%s line %d (%s): Error: attempt to destroy locked mutex '%s'.\n",
00172 filename, lineno, func, mutex_name);
00173 __ast_mutex_logger("%s line %d (%s): Error: '%s' was locked here.\n",
00174 t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
00175 break;
00176 }
00177
00178 if ((res = pthread_mutex_destroy(&t->mutex)))
00179 __ast_mutex_logger("%s line %d (%s): Error destroying mutex: %s\n",
00180 filename, lineno, func, strerror(res));
00181 #ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
00182 else
00183 t->mutex = PTHREAD_MUTEX_INIT_VALUE;
00184 #endif
00185 t->file[0] = filename;
00186 t->lineno[0] = lineno;
00187 t->func[0] = func;
00188
00189 return res;
00190 }
00191
00192 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
00193
00194
00195 #define __AST_MUTEX_DEFINE(scope,mutex) \
00196 scope ast_mutex_t mutex = AST_MUTEX_INIT_VALUE; \
00197 static void __attribute__ ((constructor)) init_##mutex(void) \
00198 { \
00199 ast_mutex_init(&mutex); \
00200 } \
00201 static void __attribute__ ((destructor)) fini_##mutex(void) \
00202 { \
00203 ast_mutex_destroy(&mutex); \
00204 }
00205 #elif defined(AST_MUTEX_INIT_ON_FIRST_USE)
00206
00207
00208
00209
00210
00211 #define __AST_MUTEX_DEFINE(scope,mutex) \
00212 scope ast_mutex_t mutex = AST_MUTEX_INIT_VALUE
00213 #else
00214
00215 #define __AST_MUTEX_DEFINE(scope,mutex) \
00216 scope ast_mutex_t mutex = AST_MUTEX_INIT_VALUE
00217 #endif
00218
00219 static inline int __ast_pthread_mutex_lock(const char *filename, int lineno, const char *func,
00220 const char* mutex_name, ast_mutex_t *t)
00221 {
00222 int res;
00223 int canlog = strcmp(filename, "logger.c");
00224
00225 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS) || defined(AST_MUTEX_INIT_ON_FIRST_USE)
00226 if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
00227 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
00228 ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
00229 filename, lineno, func, mutex_name);
00230 #endif
00231 ast_mutex_init(t);
00232 }
00233 #endif
00234
00235 #ifdef DETECT_DEADLOCKS
00236 {
00237 time_t seconds = time(NULL);
00238 time_t current;
00239 do {
00240 res = pthread_mutex_trylock(&t->mutex);
00241 if (res == EBUSY) {
00242 current = time(NULL);
00243 if ((current - seconds) && (!((current - seconds) % 5))) {
00244 __ast_mutex_logger("%s line %d (%s): Deadlock? waited %d sec for mutex '%s'?\n",
00245 filename, lineno, func, (int)(current - seconds), mutex_name);
00246 __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
00247 t->file[t->reentrancy-1], t->lineno[t->reentrancy-1],
00248 t->func[t->reentrancy-1], mutex_name);
00249 }
00250 usleep(200);
00251 }
00252 } while (res == EBUSY);
00253 }
00254 #else
00255 res = pthread_mutex_lock(&t->mutex);
00256 #endif
00257
00258 if (!res) {
00259 if (t->reentrancy < AST_MAX_REENTRANCY) {
00260 t->file[t->reentrancy] = filename;
00261 t->lineno[t->reentrancy] = lineno;
00262 t->func[t->reentrancy] = func;
00263 t->thread[t->reentrancy] = pthread_self();
00264 t->reentrancy++;
00265 } else {
00266 __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
00267 filename, lineno, func, mutex_name);
00268 }
00269 } else {
00270 __ast_mutex_logger("%s line %d (%s): Error obtaining mutex: %s\n",
00271 filename, lineno, func, strerror(errno));
00272 #ifdef THREAD_CRASH
00273 DO_THREAD_CRASH;
00274 #endif
00275 }
00276
00277 return res;
00278 }
00279
00280 static inline int __ast_pthread_mutex_trylock(const char *filename, int lineno, const char *func,
00281 const char* mutex_name, ast_mutex_t *t)
00282 {
00283 int res;
00284 int canlog = strcmp(filename, "logger.c");
00285
00286 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS) || defined(AST_MUTEX_INIT_ON_FIRST_USE)
00287 if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
00288 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
00289
00290 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
00291 filename, lineno, func, mutex_name);
00292 #endif
00293 ast_mutex_init(t);
00294 }
00295 #endif
00296
00297 if (!(res = pthread_mutex_trylock(&t->mutex))) {
00298 if (t->reentrancy < AST_MAX_REENTRANCY) {
00299 t->file[t->reentrancy] = filename;
00300 t->lineno[t->reentrancy] = lineno;
00301 t->func[t->reentrancy] = func;
00302 t->thread[t->reentrancy] = pthread_self();
00303 t->reentrancy++;
00304 } else {
00305 __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
00306 filename, lineno, func, mutex_name);
00307 }
00308 }
00309
00310 return res;
00311 }
00312
00313 static inline int __ast_pthread_mutex_unlock(const char *filename, int lineno, const char *func,
00314 const char *mutex_name, ast_mutex_t *t)
00315 {
00316 int res;
00317 int canlog = strcmp(filename, "logger.c");
00318
00319 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
00320 if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
00321 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
00322 filename, lineno, func, mutex_name);
00323 }
00324 #endif
00325
00326 if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
00327 __ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
00328 filename, lineno, func, mutex_name);
00329 __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
00330 t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
00331 #ifdef THREAD_CRASH
00332 DO_THREAD_CRASH;
00333 #endif
00334 }
00335
00336 if (--t->reentrancy < 0) {
00337 __ast_mutex_logger("%s line %d (%s): mutex '%s' freed more times than we've locked!\n",
00338 filename, lineno, func, mutex_name);
00339 t->reentrancy = 0;
00340 }
00341
00342 if (t->reentrancy < AST_MAX_REENTRANCY) {
00343 t->file[t->reentrancy] = NULL;
00344 t->lineno[t->reentrancy] = 0;
00345 t->func[t->reentrancy] = NULL;
00346 t->thread[t->reentrancy] = 0;
00347 }
00348
00349 if ((res = pthread_mutex_unlock(&t->mutex))) {
00350 __ast_mutex_logger("%s line %d (%s): Error releasing mutex: %s\n",
00351 filename, lineno, func, strerror(res));
00352 #ifdef THREAD_CRASH
00353 DO_THREAD_CRASH;
00354 #endif
00355 }
00356
00357 return res;
00358 }
00359
00360 static inline int __ast_cond_init(const char *filename, int lineno, const char *func,
00361 const char *cond_name, ast_cond_t *cond, pthread_condattr_t *cond_attr)
00362 {
00363 return pthread_cond_init(cond, cond_attr);
00364 }
00365
00366 static inline int __ast_cond_signal(const char *filename, int lineno, const char *func,
00367 const char *cond_name, ast_cond_t *cond)
00368 {
00369 return pthread_cond_signal(cond);
00370 }
00371
00372 static inline int __ast_cond_broadcast(const char *filename, int lineno, const char *func,
00373 const char *cond_name, ast_cond_t *cond)
00374 {
00375 return pthread_cond_broadcast(cond);
00376 }
00377
00378 static inline int __ast_cond_destroy(const char *filename, int lineno, const char *func,
00379 const char *cond_name, ast_cond_t *cond)
00380 {
00381 return pthread_cond_destroy(cond);
00382 }
00383
00384 static inline int __ast_cond_wait(const char *filename, int lineno, const char *func,
00385 const char *cond_name, const char *mutex_name,
00386 ast_cond_t *cond, ast_mutex_t *t)
00387 {
00388 int res;
00389 int canlog = strcmp(filename, "logger.c");
00390
00391 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
00392 if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
00393 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
00394 filename, lineno, func, mutex_name);
00395 }
00396 #endif
00397
00398 if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
00399 __ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
00400 filename, lineno, func, mutex_name);
00401 __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
00402 t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
00403 #ifdef THREAD_CRASH
00404 DO_THREAD_CRASH;
00405 #endif
00406 }
00407
00408 if (t->reentrancy > 1)
00409 __ast_mutex_logger("%s line %d (%s): mutex '%s' locked more than once, cond_wait will block!\n",
00410 filename, lineno, func, mutex_name);
00411
00412 if (--t->reentrancy < 0) {
00413 __ast_mutex_logger("%s line %d (%s): mutex '%s' freed more times than we've locked!\n",
00414 filename, lineno, func, mutex_name);
00415 t->reentrancy = 0;
00416 }
00417
00418 if (t->reentrancy < AST_MAX_REENTRANCY) {
00419 t->file[t->reentrancy] = NULL;
00420 t->lineno[t->reentrancy] = 0;
00421 t->func[t->reentrancy] = NULL;
00422 t->thread[t->reentrancy] = 0;
00423 }
00424
00425 if ((res = pthread_cond_wait(cond, &t->mutex))) {
00426 __ast_mutex_logger("%s line %d (%s): Error waiting on condition mutex '%s'\n",
00427 filename, lineno, func, strerror(res));
00428 #ifdef THREAD_CRASH
00429 DO_THREAD_CRASH;
00430 #endif
00431 } else {
00432 if (t->reentrancy < AST_MAX_REENTRANCY) {
00433 t->file[t->reentrancy] = filename;
00434 t->lineno[t->reentrancy] = lineno;
00435 t->func[t->reentrancy] = func;
00436 t->thread[t->reentrancy] = pthread_self();
00437 t->reentrancy++;
00438 } else {
00439 __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
00440 filename, lineno, func, mutex_name);
00441 }
00442 }
00443
00444 return res;
00445 }
00446
00447 static inline int __ast_cond_timedwait(const char *filename, int lineno, const char *func,
00448 const char *cond_name, const char *mutex_name, ast_cond_t *cond,
00449 ast_mutex_t *t, const struct timespec *abstime)
00450 {
00451 int res;
00452 int canlog = strcmp(filename, "logger.c");
00453
00454 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
00455 if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
00456 __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
00457 filename, lineno, func, mutex_name);
00458 }
00459 #endif
00460
00461 if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
00462 __ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
00463 filename, lineno, func, mutex_name);
00464 __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
00465 t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
00466 #ifdef THREAD_CRASH
00467 DO_THREAD_CRASH;
00468 #endif
00469 }
00470
00471 if (t->reentrancy > 1)
00472 __ast_mutex_logger("%s line %d (%s): mutex '%s' locked more than once, cond_timedwait will block!\n",
00473 filename, lineno, func, mutex_name);
00474
00475 if (--t->reentrancy < 0) {
00476 __ast_mutex_logger("%s line %d (%s): mutex '%s' freed more times than we've locked!\n",
00477 filename, lineno, func, mutex_name);
00478 t->reentrancy = 0;
00479 }
00480
00481 if (t->reentrancy < AST_MAX_REENTRANCY) {
00482 t->file[t->reentrancy] = NULL;
00483 t->lineno[t->reentrancy] = 0;
00484 t->func[t->reentrancy] = NULL;
00485 t->thread[t->reentrancy] = 0;
00486 }
00487
00488 if ((res = pthread_cond_timedwait(cond, &t->mutex, abstime)) && (res != ETIMEDOUT)) {
00489 __ast_mutex_logger("%s line %d (%s): Error waiting on condition mutex '%s'\n",
00490 filename, lineno, func, strerror(res));
00491 #ifdef THREAD_CRASH
00492 DO_THREAD_CRASH;
00493 #endif
00494 } else {
00495 if (t->reentrancy < AST_MAX_REENTRANCY) {
00496 t->file[t->reentrancy] = filename;
00497 t->lineno[t->reentrancy] = lineno;
00498 t->func[t->reentrancy] = func;
00499 t->thread[t->reentrancy] = pthread_self();
00500 t->reentrancy++;
00501 } else {
00502 __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
00503 filename, lineno, func, mutex_name);
00504 }
00505 }
00506
00507 return res;
00508 }
00509
00510 #define ast_mutex_init(pmutex) __ast_pthread_mutex_init(__FILE__, __LINE__, __PRETTY_FUNCTION__, #pmutex, pmutex)
00511 #define ast_mutex_destroy(a) __ast_pthread_mutex_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
00512 #define ast_mutex_lock(a) __ast_pthread_mutex_lock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
00513 #define ast_mutex_unlock(a) __ast_pthread_mutex_unlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
00514 #define ast_mutex_trylock(a) __ast_pthread_mutex_trylock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
00515 #define ast_cond_init(cond, attr) __ast_cond_init(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond, attr)
00516 #define ast_cond_destroy(cond) __ast_cond_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond)
00517 #define ast_cond_signal(cond) __ast_cond_signal(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond)
00518 #define ast_cond_broadcast(cond) __ast_cond_broadcast(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond)
00519 #define ast_cond_wait(cond, mutex) __ast_cond_wait(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, #mutex, cond, mutex)
00520 #define ast_cond_timedwait(cond, mutex, time) __ast_cond_timedwait(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, #mutex, cond, mutex, time)
00521
00522 #else
00523
00524
00525 #define AST_MUTEX_INIT_VALUE PTHREAD_MUTEX_INIT_VALUE
00526
00527
00528 typedef pthread_mutex_t ast_mutex_t;
00529
00530 static inline int ast_mutex_init(ast_mutex_t *pmutex)
00531 {
00532 pthread_mutexattr_t attr;
00533 pthread_mutexattr_init(&attr);
00534 pthread_mutexattr_settype(&attr, AST_MUTEX_KIND);
00535 return pthread_mutex_init(pmutex, &attr);
00536 }
00537
00538 #define ast_pthread_mutex_init(pmutex,a) pthread_mutex_init(pmutex,a)
00539
00540 static inline int ast_mutex_unlock(ast_mutex_t *pmutex)
00541 {
00542 return pthread_mutex_unlock(pmutex);
00543 }
00544
00545 static inline int ast_mutex_destroy(ast_mutex_t *pmutex)
00546 {
00547 return pthread_mutex_destroy(pmutex);
00548 }
00549
00550 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
00551
00552
00553 #define __AST_MUTEX_DEFINE(scope,mutex) \
00554 scope ast_mutex_t mutex = AST_MUTEX_INIT_VALUE; \
00555 static void __attribute__ ((constructor)) init_##mutex(void) \
00556 { \
00557 ast_mutex_init(&mutex); \
00558 } \
00559 static void __attribute__ ((destructor)) fini_##mutex(void) \
00560 { \
00561 ast_mutex_destroy(&mutex); \
00562 }
00563
00564 static inline int ast_mutex_lock(ast_mutex_t *pmutex)
00565 {
00566 return pthread_mutex_lock(pmutex);
00567 }
00568
00569 static inline int ast_mutex_trylock(ast_mutex_t *pmutex)
00570 {
00571 return pthread_mutex_trylock(pmutex);
00572 }
00573
00574 #elif defined(AST_MUTEX_INIT_ON_FIRST_USE)
00575
00576
00577
00578
00579 #define __AST_MUTEX_DEFINE(scope,mutex) \
00580 scope ast_mutex_t mutex = AST_MUTEX_INIT_VALUE
00581
00582 static inline int ast_mutex_lock(ast_mutex_t *pmutex)
00583 {
00584 if (*pmutex == (ast_mutex_t)AST_MUTEX_KIND)
00585 ast_mutex_init(pmutex);
00586 return pthread_mutex_lock(pmutex);
00587 }
00588 static inline int ast_mutex_trylock(ast_mutex_t *pmutex)
00589 {
00590 if (*pmutex == (ast_mutex_t)AST_MUTEX_KIND)
00591 ast_mutex_init(pmutex);
00592 return pthread_mutex_trylock(pmutex);
00593 }
00594 #else
00595
00596 #define __AST_MUTEX_DEFINE(scope,mutex) \
00597 scope ast_mutex_t mutex = AST_MUTEX_INIT_VALUE
00598
00599 static inline int ast_mutex_lock(ast_mutex_t *pmutex)
00600 {
00601 return pthread_mutex_lock(pmutex);
00602 }
00603
00604 static inline int ast_mutex_trylock(ast_mutex_t *pmutex)
00605 {
00606 return pthread_mutex_trylock(pmutex);
00607 }
00608
00609 #endif
00610
00611 typedef pthread_cond_t ast_cond_t;
00612
00613 static inline int ast_cond_init(ast_cond_t *cond, pthread_condattr_t *cond_attr)
00614 {
00615 return pthread_cond_init(cond, cond_attr);
00616 }
00617
00618 static inline int ast_cond_signal(ast_cond_t *cond)
00619 {
00620 return pthread_cond_signal(cond);
00621 }
00622
00623 static inline int ast_cond_broadcast(ast_cond_t *cond)
00624 {
00625 return pthread_cond_broadcast(cond);
00626 }
00627
00628 static inline int ast_cond_destroy(ast_cond_t *cond)
00629 {
00630 return pthread_cond_destroy(cond);
00631 }
00632
00633 static inline int ast_cond_wait(ast_cond_t *cond, ast_mutex_t *t)
00634 {
00635 return pthread_cond_wait(cond, t);
00636 }
00637
00638 static inline int ast_cond_timedwait(ast_cond_t *cond, ast_mutex_t *t, const struct timespec *abstime)
00639 {
00640 return pthread_cond_timedwait(cond, t, abstime);
00641 }
00642
00643 #endif
00644
00645 #define pthread_mutex_t use_ast_mutex_t_instead_of_pthread_mutex_t
00646 #define pthread_mutex_lock use_ast_mutex_lock_instead_of_pthread_mutex_lock
00647 #define pthread_mutex_unlock use_ast_mutex_unlock_instead_of_pthread_mutex_unlock
00648 #define pthread_mutex_trylock use_ast_mutex_trylock_instead_of_pthread_mutex_trylock
00649 #define pthread_mutex_init use_ast_mutex_init_instead_of_pthread_mutex_init
00650 #define pthread_mutex_destroy use_ast_mutex_destroy_instead_of_pthread_mutex_destroy
00651 #define pthread_cond_t use_ast_cond_t_instead_of_pthread_cond_t
00652 #define pthread_cond_init use_ast_cond_init_instead_of_pthread_cond_init
00653 #define pthread_cond_destroy use_ast_cond_destroy_instead_of_pthread_cond_destroy
00654 #define pthread_cond_signal use_ast_cond_signal_instead_of_pthread_cond_signal
00655 #define pthread_cond_broadcast use_ast_cond_broadcast_instead_of_pthread_cond_broadcast
00656 #define pthread_cond_wait use_ast_cond_wait_instead_of_pthread_cond_wait
00657 #define pthread_cond_timedwait use_ast_cond_wait_instead_of_pthread_cond_timedwait
00658
00659 #define AST_MUTEX_DEFINE_STATIC(mutex) __AST_MUTEX_DEFINE(static,mutex)
00660 #define AST_MUTEX_DEFINE_EXPORTED(mutex) __AST_MUTEX_DEFINE(,mutex)
00661
00662 #define AST_MUTEX_INITIALIZER __use_AST_MUTEX_DEFINE_STATIC_rather_than_AST_MUTEX_INITIALIZER__
00663
00664 #define gethostbyname __gethostbyname__is__not__reentrant__use__ast_gethostbyname__instead__
00665 #ifndef __linux__
00666 #define pthread_create __use_ast_pthread_create_instead__
00667 #endif
00668
00669 #endif