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 
00019 #define AST_PTHREADT_NULL (pthread_t) -1
00020 #define AST_PTHREADT_STOP (pthread_t) -2
00021 
00022 #ifdef DEBUG_THREADS
00023 
00024 #ifdef THREAD_CRASH
00025 #define DO_THREAD_CRASH do { *((int *)(0)) = 1; } while(0)
00026 #endif
00027 
00028 #include <errno.h>
00029 #include <string.h>
00030 #include <stdio.h>
00031 #include <unistd.h>
00032 
00033 // #define AST_MUTEX_INITIALIZER      PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
00034 // #define AST_MUTEX_KIND             PTHREAD_MUTEX_RECURSIVE_NP
00035 #ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
00036 #define AST_MUTEX_INITIALIZER         { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, NULL, 0, NULL, 0 }
00037 #else
00038 #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
00039 #define AST_MUTEX_INITIALIZER         { PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP, NULL, 0, NULL, 0 }
00040 #else
00041 #define AST_MUTEX_INITIALIZER         { PTHREAD_MUTEX_INITIALIZER, NULL, 0, NULL, 0 }
00042 #endif
00043 #endif
00044 #ifdef PTHREAD_MUTEX_ERRORCHECK_NP
00045 #define AST_MUTEX_KIND                PTHREAD_MUTEX_ERRORCHECK_NP
00046 #else
00047 #define AST_MUTEX_KIND                PTHREAD_MUTEX_ERRORCHECK
00048 #endif
00049 
00050 struct ast_mutex_info {
00051    pthread_mutex_t mutex;
00052    char *file;
00053    int lineno;
00054    char *func;
00055    pthread_t thread;
00056 };
00057 
00058 typedef struct ast_mutex_info ast_mutex_t;
00059 
00060 static inline int ast_mutex_init(ast_mutex_t *t) {
00061    static pthread_mutexattr_t  attr;
00062    static int  init = 1;
00063    int res;
00064    extern int  pthread_mutexattr_setkind_np(pthread_mutexattr_t *, int);
00065 
00066    if (init) {
00067       pthread_mutexattr_init(&attr);
00068       pthread_mutexattr_setkind_np(&attr, AST_MUTEX_KIND);
00069       init = 0;
00070    }
00071    res = pthread_mutex_init(&t->mutex, &attr);
00072    t->file = NULL;
00073    t->lineno = 0;
00074    t->func = 0;
00075    t->thread  = 0;
00076    return res;
00077 }
00078 
00079 static inline int ast_pthread_mutex_init(ast_mutex_t *t, pthread_mutexattr_t *attr) 
00080 {
00081    int res;
00082    res = pthread_mutex_init(&t->mutex, attr);
00083    t->file = NULL;
00084    t->lineno = 0;
00085    t->func = 0;
00086    t->thread  = 0;
00087    return res;
00088 }
00089 
00090 static inline int __ast_pthread_mutex_lock(char *filename, int lineno, char *func, ast_mutex_t *t) {
00091    int res;
00092    res = pthread_mutex_lock(&t->mutex);
00093    if (!res) {
00094       t->file = filename;
00095       t->lineno = lineno;
00096       t->func = func;
00097       t->thread = pthread_self();
00098    } else {
00099       fprintf(stderr, "%s line %d (%s): Error obtaining mutex: %s\n",
00100          filename, lineno, func, strerror(errno));
00101 #ifdef THREAD_CRASH
00102       DO_THREAD_CRASH;
00103 #endif
00104    }
00105    return res;
00106 }
00107 
00108 #define ast_mutex_lock(a) __ast_pthread_mutex_lock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a)
00109 
00110 static inline int __ast_pthread_mutex_trylock(char *filename, int lineno, char *func, ast_mutex_t *t) {
00111    int res;
00112    res = pthread_mutex_trylock(&t->mutex);
00113    if (!res) {
00114       t->file = filename;
00115       t->lineno = lineno;
00116       t->func = func;
00117       t->thread = pthread_self();
00118    }
00119    return res;
00120 }
00121 
00122 #define ast_mutex_trylock(a) __ast_pthread_mutex_trylock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a)
00123 
00124 static inline int __ast_pthread_mutex_unlock(char *filename, int lineno, char *func, ast_mutex_t *t) {
00125    int res;
00126    /* Assumes lock is actually held */
00127    t->file = NULL;
00128    t->lineno = 0;
00129    t->func = NULL;
00130    t->thread = 0;
00131    res = pthread_mutex_unlock(&t->mutex);
00132    if (res) {
00133       fprintf(stderr, "%s line %d (%s): Error releasing mutex: %s\n", 
00134             filename, lineno, func, strerror(res));
00135 #ifdef THREAD_CRASH
00136       DO_THREAD_CRASH;
00137 #endif
00138    }
00139    return res;
00140 }
00141 
00142 #define ast_mutex_unlock(a) __ast_pthread_mutex_unlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a)
00143 
00144 static inline int __ast_pthread_mutex_destroy(char *filename, int lineno, char *func, ast_mutex_t *t)
00145 {
00146    int res;
00147    t->file = NULL;
00148    t->lineno = 0;
00149    t->func = NULL;
00150    t->thread = 0;
00151    res = pthread_mutex_destroy(&t->mutex);
00152    if (res) 
00153       fprintf(stderr, "%s line %d (%s): Error destroying mutex: %s\n",
00154             filename, lineno, func, strerror(res));
00155    return res;
00156 }
00157 
00158 #define ast_mutex_destroy(a) __ast_pthread_mutex_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, a)
00159 
00160 #define pthread_mutex_t use_ast_mutex_t_instead_of_pthread_mutex_t
00161 #define pthread_mutex_lock use_ast_mutex_lock_instead_of_pthread_mutex_lock
00162 #define pthread_mutex_unlock use_ast_mutex_unlock_instead_of_pthread_mutex_unlock
00163 #define pthread_mutex_trylock use_ast_mutex_trylock_instead_of_pthread_mutex_trylock
00164 #define pthread_mutex_init use_ast_pthread_mutex_init_instead_of_pthread_mutex_init
00165 #define pthread_mutex_destroy use_ast_pthread_mutex_destroy_instead_of_pthread_mutex_destroy
00166 
00167 #else /* DEBUG_THREADS */
00168 
00169 #define AST_MUTEX_INITIALIZER      PTHREAD_MUTEX_INITIALIZER
00170 #ifdef PTHREAD_MUTEX_FAST_NP
00171 #define AST_MUTEX_KIND             PTHREAD_MUTEX_FAST_NP
00172 #else
00173 #define AST_MUTEX_KIND             PTHREAD_NORMAL
00174 #endif
00175 
00176 typedef pthread_mutex_t ast_mutex_t;
00177 
00178 #define ast_mutex_lock(t) pthread_mutex_lock(t)
00179 #define ast_mutex_unlock(t) pthread_mutex_unlock(t)
00180 #define ast_mutex_trylock(t) pthread_mutex_trylock(t)
00181 #define ast_mutex_init(t) pthread_mutex_init(t, NULL)
00182 #define ast_pthread_mutex_init(t,a) pthread_mutex_init(t,a)
00183 #define ast_mutex_destroy(t) pthread_mutex_destroy(t)
00184 
00185 #endif /* DEBUG_THREADS */
00186 
00187 
00188 #endif

Generated on Sun Apr 18 23:33:52 2004 for Asterisk by doxygen 1.3.6-20040222