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-2021 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 
18 LDAP_BEGIN_DECL
19 
20 /* Can be done twice in libldap_r.  See libldap_r/ldap_thr_debug.h. */
21 LDAP_F(int) ldap_int_thread_initialize LDAP_P(( void ));
22 LDAP_F(int) ldap_int_thread_destroy    LDAP_P(( void ));
23 
24 LDAP_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 
42 LDAP_BEGIN_DECL
43 
44 typedef pthread_t		ldap_int_thread_t;
45 typedef pthread_mutex_t		ldap_int_thread_mutex_t;
46 typedef pthread_cond_t		ldap_int_thread_cond_t;
47 typedef 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
69 typedef 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 
77 LDAP_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 
92 LDAP_BEGIN_DECL
93 
94 typedef cthread_t		ldap_int_thread_t;
95 typedef struct mutex		ldap_int_thread_mutex_t;
96 typedef struct condition	ldap_int_thread_cond_t;
97 typedef 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 
104 LDAP_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 
116 LDAP_BEGIN_DECL
117 
118 typedef pth_t		ldap_int_thread_t;
119 typedef pth_mutex_t	ldap_int_thread_mutex_t;
120 typedef pth_cond_t	ldap_int_thread_cond_t;
121 typedef pth_key_t	ldap_int_thread_key_t;
122 
123 #if 0
124 #define LDAP_THREAD_HAVE_RDWR 1
125 typedef 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 
133 LDAP_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 
145 LDAP_BEGIN_DECL
146 
147 typedef thread_t		ldap_int_thread_t;
148 typedef mutex_t			ldap_int_thread_mutex_t;
149 typedef cond_t			ldap_int_thread_cond_t;
150 typedef 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 
176 LDAP_BEGIN_DECL
177 
178 typedef unsigned long	ldap_int_thread_t;
179 typedef HANDLE	ldap_int_thread_mutex_t;
180 typedef HANDLE	ldap_int_thread_cond_t;
181 typedef DWORD	ldap_int_thread_key_t;
182 
183 LDAP_F( int )
184 ldap_int_mutex_firstcreate LDAP_P(( ldap_int_thread_mutex_t *mutex ));
185 
186 #ifndef LDAP_INT_MUTEX_NULL
187 #define LDAP_INT_MUTEX_NULL		((HANDLE)0)
188 #define LDAP_INT_MUTEX_FIRSTCREATE(m) \
189 		ldap_int_mutex_firstcreate(&(m))
190 #endif
191 
192 LDAP_END_DECL
193 
194 #else
195 /***********************************
196  *                                 *
197  * thread definitions for no       *
198  * underlying library support      *
199  *                                 *
200  ***********************************/
201 
202 #ifndef NO_THREADS
203 #define NO_THREADS 1
204 #endif
205 
206 LDAP_BEGIN_DECL
207 
208 typedef int			ldap_int_thread_t;
209 typedef int			ldap_int_thread_mutex_t;
210 typedef int			ldap_int_thread_cond_t;
211 typedef int			ldap_int_thread_key_t;
212 
213 #define LDAP_THREAD_HAVE_TPOOL 1
214 typedef int			ldap_int_thread_pool_t;
215 
216 #ifndef LDAP_INT_MUTEX_NULL
217 #define LDAP_INT_MUTEX_NULL				0
218 #define LDAP_INT_MUTEX_FIRSTCREATE(m)	((void) 0)
219 #endif
220 
221 LDAP_END_DECL
222 
223 #endif /* no threads support */
224 
225 
226 LDAP_BEGIN_DECL
227 
228 #ifndef ldap_int_thread_equal
229 #define ldap_int_thread_equal(a, b)	((a) == (b))
230 #endif
231 
232 #ifndef LDAP_THREAD_HAVE_RDWR
233 typedef struct ldap_int_thread_rdwr_s * ldap_int_thread_rdwr_t;
234 #endif
235 
236 LDAP_F(int) ldap_int_thread_pool_startup ( void );
237 LDAP_F(int) ldap_int_thread_pool_shutdown ( void );
238 
239 #ifndef LDAP_THREAD_HAVE_TPOOL
240 typedef struct ldap_int_thread_pool_s * ldap_int_thread_pool_t;
241 #endif
242 
243 typedef struct ldap_int_thread_rmutex_s * ldap_int_thread_rmutex_t;
244 LDAP_END_DECL
245 
246 
247 #if defined(LDAP_THREAD_DEBUG) && !((LDAP_THREAD_DEBUG +0) & 2U)
248 #define LDAP_THREAD_DEBUG_WRAP 1
249 #endif
250 
251 #ifdef LDAP_THREAD_DEBUG_WRAP
252 /**************************************
253  *                                    *
254  * definitions for type-wrapped debug *
255  *                                    *
256  **************************************/
257 
258 LDAP_BEGIN_DECL
259 
260 #ifndef LDAP_UINTPTR_T	/* May be configured in CPPFLAGS */
261 #define LDAP_UINTPTR_T	unsigned long
262 #endif
263 
264 typedef enum {
265 	ldap_debug_magic =	-(int) (((unsigned)-1)/19)
266 } ldap_debug_magic_t;
267 
268 typedef enum {
269 	/* Could fill in "locked" etc here later */
270 	ldap_debug_state_inited = (int) (((unsigned)-1)/11),
271 	ldap_debug_state_destroyed
272 } ldap_debug_state_t;
273 
274 typedef struct {
275 	/* Enclosed in magic numbers in the hope of catching overwrites */
276 	ldap_debug_magic_t	magic;	/* bit pattern to recognize usages  */
277 	LDAP_UINTPTR_T		self;	/* ~(LDAP_UINTPTR_T)&(this struct) */
278 	union ldap_debug_mem_u {	/* Dummy memory reference */
279 		unsigned char	*ptr;
280 		LDAP_UINTPTR_T	num;
281 	} mem;
282 	ldap_debug_state_t	state;	/* doubles as another magic number */
283 } ldap_debug_usage_info_t;
284 
285 typedef struct {
286 	ldap_int_thread_mutex_t	wrapped;
287 	ldap_debug_usage_info_t	usage;
288 	ldap_int_thread_t	owner;
289 } ldap_debug_thread_mutex_t;
290 
291 #define	LDAP_DEBUG_MUTEX_NULL	{LDAP_INT_MUTEX_NULL, {0,0,{0},0} /*,owner*/}
292 #define	LDAP_DEBUG_MUTEX_FIRSTCREATE(m) \
293 	((void) ((m).usage.state || ldap_pvt_thread_mutex_init(&(m))))
294 
295 typedef struct {
296 	ldap_int_thread_cond_t	wrapped;
297 	ldap_debug_usage_info_t	usage;
298 } ldap_debug_thread_cond_t;
299 
300 typedef struct {
301 	ldap_int_thread_rdwr_t	wrapped;
302 	ldap_debug_usage_info_t	usage;
303 } ldap_debug_thread_rdwr_t;
304 
305 #ifndef NDEBUG
306 #define	LDAP_INT_THREAD_ASSERT_MUTEX_OWNER(mutex) \
307 	ldap_debug_thread_assert_mutex_owner( \
308 		__FILE__, __LINE__, "owns(" #mutex ")", mutex )
309 LDAP_F(void) ldap_debug_thread_assert_mutex_owner LDAP_P((
310 	LDAP_CONST char *file,
311 	int line,
312 	LDAP_CONST char *msg,
313 	ldap_debug_thread_mutex_t *mutex ));
314 #endif /* NDEBUG */
315 
316 LDAP_END_DECL
317 
318 #endif /* LDAP_THREAD_DEBUG_WRAP */
319 
320 #endif /* _LDAP_INT_THREAD_H */
321