Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

lock.h

Go to the documentation of this file.
00001 /* 00002 * Asterisk -- A telephony toolkit for Linux. 00003 * 00004 * General Asterisk channel definitions. 00005 * 00006 * Copyright (C) 1999, Mark Spencer 00007 * 00008 * Mark Spencer <markster@linux-support.net> 00009 * 00010 * This program is free software, distributed under the terms of 00011 * the GNU General Public License 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 /* Provide the Linux initializers for MacOS X */ 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 /* __FreeBSD__ */ 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 /* From now on, Asterisk REQUIRES Recursive (not error checking) mutexes 00051 and will not run without them. */ 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 /* if AST_MUTEX_INIT_W_CONSTRUCTORS is defined, use file scope 00093 constrictors/destructors to create/destroy mutexes. */ 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 /* if AST_MUTEX_INIT_ON_FIRST_USE is defined, mutexes are created on 00106 first use. The performance impact on FreeBSD should be small since 00107 the pthreads library does this itself to initialize errror checking 00108 (defaulty type) mutexes. If nither is defined, the pthreads librariy 00109 does the initialization itself on first use. */ 00110 #define __AST_MUTEX_DEFINE(scope,mutex) \ 00111 scope ast_mutex_t mutex = AST_MUTEX_INIT_VAULE 00112 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */ 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 /* Assumes lock is actually held */ 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 /* DEBUG_THREADS */ 00201 00202 /* From now on, Asterisk REQUIRES Recursive (not error checking) mutexes 00203 and will not run without them. */ 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 /* if AST_MUTEX_INIT_W_CONSTRUCTORS is defined, use file scope 00231 constrictors/destructors to create/destroy mutexes. */ 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 /* if AST_MUTEX_INIT_ON_FIRST_USE is defined, mutexes are created on 00248 first use. The performance impact on FreeBSD should be small since 00249 the pthreads library does this itself to initialize errror checking 00250 (defaulty type) mutexes.*/ 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 /* By default, use static initialization of mutexes.*/ 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 /* AST_MUTEX_INIT_W_CONSTRUCTORS */ 00273 00274 #endif /* DEBUG_THREADS */ 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

Generated on Sat Jun 12 16:40:58 2004 for Asterisk by doxygen 1.3.7