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