00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
#ifndef _ASTERISK_LOCK_H
00015
#define _ASTERISK_LOCK_H
00016
00017
#include <pthread.h>
00018
#include <netdb.h>
00019
00020 #define AST_PTHREADT_NULL (pthread_t) -1
00021 #define AST_PTHREADT_STOP (pthread_t) -2
00022
00023
#ifdef __APPLE__
00024
00025
#define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
00026
#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP { 0x4d555458, \
00027
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
00028
0x20 } }
00029
#endif
00030
00031
#ifdef __FreeBSD__
00032
#ifdef __GNUC__
00033
#define AST_MUTEX_INIT_W_CONSTRUCTORS
00034
#else
00035
#define AST_MUTEX_INIT_ON_FIRST_USE
00036
#endif
00037
#endif
00038
00039
#ifdef DEBUG_THREADS
00040
00041
#ifdef THREAD_CRASH
00042
#define DO_THREAD_CRASH do { *((int *)(0)) = 1; } while(0)
00043
#endif
00044
00045
#include <errno.h>
00046
#include <string.h>
00047
#include <stdio.h>
00048
#include <unistd.h>
00049
00050
00051
00052
#ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
00053
#define AST_MUTEX_INIT_VAULE { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, NULL, 0, NULL, 0 }
00054
#else
00055
#define AST_MUTEX_INIT_VAULE { PTHREAD_MUTEX_INITIALIZER, NULL, 0, NULL, 0 }
00056
#endif
00057
00058
#ifdef PTHREAD_MUTEX_RECURSIVE_NP
00059
#define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE_NP
00060
#else
00061
#define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE
00062
#endif
00063
00064
struct ast_mutex_info {
00065 pthread_mutex_t mutex;
00066
char *file;
00067
int lineno;
00068
char *func;
00069 pthread_t thread;
00070 };
00071
00072
typedef struct ast_mutex_info
ast_mutex_t;
00073
00074
static inline int ast_pthread_mutex_init(ast_mutex_t *t, pthread_mutexattr_t *attr)
00075 {
00076 t->file = NULL;
00077 t->lineno = 0;
00078 t->func = 0;
00079 t->thread = 0;
00080
return pthread_mutex_init(&t->mutex, attr);
00081 }
00082
00083
static inline int ast_mutex_init(ast_mutex_t *t)
00084 {
00085
static pthread_mutexattr_t attr;
00086 pthread_mutexattr_init(&attr);
00087 pthread_mutexattr_settype(&attr, AST_MUTEX_KIND);
00088
return ast_pthread_mutex_init(t, &attr);
00089 }
00090
00091
#if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
00092
00093
00094
#define __AST_MUTEX_DEFINE(scope,mutex) \
00095
scope ast_mutex_t mutex = AST_MUTEX_INIT_VAULE; \
00096
static void __attribute__ ((constructor)) init_##mutex(void) \
00097
{ \
00098
ast_mutex_init(&mutex); \
00099
} \
00100
static void __attribute__ ((destructor)) fini_##mutex(void) \
00101
{ \
00102
ast_mutex_destroy(&mutex); \
00103
}
00104
#elif defined(AST_MUTEX_INIT_ON_FIRST_USE) || !defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
00105
00106
00107
00108
00109
00110
#define __AST_MUTEX_DEFINE(scope,mutex) \
00111
scope ast_mutex_t mutex = AST_MUTEX_INIT_VAULE
00112
#endif
00113
00114
static inline int __ast_pthread_mutex_lock(
char *filename,
int lineno,
char *func, ast_mutex_t *t)
00115 {
00116
int res;
00117
#ifdef AST_MUTEX_INIT_ON_FIRST_USE
00118
if(*t->mutex == (
ast_mutex_t)
AST_MUTEX_KIND)
00119 ast_mutex_init(t->mutex);
00120
#endif
00121
res = pthread_mutex_lock(&t->mutex);
00122
if (!res) {
00123 t->file = filename;
00124 t->lineno = lineno;
00125 t->func = func;
00126 t->thread = pthread_self();
00127 }
else {
00128 fprintf(stderr,
"%s line %d (%s): Error obtaining mutex: %s\n",
00129 filename, lineno, func, strerror(errno));
00130
#ifdef THREAD_CRASH
00131
DO_THREAD_CRASH;
00132
#endif
00133
}
00134
return res;
00135 }
00136
00137
#define ast_mutex_lock(a) __ast_pthread_mutex_lock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a)
00138
00139
static inline int __ast_pthread_mutex_trylock(
char *filename,
int lineno,
char *func, ast_mutex_t *t) {
00140
int res;
00141
#ifdef AST_MUTEX_INIT_ON_FIRST_USE
00142
if(*t->mutex == (
ast_mutex_t)
AST_MUTEX_KIND)
00143 ast_mutex_init(t->mutex);
00144
#endif
00145
res = pthread_mutex_trylock(&t->mutex);
00146
if (!res) {
00147 t->file = filename;
00148 t->lineno = lineno;
00149 t->func = func;
00150 t->thread = pthread_self();
00151 }
00152
return res;
00153 }
00154
00155
#define ast_mutex_trylock(a) __ast_pthread_mutex_trylock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a)
00156
00157
static inline int __ast_pthread_mutex_unlock(
char *filename,
int lineno,
char *func, ast_mutex_t *t) {
00158
int res;
00159
00160 t->file = NULL;
00161 t->lineno = 0;
00162 t->func = NULL;
00163 t->thread = 0;
00164 res = pthread_mutex_unlock(&t->mutex);
00165
if (res) {
00166 fprintf(stderr,
"%s line %d (%s): Error releasing mutex: %s\n",
00167 filename, lineno, func, strerror(res));
00168
#ifdef THREAD_CRASH
00169
DO_THREAD_CRASH;
00170
#endif
00171
}
00172
return res;
00173 }
00174
00175
#define ast_mutex_unlock(a) __ast_pthread_mutex_unlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a)
00176
00177
static inline int __ast_pthread_mutex_destroy(
char *filename,
int lineno,
char *func, ast_mutex_t *t)
00178 {
00179
int res;
00180 t->file = NULL;
00181 t->lineno = 0;
00182 t->func = NULL;
00183 t->thread = 0;
00184 res = pthread_mutex_destroy(&t->mutex);
00185
if (res)
00186 fprintf(stderr,
"%s line %d (%s): Error destroying mutex: %s\n",
00187 filename, lineno, func, strerror(res));
00188
return res;
00189 }
00190
00191
#define ast_mutex_destroy(a) __ast_pthread_mutex_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, a)
00192
00193
#define pthread_mutex_t use_ast_mutex_t_instead_of_pthread_mutex_t
00194
#define pthread_mutex_lock use_ast_mutex_lock_instead_of_pthread_mutex_lock
00195
#define pthread_mutex_unlock use_ast_mutex_unlock_instead_of_pthread_mutex_unlock
00196
#define pthread_mutex_trylock use_ast_mutex_trylock_instead_of_pthread_mutex_trylock
00197
#define pthread_mutex_init use_ast_pthread_mutex_init_instead_of_pthread_mutex_init
00198
#define pthread_mutex_destroy use_ast_pthread_mutex_destroy_instead_of_pthread_mutex_destroy
00199
00200
#else
00201
00202
00203
00204
#ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
00205
#define AST_MUTEX_INIT_VAULE PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
00206
#else
00207 #define AST_MUTEX_INIT_VAULE PTHREAD_MUTEX_INITIALIZER
00208
#endif
00209
00210
#ifdef PTHREAD_MUTEX_RECURSIVE_NP
00211
#define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE_NP
00212
#else
00213 #define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE
00214
#endif
00215
00216 typedef pthread_mutex_t
ast_mutex_t;
00217
00218
static inline int ast_mutex_init(ast_mutex_t *pmutex)
00219 {
00220 pthread_mutexattr_t attr;
00221 pthread_mutexattr_init(&attr);
00222 pthread_mutexattr_settype(&attr,
AST_MUTEX_KIND);
00223
return pthread_mutex_init(pmutex, &attr);
00224 }
00225 #define ast_pthread_mutex_init(pmutex,a) pthread_mutex_init(pmutex,a)
00226 #define ast_mutex_unlock(pmutex) pthread_mutex_unlock(pmutex)
00227 #define ast_mutex_destroy(pmutex) pthread_mutex_destroy(pmutex)
00228
00229
#if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
00230
00231
00232
#define __AST_MUTEX_DEFINE(scope,mutex) \
00233
scope ast_mutex_t mutex = AST_MUTEX_INIT_VAULE; \
00234
static void __attribute__ ((constructor)) init_##mutex(void) \
00235
{ \
00236
ast_mutex_init(&mutex); \
00237
} \
00238
static void __attribute__ ((destructor)) fini_##mutex(void) \
00239
{ \
00240
ast_mutex_destroy(&mutex); \
00241
}
00242
00243
#define ast_mutex_lock(pmutex) pthread_mutex_lock(pmutex)
00244
#define ast_mutex_trylock(pmutex) pthread_mutex_trylock(pmutex)
00245
00246
#elif defined(AST_MUTEX_INIT_ON_FIRST_USE)
00247
00248
00249
00250
00251
#define __AST_MUTEX_DEFINE(scope,mutex) \
00252
scope ast_mutex_t mutex = AST_MUTEX_INIT_VAULE
00253
00254
static inline int ast_mutex_lock(ast_mutex_t *pmutex)
00255 {
00256
if(*pmutex == (
ast_mutex_t)
AST_MUTEX_KIND)
00257 ast_mutex_init(pmutex);
00258
return pthread_mutex_lock(pmutex);
00259 }
00260
static inline int ast_mutex_trylock(ast_mutex_t *pmutex)
00261 {
00262
if(*pmutex == (
ast_mutex_t)
AST_MUTEX_KIND)
00263 ast_mutex_init(pmutex);
00264
return pthread_mutex_trylock(pmutex);
00265 }
00266
#else
00267
00268 #define __AST_MUTEX_DEFINE(scope,mutex) \
00269
scope ast_mutex_t mutex = AST_MUTEX_INIT_VAULE
00270 #define ast_mutex_lock(pmutex) pthread_mutex_lock(pmutex)
00271 #define ast_mutex_trylock(pmutex) pthread_mutex_trylock(pmutex)
00272
#endif
00273
00274
#endif
00275
00276 #define AST_MUTEX_DEFINE_STATIC(mutex) __AST_MUTEX_DEFINE(static,mutex)
00277 #define AST_MUTEX_DEFINE_EXPORTED(mutex) __AST_MUTEX_DEFINE(,mutex)
00278
00279
00280 #define AST_MUTEX_INITIALIZER __use_AST_MUTEX_DEFINE_STATIC_rather_than_AST_MUTEX_INITIALIZER__
00281 #define gethostbyname __gethostbyname__is__not__reentrant__use__ast_gethostbyname__instead__
00282
00283
#endif