Change mutex defines so it should work on OS that don't have the _NP mutex types...
[asterisk/asterisk.git] / include / asterisk / lock.h
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * General Asterisk channel definitions.
5  * 
6  * Copyright (C) 1999, Mark Spencer
7  *
8  * Mark Spencer <markster@linux-support.net>
9  *
10  * This program is free software, distributed under the terms of
11  * the GNU General Public License
12  */
13
14 #ifndef _ASTERISK_LOCK_H
15 #define _ASTERISK_LOCK_H
16
17 #include <pthread.h>
18
19 #define AST_PTHREADT_NULL (pthread_t) -1
20 #define AST_PTHREADT_STOP (pthread_t) -2
21
22 /* From now on, Asterisk REQUIRES Recursive (not error checking) mutexes
23    and will not run without them. */
24
25 #ifdef PTHREAD_MUTEX_RECURSIVE_NP
26 #define AST_MUTEX_INITIALIZER      PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
27 #define AST_MUTEX_KIND             PTHREAD_MUTEX_RECURSIVE_NP
28 #else
29 #define AST_MUTEX_INITIALIZER      PTHREAD_MUTEX_INITIALIZER
30 #define AST_MUTEX_KIND             PTHREAD_MUTEX_RECURSIVE
31 #endif
32
33 #ifdef DEBUG_THREADS
34
35 #ifdef THREAD_CRASH
36 #define DO_THREAD_CRASH do { *((int *)(0)) = 1; } while(0)
37 #endif
38
39 #include <errno.h>
40 #include <string.h>
41 #include <stdio.h>
42 #include <unistd.h>
43
44 struct ast_mutex_info {
45         pthread_mutex_t mutex;
46         char *file;
47         int lineno;
48         char *func;
49         pthread_t thread;
50 };
51
52 typedef struct ast_mutex_info ast_mutex_t;
53
54 static inline int ast_mutex_init(ast_mutex_t *t) {
55         static pthread_mutexattr_t  attr;
56         static int  init = 1;
57         int res;
58         extern int  pthread_mutexattr_setkind_np(pthread_mutexattr_t *, int);
59
60         if (init) {
61                 pthread_mutexattr_init(&attr);
62                 pthread_mutexattr_setkind_np(&attr, AST_MUTEX_KIND);
63                 init = 0;
64         }
65         res = pthread_mutex_init(&t->mutex, &attr);
66         t->file = NULL;
67         t->lineno = 0;
68         t->func = 0;
69         t->thread  = 0;
70         return res;
71 }
72
73 static inline int ast_pthread_mutex_init(ast_mutex_t *t, pthread_mutexattr_t *attr) 
74 {
75         int res;
76         res = pthread_mutex_init(&t->mutex, attr);
77         t->file = NULL;
78         t->lineno = 0;
79         t->func = 0;
80         t->thread  = 0;
81         return res;
82 }
83
84 static inline int __ast_pthread_mutex_lock(char *filename, int lineno, char *func, ast_mutex_t *t) {
85         int res;
86         res = pthread_mutex_lock(&t->mutex);
87         if (!res) {
88                 t->file = filename;
89                 t->lineno = lineno;
90                 t->func = func;
91                 t->thread = pthread_self();
92         } else {
93                 fprintf(stderr, "%s line %d (%s): Error obtaining mutex: %s\n",
94                         filename, lineno, func, strerror(errno));
95 #ifdef THREAD_CRASH
96                 DO_THREAD_CRASH;
97 #endif
98         }
99         return res;
100 }
101
102 #define ast_mutex_lock(a) __ast_pthread_mutex_lock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a)
103
104 static inline int __ast_pthread_mutex_trylock(char *filename, int lineno, char *func, ast_mutex_t *t) {
105         int res;
106         res = pthread_mutex_trylock(&t->mutex);
107         if (!res) {
108                 t->file = filename;
109                 t->lineno = lineno;
110                 t->func = func;
111                 t->thread = pthread_self();
112         }
113         return res;
114 }
115
116 #define ast_mutex_trylock(a) __ast_pthread_mutex_trylock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a)
117
118 static inline int __ast_pthread_mutex_unlock(char *filename, int lineno, char *func, ast_mutex_t *t) {
119         int res;
120         /* Assumes lock is actually held */
121         t->file = NULL;
122         t->lineno = 0;
123         t->func = NULL;
124         t->thread = 0;
125         res = pthread_mutex_unlock(&t->mutex);
126         if (res) {
127                 fprintf(stderr, "%s line %d (%s): Error releasing mutex: %s\n", 
128                                 filename, lineno, func, strerror(res));
129 #ifdef THREAD_CRASH
130                 DO_THREAD_CRASH;
131 #endif
132         }
133         return res;
134 }
135
136 #define ast_mutex_unlock(a) __ast_pthread_mutex_unlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a)
137
138 static inline int __ast_pthread_mutex_destroy(char *filename, int lineno, char *func, ast_mutex_t *t)
139 {
140         int res;
141         t->file = NULL;
142         t->lineno = 0;
143         t->func = NULL;
144         t->thread = 0;
145         res = pthread_mutex_destroy(&t->mutex);
146         if (res) 
147                 fprintf(stderr, "%s line %d (%s): Error destroying mutex: %s\n",
148                                 filename, lineno, func, strerror(res));
149         return res;
150 }
151
152 #define ast_mutex_destroy(a) __ast_pthread_mutex_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, a)
153
154 #define pthread_mutex_t use_ast_mutex_t_instead_of_pthread_mutex_t
155 #define pthread_mutex_lock use_ast_mutex_lock_instead_of_pthread_mutex_lock
156 #define pthread_mutex_unlock use_ast_mutex_unlock_instead_of_pthread_mutex_unlock
157 #define pthread_mutex_trylock use_ast_mutex_trylock_instead_of_pthread_mutex_trylock
158 #define pthread_mutex_init use_ast_pthread_mutex_init_instead_of_pthread_mutex_init
159 #define pthread_mutex_destroy use_ast_pthread_mutex_destroy_instead_of_pthread_mutex_destroy
160
161 #else /* DEBUG_THREADS */
162
163 typedef pthread_mutex_t ast_mutex_t;
164
165 #define ast_mutex_lock(t) pthread_mutex_lock(t)
166 #define ast_mutex_unlock(t) pthread_mutex_unlock(t)
167 #define ast_mutex_trylock(t) pthread_mutex_trylock(t)
168 static inline int ast_mutex_init(ast_mutex_t *t)
169 {
170         pthread_mutexattr_t attr;
171         pthread_mutexattr_init(&attr);
172         pthread_mutexattr_settype(&attr, AST_MUTEX_KIND);
173         return pthread_mutex_init(t, &attr);
174 }
175 #define ast_pthread_mutex_init(t,a) pthread_mutex_init(t,a)
176 #define ast_mutex_destroy(t) pthread_mutex_destroy(t)
177
178 #endif /* DEBUG_THREADS */
179
180
181 #endif