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

Generated on Fri Oct 31 07:05:06 2003 for Asterisk by doxygen 1.3.4