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.  See libldap/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 #ifndef _LDAP_INT_THREAD_H
27 #define _LDAP_INT_THREAD_H
28 
29 #if defined( HAVE_PTHREADS )
30 /**********************************
31  *                                *
32  * definitions for POSIX Threads  *
33  *                                *
34  **********************************/
35 
36 #include <pthread.h>
37 #ifdef HAVE_SCHED_H
38 #include <sched.h>
39 #endif
40 
41 LDAP_BEGIN_DECL
42 
43 typedef pthread_t		ldap_int_thread_t;
44 typedef pthread_mutex_t		ldap_int_thread_mutex_t;
45 typedef pthread_cond_t		ldap_int_thread_cond_t;
46 typedef pthread_key_t		ldap_int_thread_key_t;
47 
48 #define ldap_int_thread_equal(a, b)	pthread_equal((a), (b))
49 
50 #if defined( _POSIX_REENTRANT_FUNCTIONS ) || \
51 	defined( _POSIX_THREAD_SAFE_FUNCTIONS ) || \
52 	defined( _POSIX_THREADSAFE_FUNCTIONS )
53 #define HAVE_REENTRANT_FUNCTIONS 1
54 #endif
55 
56 #if defined( HAVE_PTHREAD_GETCONCURRENCY ) || \
57 	defined( HAVE_THR_GETCONCURRENCY )
58 #define LDAP_THREAD_HAVE_GETCONCURRENCY 1
59 #endif
60 
61 #if defined( HAVE_PTHREAD_SETCONCURRENCY ) || \
62 	defined( HAVE_THR_SETCONCURRENCY )
63 #define LDAP_THREAD_HAVE_SETCONCURRENCY 1
64 #endif
65 
66 #if defined( HAVE_PTHREAD_RWLOCK_DESTROY )
67 #define LDAP_THREAD_HAVE_RDWR 1
68 typedef pthread_rwlock_t ldap_int_thread_rdwr_t;
69 #endif
70 
71 #ifndef LDAP_INT_MUTEX_NULL
72 #define LDAP_INT_MUTEX_NULL	PTHREAD_MUTEX_INITIALIZER
73 #define LDAP_INT_MUTEX_FIRSTCREATE(m)	((void) 0)
74 #endif
75 
76 LDAP_END_DECL
77 
78 #elif defined( HAVE_GNU_PTH )
79 /***********************************
80  *                                 *
81  * thread definitions for GNU Pth  *
82  *                                 *
83  ***********************************/
84 
85 #define PTH_SYSCALL_SOFT 1
86 #include <pth.h>
87 
88 LDAP_BEGIN_DECL
89 
90 typedef pth_t		ldap_int_thread_t;
91 typedef pth_mutex_t	ldap_int_thread_mutex_t;
92 typedef pth_cond_t	ldap_int_thread_cond_t;
93 typedef pth_key_t	ldap_int_thread_key_t;
94 
95 #if 0
96 #define LDAP_THREAD_HAVE_RDWR 1
97 typedef pth_rwlock_t ldap_int_thread_rdwr_t;
98 #endif
99 
100 #ifndef LDAP_INT_MUTEX_NULL
101 #define LDAP_INT_MUTEX_NULL	PTH_MUTEX_INIT
102 #define LDAP_INT_MUTEX_FIRSTCREATE(m)	((void) 0)
103 #endif
104 
105 LDAP_END_DECL
106 
107 #elif defined( HAVE_THR )
108 /********************************************
109  *                                          *
110  * thread definitions for Solaris LWP (THR) *
111  *                                          *
112  ********************************************/
113 
114 #include <thread.h>
115 #include <synch.h>
116 
117 LDAP_BEGIN_DECL
118 
119 typedef thread_t		ldap_int_thread_t;
120 typedef mutex_t			ldap_int_thread_mutex_t;
121 typedef cond_t			ldap_int_thread_cond_t;
122 typedef thread_key_t	ldap_int_thread_key_t;
123 
124 #define HAVE_REENTRANT_FUNCTIONS 1
125 
126 #ifdef HAVE_THR_GETCONCURRENCY
127 #define LDAP_THREAD_HAVE_GETCONCURRENCY 1
128 #endif
129 #ifdef HAVE_THR_SETCONCURRENCY
130 #define LDAP_THREAD_HAVE_SETCONCURRENCY 1
131 #endif
132 
133 #ifndef LDAP_INT_MUTEX_NULL
134 #define LDAP_INT_MUTEX_NULL	DEFAULTMUTEX
135 #define LDAP_INT_MUTEX_FIRSTCREATE(m)	((void) 0)
136 #endif
137 
138 #elif defined(HAVE_NT_THREADS)
139 /*************************************
140  *                                   *
141  * thread definitions for NT threads *
142  *                                   *
143  *************************************/
144 
145 #include <process.h>
146 #include <windows.h>
147 
148 LDAP_BEGIN_DECL
149 
150 typedef unsigned long	ldap_int_thread_t;
151 typedef HANDLE	ldap_int_thread_mutex_t;
152 typedef HANDLE	ldap_int_thread_cond_t;
153 typedef DWORD	ldap_int_thread_key_t;
154 
155 LDAP_F( int )
156 ldap_int_mutex_firstcreate LDAP_P(( ldap_int_thread_mutex_t *mutex ));
157 
158 #ifndef LDAP_INT_MUTEX_NULL
159 #define LDAP_INT_MUTEX_NULL		((HANDLE)0)
160 #define LDAP_INT_MUTEX_FIRSTCREATE(m) \
161 		ldap_int_mutex_firstcreate(&(m))
162 #endif
163 
164 LDAP_END_DECL
165 
166 #else
167 /***********************************
168  *                                 *
169  * thread definitions for no       *
170  * underlying library support      *
171  *                                 *
172  ***********************************/
173 
174 #ifndef NO_THREADS
175 #define NO_THREADS 1
176 #endif
177 
178 LDAP_BEGIN_DECL
179 
180 typedef int			ldap_int_thread_t;
181 typedef int			ldap_int_thread_mutex_t;
182 typedef int			ldap_int_thread_cond_t;
183 typedef int			ldap_int_thread_key_t;
184 
185 #define LDAP_THREAD_HAVE_TPOOL 1
186 typedef int			ldap_int_thread_pool_t;
187 
188 #ifndef LDAP_INT_MUTEX_NULL
189 #define LDAP_INT_MUTEX_NULL				0
190 #define LDAP_INT_MUTEX_FIRSTCREATE(m)	((void) 0)
191 #endif
192 
193 LDAP_END_DECL
194 
195 #endif /* no threads support */
196 
197 
198 LDAP_BEGIN_DECL
199 
200 #ifndef ldap_int_thread_equal
201 #define ldap_int_thread_equal(a, b)	((a) == (b))
202 #endif
203 
204 #ifndef LDAP_THREAD_HAVE_RDWR
205 typedef struct ldap_int_thread_rdwr_s * ldap_int_thread_rdwr_t;
206 #endif
207 
208 LDAP_F(int) ldap_int_thread_pool_startup ( void );
209 LDAP_F(int) ldap_int_thread_pool_shutdown ( void );
210 
211 #ifndef LDAP_THREAD_HAVE_TPOOL
212 typedef struct ldap_int_thread_pool_s * ldap_int_thread_pool_t;
213 #endif
214 LDAP_END_DECL
215 
216 
217 #if defined(LDAP_THREAD_DEBUG) && !((LDAP_THREAD_DEBUG +0) & 2U)
218 #define LDAP_THREAD_DEBUG_WRAP 1
219 #endif
220 
221 #ifdef LDAP_THREAD_DEBUG_WRAP
222 /**************************************
223  *                                    *
224  * definitions for type-wrapped debug *
225  *                                    *
226  **************************************/
227 
228 LDAP_BEGIN_DECL
229 
230 #ifndef LDAP_UINTPTR_T	/* May be configured in CPPFLAGS */
231 #define LDAP_UINTPTR_T	unsigned long
232 #endif
233 
234 typedef enum {
235 	ldap_debug_magic =	-(int) (((unsigned)-1)/19)
236 } ldap_debug_magic_t;
237 
238 typedef enum {
239 	/* Could fill in "locked" etc here later */
240 	ldap_debug_state_inited = (int) (((unsigned)-1)/11),
241 	ldap_debug_state_destroyed
242 } ldap_debug_state_t;
243 
244 typedef struct {
245 	/* Enclosed in magic numbers in the hope of catching overwrites */
246 	ldap_debug_magic_t	magic;	/* bit pattern to recognize usages  */
247 	LDAP_UINTPTR_T		self;	/* ~(LDAP_UINTPTR_T)&(this struct) */
248 	union ldap_debug_mem_u {	/* Dummy memory reference */
249 		unsigned char	*ptr;
250 		LDAP_UINTPTR_T	num;
251 	} mem;
252 	ldap_debug_state_t	state;	/* doubles as another magic number */
253 } ldap_debug_usage_info_t;
254 
255 typedef struct {
256 	ldap_int_thread_mutex_t	wrapped;
257 	ldap_debug_usage_info_t	usage;
258 	ldap_int_thread_t	owner;
259 } ldap_debug_thread_mutex_t;
260 
261 #define	LDAP_DEBUG_MUTEX_NULL	{LDAP_INT_MUTEX_NULL, {0,0,{0},0} /*,owner*/}
262 #define	LDAP_DEBUG_MUTEX_FIRSTCREATE(m) \
263 	((void) ((m).usage.state || ldap_pvt_thread_mutex_init(&(m))))
264 
265 typedef struct {
266 	ldap_int_thread_cond_t	wrapped;
267 	ldap_debug_usage_info_t	usage;
268 } ldap_debug_thread_cond_t;
269 
270 typedef struct {
271 	ldap_int_thread_rdwr_t	wrapped;
272 	ldap_debug_usage_info_t	usage;
273 } ldap_debug_thread_rdwr_t;
274 
275 #ifndef NDEBUG
276 #define	LDAP_INT_THREAD_ASSERT_MUTEX_OWNER(mutex) \
277 	ldap_debug_thread_assert_mutex_owner( \
278 		__FILE__, __LINE__, "owns(" #mutex ")", mutex )
279 LDAP_F(void) ldap_debug_thread_assert_mutex_owner LDAP_P((
280 	LDAP_CONST char *file,
281 	int line,
282 	LDAP_CONST char *msg,
283 	ldap_debug_thread_mutex_t *mutex ));
284 #endif /* NDEBUG */
285 
286 LDAP_END_DECL
287 
288 #endif /* LDAP_THREAD_DEBUG_WRAP */
289 
290 #endif /* _LDAP_INT_THREAD_H */
291