source: trunk/include/sh_pthread.h@ 139

Last change on this file since 139 was 139, checked in by rainer, 17 years ago

Detect availability of recursive mutexes on Linux.

File size: 5.2 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/* pthread_mutex_unlock() has the wrong type (returns int), so
14 * we need to wrap it in this function.
15 */
16extern void sh_pthread_mutex_unlock (void *arg);
17
18#define SH_MUTEX_LOCK(M) \
19 do { \
20 int oldtype; \
21 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype); \
22 pthread_cleanup_push(sh_pthread_mutex_unlock, (void*)&(M));\
23 pthread_mutex_lock(&(M))
24
25
26#define SH_MUTEX_UNLOCK(M) \
27 pthread_cleanup_pop(1); \
28 pthread_setcanceltype(oldtype, NULL); \
29 } while (0)
30
31#define SH_MUTEX_LOCK_UNSAFE(M) pthread_mutex_lock(&(M))
32#define SH_MUTEX_UNLOCK_UNSAFE(M) pthread_mutex_unlock(&(M))
33
34
35/*
36 * ---- Recursive mutex ----
37 */
38#if defined(HAVE_PTHREAD_MUTEX_RECURSIVE)
39
40/* On GNU C, it's an enum, thus the alternative implementation
41 * below is used.
42 */
43#define SH_MUTEX_RECURSIVE(M) \
44static pthread_mutex_t M; \
45static void M ## _init (void) \
46{ \
47 pthread_mutexattr_t mta; \
48 pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE); \
49 pthread_mutex_init(&(M), &mta); \
50 pthread_mutexattr_destroy(&mta); \
51 return; \
52} \
53static pthread_once_t M ## _initialized = PTHREAD_ONCE_INIT
54
55#define SH_MUTEX_RECURSIVE_INIT(M) \
56(void) pthread_once(&(M ## _initialized), (M ## _init))
57
58#define SH_MUTEX_RECURSIVE_LOCK(M) \
59 do { \
60 int oldtype; \
61 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype); \
62 pthread_cleanup_push(sh_pthread_mutex_unlock, (void*)&(M));\
63 pthread_mutex_lock(&(M))
64
65#define SH_MUTEX_RECURSIVE_UNLOCK(M) \
66 pthread_cleanup_pop(1); \
67 pthread_setcanceltype(oldtype, NULL); \
68 } while (0)
69
70#else
71/* !defined(PTHREAD_MUTEX_RECURSIVE) */
72 struct sh_RMutex {
73
74 pthread_mutex_t lock;
75 unsigned int held;
76 unsigned int waiters;
77 pthread_t tid;
78 pthread_cond_t cv;
79};
80
81void sh_RMutexLock(struct sh_RMutex * tok);
82void sh_RMutexUnlock(void * arg);
83void sh_InitRMutex(struct sh_RMutex * tok);
84
85#define SH_MUTEX_RECURSIVE(M) \
86static struct sh_RMutex M; \
87static void M ## _init (void) \
88{ \
89 sh_InitRMutex(&(M)); \
90 return; \
91} \
92static pthread_once_t M ## _initialized = PTHREAD_ONCE_INIT
93
94#define SH_MUTEX_RECURSIVE_INIT(M) \
95(void) pthread_once(&(M ## _initialized), (M ## _init))
96
97#define SH_MUTEX_RECURSIVE_LOCK(M) \
98 do { \
99 int oldtype; \
100 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype); \
101 pthread_cleanup_push(sh_RMutexUnlock, (void*)&(M)); \
102 sh_RMutexLock(&(M))
103
104#define SH_MUTEX_RECURSIVE_UNLOCK(M) \
105 pthread_cleanup_pop(1); \
106 pthread_setcanceltype(oldtype, NULL); \
107 } while (0)
108
109#endif
110/*
111 * ---- Global mutexes ----
112 */
113SH_MUTEX_EXTERN(mutex_skey);
114SH_MUTEX_EXTERN(mutex_resolv);
115SH_MUTEX_EXTERN(mutex_pwent);
116SH_MUTEX_EXTERN(mutex_readdir);
117
118/*
119 * ---- Initialize thread-specific conversion area ----
120 */
121extern int sh_g_thread();
122
123#else
124
125#define SH_MUTEX(M) void *SH_MUTEX_DUMMY_ ## M
126#define SH_MUTEX_INIT(M,I) extern void *SH_MUTEX_DUMMY_ ## M
127#define SH_MUTEX_STATIC(M,I) extern void *SH_MUTEX_DUMMY_ ## M
128#define SH_MUTEX_EXTERN(M) extern void *SH_MUTEX_DUMMY_ ## M
129#define SH_MUTEX_LOCK(M) ((void)0)
130#define SH_MUTEX_UNLOCK(M) ((void)0)
131#define SH_MUTEX_LOCK_UNSAFE(M) ((void)0)
132#define SH_MUTEX_UNLOCK_UNSAFE(M) ((void)0)
133
134#define SH_MUTEX_RECURSIVE(M) extern void *SH_MUTEX_DUMMY_ ## M
135#define SH_MUTEX_RECURSIVE_INIT(M) ((void)0)
136#define SH_MUTEX_RECURSIVE_LOCK(M) ((void)0)
137#define SH_MUTEX_RECURSIVE_UNLOCK(M) ((void)0)
138
139/* #ifdef HAVE_PTHREAD */
140#endif
141
142/* #ifndef SH_PTHREAD_H */
143#endif
Note: See TracBrowser for help on using the repository browser.