1/* ldap_int_thread.h - ldap internal thread wrappers header file */
2/* $OpenLDAP$ */
3/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 *
5 * Copyright 1998-2011 The OpenLDAP Foundation.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
10 * Public License.
11 *
12 * A copy of this license is available in file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
15 */
16
17
18LDAP_BEGIN_DECL
19
20/* Can be done twice in libldap_r.  See libldap_r/ldap_thr_debug.h. */
21LDAP_F(int) ldap_int_thread_initialize LDAP_P(( void ));
22LDAP_F(int) ldap_int_thread_destroy    LDAP_P(( void ));
23
24LDAP_END_DECL
25
26
27#ifndef _LDAP_INT_THREAD_H
28#define _LDAP_INT_THREAD_H
29
30#if defined( HAVE_PTHREADS )
31/**********************************
32 *                                *
33 * definitions for POSIX Threads  *
34 *                                *
35 **********************************/
36
37#include <pthread.h>
38#ifdef HAVE_SCHED_H
39#include <sched.h>
40#endif
41
42LDAP_BEGIN_DECL
43
44typedef pthread_t		ldap_int_thread_t;
45typedef pthread_mutex_t		ldap_int_thread_mutex_t;
46typedef pthread_cond_t		ldap_int_thread_cond_t;
47typedef pthread_key_t		ldap_int_thread_key_t;
48
49#define ldap_int_thread_equal(a, b)	pthread_equal((a), (b))
50
51#if defined( _POSIX_REENTRANT_FUNCTIONS ) || \
52	defined( _POSIX_THREAD_SAFE_FUNCTIONS ) || \
53	defined( _POSIX_THREADSAFE_FUNCTIONS )
54#define HAVE_REENTRANT_FUNCTIONS 1
55#endif
56
57#if defined( HAVE_PTHREAD_GETCONCURRENCY ) || \
58	defined( HAVE_THR_GETCONCURRENCY )
59#define LDAP_THREAD_HAVE_GETCONCURRENCY 1
60#endif
61
62#if defined( HAVE_PTHREAD_SETCONCURRENCY ) || \
63	defined( HAVE_THR_SETCONCURRENCY )
64#define LDAP_THREAD_HAVE_SETCONCURRENCY 1
65#endif
66
67#if defined( HAVE_PTHREAD_RWLOCK_DESTROY )
68#define LDAP_THREAD_HAVE_RDWR 1
69typedef pthread_rwlock_t ldap_int_thread_rdwr_t;
70#endif
71
72#ifndef LDAP_INT_MUTEX_NULL
73#define LDAP_INT_MUTEX_NULL	PTHREAD_MUTEX_INITIALIZER
74#define LDAP_INT_MUTEX_FIRSTCREATE(m)	((void) 0)
75#endif
76
77LDAP_END_DECL
78
79#elif defined ( HAVE_MACH_CTHREADS )
80/**********************************
81 *                                *
82 * definitions for Mach CThreads  *
83 *                                *
84 **********************************/
85
86#if defined( HAVE_MACH_CTHREADS_H )
87#	include <mach/cthreads.h>
88#elif defined( HAVE_CTHREADS_H )
89#	include <cthreads.h>
90#endif
91
92LDAP_BEGIN_DECL
93
94typedef cthread_t		ldap_int_thread_t;
95typedef struct mutex		ldap_int_thread_mutex_t;
96typedef struct condition	ldap_int_thread_cond_t;
97typedef cthread_key_t		ldap_int_thread_key_t;
98
99#ifndef LDAP_INT_MUTEX_NULL
100#define LDAP_INT_MUTEX_NULL	MUTEX_INITIALIZER
101#define LDAP_INT_MUTEX_FIRSTCREATE(m)	((void) 0)
102#endif
103
104LDAP_END_DECL
105
106#elif defined( HAVE_GNU_PTH )
107/***********************************
108 *                                 *
109 * thread definitions for GNU Pth  *
110 *                                 *
111 ***********************************/
112
113#define PTH_SYSCALL_SOFT 1
114#include <pth.h>
115
116LDAP_BEGIN_DECL
117
118typedef pth_t		ldap_int_thread_t;
119typedef pth_mutex_t	ldap_int_thread_mutex_t;
120typedef pth_cond_t	ldap_int_thread_cond_t;
121typedef pth_key_t	ldap_int_thread_key_t;
122
123#if 0
124#define LDAP_THREAD_HAVE_RDWR 1
125typedef pth_rwlock_t ldap_int_thread_rdwr_t;
126#endif
127
128#ifndef LDAP_INT_MUTEX_NULL
129#define LDAP_INT_MUTEX_NULL	PTH_MUTEX_INIT
130#define LDAP_INT_MUTEX_FIRSTCREATE(m)	((void) 0)
131#endif
132
133LDAP_END_DECL
134
135#elif defined( HAVE_THR )
136/********************************************
137 *                                          *
138 * thread definitions for Solaris LWP (THR) *
139 *                                          *
140 ********************************************/
141
142#include <thread.h>
143#include <synch.h>
144
145LDAP_BEGIN_DECL
146
147typedef thread_t		ldap_int_thread_t;
148typedef mutex_t			ldap_int_thread_mutex_t;
149typedef cond_t			ldap_int_thread_cond_t;
150typedef thread_key_t	ldap_int_thread_key_t;
151
152#define HAVE_REENTRANT_FUNCTIONS 1
153
154#ifdef HAVE_THR_GETCONCURRENCY
155#define LDAP_THREAD_HAVE_GETCONCURRENCY 1
156#endif
157#ifdef HAVE_THR_SETCONCURRENCY
158#define LDAP_THREAD_HAVE_SETCONCURRENCY 1
159#endif
160
161#ifndef LDAP_INT_MUTEX_NULL
162#define LDAP_INT_MUTEX_NULL	DEFAULTMUTEX
163#define LDAP_INT_MUTEX_FIRSTCREATE(m)	((void) 0)
164#endif
165
166#elif defined(HAVE_NT_THREADS)
167/*************************************
168 *                                   *
169 * thread definitions for NT threads *
170 *                                   *
171 *************************************/
172
173#include <process.h>
174#include <windows.h>
175
176LDAP_BEGIN_DECL
177
178typedef unsigned long	ldap_int_thread_t;
179typedef HANDLE	ldap_int_thread_mutex_t;
180typedef HANDLE	ldap_int_thread_cond_t;
181typedef DWORD	ldap_int_thread_key_t;
182
183#ifndef LDAP_INT_MUTEX_NULL
184#define LDAP_INT_MUTEX_NULL		((HANDLE)0)
185#define LDAP_INT_MUTEX_FIRSTCREATE(m) \
186		((void) ((m) || ldap_pvt_thread_mutex_init(&(m))))
187#endif
188
189LDAP_END_DECL
190
191#else
192/***********************************
193 *                                 *
194 * thread definitions for no       *
195 * underlying library support      *
196 *                                 *
197 ***********************************/
198
199#ifndef NO_THREADS
200#define NO_THREADS 1
201#endif
202
203LDAP_BEGIN_DECL
204
205typedef int			ldap_int_thread_t;
206typedef int			ldap_int_thread_mutex_t;
207typedef int			ldap_int_thread_cond_t;
208typedef int			ldap_int_thread_key_t;
209
210#define LDAP_THREAD_HAVE_TPOOL 1
211typedef int			ldap_int_thread_pool_t;
212
213#ifndef LDAP_INT_MUTEX_NULL
214#define LDAP_INT_MUTEX_NULL				0
215#define LDAP_INT_MUTEX_FIRSTCREATE(m)	((void) 0)
216#endif
217
218LDAP_END_DECL
219
220#endif /* no threads support */
221
222
223LDAP_BEGIN_DECL
224
225#ifndef ldap_int_thread_equal
226#define ldap_int_thread_equal(a, b)	((a) == (b))
227#endif
228
229#ifndef LDAP_THREAD_HAVE_RDWR
230typedef struct ldap_int_thread_rdwr_s * ldap_int_thread_rdwr_t;
231#endif
232
233LDAP_F(int) ldap_int_thread_pool_startup ( void );
234LDAP_F(int) ldap_int_thread_pool_shutdown ( void );
235
236#ifndef LDAP_THREAD_HAVE_TPOOL
237typedef struct ldap_int_thread_pool_s * ldap_int_thread_pool_t;
238#endif
239
240typedef struct ldap_int_thread_rmutex_s * ldap_int_thread_rmutex_t;
241LDAP_END_DECL
242
243
244#if defined(LDAP_THREAD_DEBUG) && !((LDAP_THREAD_DEBUG +0) & 2U)
245#define LDAP_THREAD_DEBUG_WRAP 1
246#endif
247
248#ifdef LDAP_THREAD_DEBUG_WRAP
249/**************************************
250 *                                    *
251 * definitions for type-wrapped debug *
252 *                                    *
253 **************************************/
254
255LDAP_BEGIN_DECL
256
257#ifndef LDAP_UINTPTR_T	/* May be configured in CPPFLAGS */
258#define LDAP_UINTPTR_T	unsigned long
259#endif
260
261typedef enum {
262	ldap_debug_magic =	-(int) (((unsigned)-1)/19)
263} ldap_debug_magic_t;
264
265typedef enum {
266	/* Could fill in "locked" etc here later */
267	ldap_debug_state_inited = (int) (((unsigned)-1)/11),
268	ldap_debug_state_destroyed
269} ldap_debug_state_t;
270
271typedef struct {
272	/* Enclosed in magic numbers in the hope of catching overwrites */
273	ldap_debug_magic_t	magic;	/* bit pattern to recognize usages  */
274	LDAP_UINTPTR_T		self;	/* ~(LDAP_UINTPTR_T)&(this struct) */
275	union ldap_debug_mem_u {	/* Dummy memory reference */
276		unsigned char	*ptr;
277		LDAP_UINTPTR_T	num;
278	} mem;
279	ldap_debug_state_t	state;	/* doubles as another magic number */
280} ldap_debug_usage_info_t;
281
282typedef struct {
283	ldap_int_thread_mutex_t	wrapped;
284	ldap_debug_usage_info_t	usage;
285	ldap_int_thread_t	owner;
286} ldap_debug_thread_mutex_t;
287
288#define	LDAP_DEBUG_MUTEX_NULL	{LDAP_INT_MUTEX_NULL, {0,0,{0},0} /*,owner*/}
289#define	LDAP_DEBUG_MUTEX_FIRSTCREATE(m) \
290	((void) ((m).usage.state || ldap_pvt_thread_mutex_init(&(m))))
291
292typedef struct {
293	ldap_int_thread_cond_t	wrapped;
294	ldap_debug_usage_info_t	usage;
295} ldap_debug_thread_cond_t;
296
297typedef struct {
298	ldap_int_thread_rdwr_t	wrapped;
299	ldap_debug_usage_info_t	usage;
300} ldap_debug_thread_rdwr_t;
301
302#ifndef NDEBUG
303#define	LDAP_INT_THREAD_ASSERT_MUTEX_OWNER(mutex) \
304	ldap_debug_thread_assert_mutex_owner( \
305		__FILE__, __LINE__, "owns(" #mutex ")", mutex )
306LDAP_F(void) ldap_debug_thread_assert_mutex_owner LDAP_P((
307	LDAP_CONST char *file,
308	int line,
309	LDAP_CONST char *msg,
310	ldap_debug_thread_mutex_t *mutex ));
311#endif /* NDEBUG */
312
313LDAP_END_DECL
314
315#endif /* LDAP_THREAD_DEBUG_WRAP */
316
317#endif /* _LDAP_INT_THREAD_H */
318