source: trunk/include/sh_pthread.h@ 354

Last change on this file since 354 was 320, checked in by katerina, 14 years ago

Fix for ticket #237: Potential deadlock in sh_hash_hashdelete()

File size: 6.6 KB
Line 
1#ifndef SH_PTHREAD_H
2#define SH_PTHREAD_H
3
4#ifdef HAVE_PTHREAD
5
6#include <pthread.h>
7
8#define SH_MUTEX(M) pthread_mutex_t M
9#define SH_MUTEX_INIT(M,I) pthread_mutex_t M = I
10#define SH_MUTEX_STATIC(M,I) static pthread_mutex_t M = I
11#define SH_MUTEX_EXTERN(M) extern pthread_mutex_t M
12
13#define SH_SETSIGMASK(A, B, C) sh_pthread_setsigmask(A,B,C)
14
15int sh_pthread_setsigmask(int how, const void *set, void *oldset);
16
17/* pthread_mutex_unlock() has the wrong type (returns int), so
18 * we need to wrap it in this function.
19 */
20extern void sh_pthread_mutex_unlock (void *arg);
21
22#define SH_MUTEX_LOCK(M) \
23 do { \
24 int oldtype; \
25 int executeStack = 1; \
26 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype); \
27 pthread_cleanup_push(sh_pthread_mutex_unlock, (void*)&(M));\
28 pthread_mutex_lock(&(M))
29
30#define SH_MUTEX_TRYLOCK(M) \
31 do { \
32 int oldtype; \
33 int executeStack = 0; \
34 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype); \
35 pthread_cleanup_push(sh_pthread_mutex_unlock, (void*)&(M));\
36 pthread_mutex_trylock(&(M)); \
37 executeStack = 1
38
39#define SH_MUTEX_UNLOCK(M) \
40 pthread_cleanup_pop(executeStack); \
41 pthread_setcanceltype(oldtype, NULL); \
42 } while (0)
43
44#define SH_MUTEX_LOCK_UNSAFE(M) pthread_mutex_lock(&(M))
45#define SH_MUTEX_TRYLOCK_UNSAFE(M) pthread_mutex_trylock(&(M))
46#define SH_MUTEX_UNLOCK_UNSAFE(M) pthread_mutex_unlock(&(M))
47
48
49/*
50 * ---- Recursive mutex ----
51 */
52#if defined(HAVE_PTHREAD_MUTEX_RECURSIVE)
53
54#define SH_MUTEX_RECURSIVE(M) \
55static pthread_mutex_t M; \
56static void M ## _init (void) \
57{ \
58 pthread_mutexattr_t mta; \
59 pthread_mutexattr_init(&mta); \
60 pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE); \
61 pthread_mutex_init(&(M), &mta); \
62 pthread_mutexattr_destroy(&mta); \
63 return; \
64} \
65static pthread_once_t M ## _initialized = PTHREAD_ONCE_INIT
66
67#define SH_MUTEX_RECURSIVE_INIT(M) \
68(void) pthread_once(&(M ## _initialized), (M ## _init))
69
70#define SH_MUTEX_RECURSIVE_LOCK(M) \
71 do { \
72 int oldtype; \
73 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype); \
74 pthread_cleanup_push(sh_pthread_mutex_unlock, (void*)&(M));\
75 pthread_mutex_lock(&(M))
76
77#define SH_MUTEX_RECURSIVE_UNLOCK(M) \
78 pthread_cleanup_pop(1); \
79 pthread_setcanceltype(oldtype, NULL); \
80 } while (0)
81
82#else
83/* !defined(PTHREAD_MUTEX_RECURSIVE) */
84 struct sh_RMutex {
85
86 pthread_mutex_t lock;
87 unsigned int held;
88 unsigned int waiters;
89 pthread_t tid;
90 pthread_cond_t cv;
91};
92
93void sh_RMutexLock(struct sh_RMutex * tok);
94void sh_RMutexUnlock(void * arg);
95void sh_InitRMutex(struct sh_RMutex * tok);
96
97#define SH_MUTEX_RECURSIVE(M) \
98static struct sh_RMutex M; \
99static void M ## _init (void) \
100{ \
101 sh_InitRMutex(&(M)); \
102 return; \
103} \
104static pthread_once_t M ## _initialized = PTHREAD_ONCE_INIT
105
106#define SH_MUTEX_RECURSIVE_INIT(M) \
107(void) pthread_once(&(M ## _initialized), (M ## _init))
108
109#define SH_MUTEX_RECURSIVE_LOCK(M) \
110 do { \
111 int oldtype; \
112 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype); \
113 pthread_cleanup_push(sh_RMutexUnlock, (void*)&(M)); \
114 sh_RMutexLock(&(M))
115
116#define SH_MUTEX_RECURSIVE_UNLOCK(M) \
117 pthread_cleanup_pop(1); \
118 pthread_setcanceltype(oldtype, NULL); \
119 } while (0)
120
121#endif
122/*
123 * ---- Global mutexes ----
124 */
125SH_MUTEX_EXTERN(mutex_skey);
126SH_MUTEX_EXTERN(mutex_resolv);
127SH_MUTEX_EXTERN(mutex_pwent);
128SH_MUTEX_EXTERN(mutex_readdir);
129/* Prevent threads from logging while we are in suspend */
130SH_MUTEX_EXTERN(mutex_thread_nolog);
131
132/*
133 * ---- Initialize thread-specific conversion area ----
134 */
135extern int sh_g_thread(void);
136
137
138/*
139 * ---- Functions for threaded modules ----
140 */
141int sh_pthread_create(void *(*start_routine)(void*), void *arg);
142int sh_pthread_cancel_all(void);
143void sh_threaded_module_reconf(void *arg);
144void * sh_threaded_module_run(void *arg);
145
146#else
147
148#define SH_SETSIGMASK(A, B, C) sh_pthread_setsigmask(A,B,C)
149
150int sh_pthread_setsigmask(int how, const void *set, void *oldset);
151
152#define PTHREAD_MUTEX_INITIALIZER NULL
153#define SH_MUTEX(M) void *SH_MUTEX_DUMMY_ ## M
154#define SH_MUTEX_INIT(M,I) extern void *SH_MUTEX_DUMMY_ ## M
155#define SH_MUTEX_STATIC(M,I) extern void *SH_MUTEX_DUMMY_ ## M
156#define SH_MUTEX_EXTERN(M) extern void *SH_MUTEX_DUMMY_ ## M
157#define SH_MUTEX_LOCK(M) ((void)0)
158#define SH_MUTEX_TRYLOCK(M) ((void)0)
159#define SH_MUTEX_UNLOCK(M) ((void)0)
160#define SH_MUTEX_LOCK_UNSAFE(M) ((void)0)
161#define SH_MUTEX_TRYLOCK_UNSAFE(M) (0)
162#define SH_MUTEX_UNLOCK_UNSAFE(M) ((void)0)
163
164#define SH_MUTEX_RECURSIVE(M) extern void *SH_MUTEX_DUMMY_ ## M
165#define SH_MUTEX_RECURSIVE_INIT(M) ((void)0)
166#define SH_MUTEX_RECURSIVE_LOCK(M) ((void)0)
167#define SH_MUTEX_RECURSIVE_UNLOCK(M) ((void)0)
168
169/* #ifdef HAVE_PTHREAD */
170#endif
171
172/* #ifndef SH_PTHREAD_H */
173#endif
Note: See TracBrowser for help on using the repository browser.