GNU libmicrohttpd
1.0.6
Toggle main menu visibility
Loading...
Searching...
No Matches
mhd_threads.h
Go to the documentation of this file.
1
/*
2
This file is part of libmicrohttpd
3
Copyright (C) 2016-2023 Karlson2k (Evgeny Grin)
4
5
This library is free software; you can redistribute it and/or
6
modify it under the terms of the GNU Lesser General Public
7
License as published by the Free Software Foundation; either
8
version 2.1 of the License, or (at your option) any later version.
9
10
This library is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
Lesser General Public License for more details.
14
15
You should have received a copy of the GNU Lesser General Public
16
License along with this library; if not, write to the Free Software
17
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
19
*/
20
35
36
#ifndef MHD_THREADS_H
37
#define MHD_THREADS_H 1
38
39
#include "
mhd_options.h
"
40
#ifdef HAVE_STDDEF_H
41
# include <stddef.h>
/* for size_t */
42
#elif defined(HAVE_STDLIB_H)
43
# include <stdlib.h>
/* for size_t */
44
#else
/* ! HAVE_STDLIB_H */
45
# include <stdio.h>
/* for size_t */
46
#endif
/* ! HAVE_STDLIB_H */
47
48
#if defined(MHD_USE_POSIX_THREADS)
49
# undef HAVE_CONFIG_H
50
# include <pthread.h>
51
# define HAVE_CONFIG_H 1
52
# ifndef MHD_USE_THREADS
53
# define MHD_USE_THREADS 1
54
# endif
55
#elif defined(MHD_USE_W32_THREADS)
56
# ifndef WIN32_LEAN_AND_MEAN
57
# define WIN32_LEAN_AND_MEAN 1
58
# endif
/* !WIN32_LEAN_AND_MEAN */
59
# include <windows.h>
60
# ifndef MHD_USE_THREADS
61
# define MHD_USE_THREADS 1
62
# endif
63
#else
64
# error No threading API is available.
65
#endif
66
67
#ifdef HAVE_STDBOOL_H
68
# include <stdbool.h>
69
#endif
/* HAVE_STDBOOL_H */
70
71
#if defined(MHD_USE_POSIX_THREADS) && defined(MHD_USE_W32_THREADS)
72
# error Both MHD_USE_POSIX_THREADS and MHD_USE_W32_THREADS are defined
73
#endif
/* MHD_USE_POSIX_THREADS && MHD_USE_W32_THREADS */
74
75
#ifndef MHD_NO_THREAD_NAMES
76
# if defined(MHD_USE_POSIX_THREADS)
77
# if defined(HAVE_PTHREAD_SETNAME_NP_GNU) || \
78
defined(HAVE_PTHREAD_SET_NAME_NP_FREEBSD) || \
79
defined(HAVE_PTHREAD_SETNAME_NP_DARWIN) || \
80
defined(HAVE_PTHREAD_SETNAME_NP_NETBSD) || \
81
defined(HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD) || \
82
defined(HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI)
83
# define MHD_USE_THREAD_NAME_
84
# endif
/* HAVE_PTHREAD_SETNAME_NP */
85
# elif defined(MHD_USE_W32_THREADS)
86
# ifdef _MSC_FULL_VER
87
/* Thread names only available with VC compiler */
88
# define MHD_USE_THREAD_NAME_
89
# endif
/* _MSC_FULL_VER */
90
# endif
91
#endif
92
93
/* ** Thread handle - used to control the thread ** */
94
95
#if defined(MHD_USE_POSIX_THREADS)
101
# define MHD_join_thread_(native_handle) \
102
(! pthread_join ((native_handle), NULL))
103
#elif defined(MHD_USE_W32_THREADS)
109
# define MHD_join_thread_(native_handle) \
110
( (WAIT_OBJECT_0 == WaitForSingleObject ( (native_handle), INFINITE)) ? \
111
(CloseHandle ( (native_handle)), ! 0) : 0 )
112
#endif
113
114
#if defined(MHD_USE_POSIX_THREADS)
118
typedef
pthread_t MHD_thread_handle_native_;
119
#elif defined(MHD_USE_W32_THREADS)
123
typedef
HANDLE MHD_thread_handle_native_;
124
#endif
125
126
#if defined(MHD_USE_POSIX_THREADS)
127
# if defined(__gnu_linux__) || \
128
(defined(__linux__) && defined(__GLIBC__))
129
/* The next part of code is disabled because it relies on undocumented
130
behaviour.
131
It could be enabled for neglectable performance and size improvements. */
132
# if 0
/* Disabled code */
136
# define MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_ \
137
((MHD_thread_handle_native_) 0)
138
# endif
/* Disabled code */
139
# endif
/* __gnu_linux__ || (__linux__ && __GLIBC__) */
140
#elif defined(MHD_USE_W32_THREADS)
144
# define MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_ \
145
((MHD_thread_handle_native_) NULL)
146
#endif
/* MHD_USE_W32_THREADS */
147
148
#if ! defined(MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_)
152
struct
MHD_thread_handle_struct_
153
{
154
bool
valid
;
155
MHD_thread_handle_native_
native
;
156
};
157
160
typedef
struct
MHD_thread_handle_struct_
MHD_thread_handle_
;
161
165
# define MHD_thread_handle_set_invalid_(handle_ptr) \
166
((handle_ptr)->valid = false)
167
171
# define MHD_thread_handle_set_native_(handle_ptr,native_val) \
172
((handle_ptr)->valid = true, (handle_ptr)->native = native_val)
173
176
# define MHD_thread_handle_is_valid_(handle_var) \
177
((handle_var).valid)
178
181
# define MHD_thread_handle_get_native_(handle_var) \
182
((handle_var).native)
183
#else
/* MHD_THREAD_HANDLE_NATIVE_INVALID_ */
187
typedef
MHD_thread_handle_native_
MHD_thread_handle_
;
188
192
# define MHD_thread_handle_set_invalid_(handle_ptr) \
193
((*(handle_ptr)) = MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_)
198
# define MHD_thread_handle_set_native_(handle_ptr,native_val) \
199
((*(handle_ptr)) = native_val)
203
# define MHD_thread_handle_is_valid_(handle_var) \
204
(MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_ != handle_var)
208
# define MHD_thread_handle_get_native_(handle_var) \
209
(handle_var)
215
# define MHD_thread_handle_get_native_ptr_(handle_ptr) \
216
(handle_ptr)
217
#endif
/* MHD_THREAD_HANDLE_NATIVE_INVALID_ */
218
219
220
/* ** Thread ID - used to check threads match ** */
221
222
#if defined(MHD_USE_POSIX_THREADS)
226
typedef
pthread_t MHD_thread_ID_native_;
227
231
# define MHD_thread_ID_native_current_ pthread_self
232
237
# define MHD_thread_ID_native_equal_(id1,id2) \
238
(pthread_equal(id1,id2))
239
#elif defined(MHD_USE_W32_THREADS)
243
typedef
DWORD MHD_thread_ID_native_;
244
248
# define MHD_thread_ID_native_current_ GetCurrentThreadId
249
254
# define MHD_thread_ID_native_equal_(id1,id2) \
255
((id1) == (id2))
256
#endif
257
263
#define MHD_thread_ID_native_is_current_thread_(id) \
264
MHD_thread_ID_native_equal_(id, MHD_thread_ID_native_current_())
265
266
267
#if defined(MHD_USE_POSIX_THREADS)
268
# if defined(MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_)
272
# define MHD_THREAD_ID_NATIVE_VALUE_INVALID_ \
273
MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_
274
# endif
/* MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_ */
275
#elif defined(MHD_USE_W32_THREADS)
279
# define MHD_THREAD_ID_NATIVE_VALUE_INVALID_ \
280
((MHD_thread_ID_native_) 0)
281
#endif
/* MHD_USE_W32_THREADS */
282
283
#if ! defined(MHD_THREAD_ID_NATIVE_VALUE_INVALID_)
287
struct
MHD_thread_ID_struct_
288
{
289
bool
valid
;
290
MHD_thread_ID_native_
native
;
291
};
292
295
typedef
struct
MHD_thread_ID_struct_
MHD_thread_ID_
;
296
300
# define MHD_thread_ID_set_invalid_(ID_ptr) \
301
((ID_ptr)->valid = false)
302
306
# define MHD_thread_ID_set_native_(ID_ptr,native_val) \
307
((ID_ptr)->valid = true, (ID_ptr)->native = native_val)
308
311
# define MHD_thread_ID_is_valid_(ID_var) \
312
((ID_var).valid)
313
316
# define MHD_thread_ID_get_native_(ID_var) \
317
((ID_var).native)
318
321
# define MHD_thread_ID_is_current_thread_(ID_var) \
322
(MHD_thread_ID_is_valid_(ID_var) && \
323
MHD_thread_ID_native_is_current_thread_((ID_var).native))
324
#else
/* MHD_THREAD_ID_NATIVE_INVALID_ */
328
typedef
MHD_thread_ID_native_
MHD_thread_ID_
;
329
333
# define MHD_thread_ID_set_invalid_(ID_ptr) \
334
((*(ID_ptr)) = MHD_THREAD_ID_NATIVE_VALUE_INVALID_)
339
# define MHD_thread_ID_set_native_(ID_ptr,native_val) \
340
((*(ID_ptr)) = native_val)
344
# define MHD_thread_ID_is_valid_(ID_var) \
345
(MHD_THREAD_ID_NATIVE_VALUE_INVALID_ != ID_var)
349
# define MHD_thread_ID_get_native_(ID_var) \
350
(ID_var)
354
# define MHD_thread_ID_is_current_thread_(ID_var) \
355
MHD_thread_ID_native_is_current_thread_(ID_var)
356
#endif
/* MHD_THREAD_ID_NATIVE_INVALID_ */
357
361
# define MHD_thread_ID_set_current_thread_(ID_ptr) \
362
MHD_thread_ID_set_native_(ID_ptr,MHD_thread_ID_native_current_())
363
364
365
#if defined(MHD_USE_POSIX_THREADS)
366
# if defined(MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_) && \
367
! defined(MHD_THREAD_ID_NATIVE_VALUE_INVALID_)
368
# error \
369
MHD_THREAD_ID_NATIVE_VALUE_INVALID_ is defined, but MHD_THREAD_ID_NATIVE_VALUE_INVALID_ is not defined
370
# elif ! defined(MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_) && \
371
defined(MHD_THREAD_ID_NATIVE_VALUE_INVALID_)
372
# error \
373
MHD_THREAD_ID_NATIVE_VALUE_INVALID_ is not defined, but MHD_THREAD_ID_NATIVE_VALUE_INVALID_ is defined
374
# endif
375
#endif
/* MHD_USE_POSIX_THREADS */
376
377
/* When staring a new thread, the kernel (and thread implementation) may
378
* pause the calling (initial) thread and start the new thread.
379
* If thread identifier is assigned to variable in the initial thread then
380
* the value of the identifier variable will be undefined in the new thread
381
* until the initial thread continue processing.
382
* However, it is also possible that the new thread created, but not executed
383
* for some time while the initial thread continue execution. In this case any
384
* variable assigned in the new thread will be undefined for some time until
385
* they really processed by the new thread.
386
* To avoid data races, a special structure MHD_thread_handle_ID_ is used.
387
* The "handle" is assigned by calling (initial) thread and should be always
388
* defined when checked in the initial thread.
389
* The "ID" is assigned by the new thread and should be always defined when
390
* checked inside the new thread.
391
*/
392
/* Depending on implementation, pthread_create() MAY set thread ID into
393
* provided pointer and after it start thread OR start thread and after
394
* it set thread ID. In the latter case, to avoid data races, additional
395
* pthread_self() call is required in thread routine. If some platform
396
* is known for setting thread ID BEFORE starting thread macro
397
* MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD could be defined
398
* to save some resources. */
399
/* #define MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD 1 */
400
401
/* * handle - must be valid when other thread knows that particular thread
402
is started.
403
* ID - must be valid when code is executed inside thread */
404
#if defined(MHD_USE_POSIX_THREADS) && \
405
defined(MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD) && \
406
defined(MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_) && \
407
defined(MHD_THREAD_ID_NATIVE_VALUE_INVALID_) && \
408
defined(MHD_thread_handle_get_native_ptr_)
409
union
_MHD_thread_handle_ID_
410
{
411
MHD_thread_handle_
handle
;
412
MHD_thread_ID_
ID
;
413
};
414
typedef
union
_MHD_thread_handle_ID_
MHD_thread_handle_ID_
;
415
# define MHD_THREAD_HANDLE_ID_IS_UNION 1
416
#else
/* !MHD_USE_POSIX_THREADS
417
|| !MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD
418
|| !MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_
419
|| !MHD_THREAD_ID_NATIVE_VALUE_INVALID_
420
|| !MHD_thread_handle_get_native_ptr_ */
421
struct
_MHD_thread_handle_ID_
422
{
423
MHD_thread_handle_
handle
;
424
MHD_thread_ID_
ID
;
425
};
426
typedef
struct
_MHD_thread_handle_ID_
MHD_thread_handle_ID_
;
427
#endif
/* !MHD_USE_POSIX_THREADS
428
|| !MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD
429
|| !MHD_THREAD_HANDLE_NATIVE_VALUE_INVALID_
430
|| !MHD_THREAD_ID_NATIVE_VALUE_INVALID_
431
|| !MHD_thread_handle_get_native_ptr_ */
432
436
#define MHD_thread_handle_ID_set_invalid_(hndl_id_ptr) \
437
(MHD_thread_handle_set_invalid_(&((hndl_id_ptr)->handle)), \
438
MHD_thread_ID_set_invalid_(&((hndl_id_ptr)->ID)))
439
444
#define MHD_thread_handle_ID_is_valid_handle_(hndl_id) \
445
MHD_thread_handle_is_valid_((hndl_id).handle)
446
451
#define MHD_thread_handle_ID_set_native_handle_(hndl_id_ptr,native_val) \
452
MHD_thread_handle_set_native_(&((hndl_id_ptr)->handle),native_val)
453
454
#if defined(MHD_thread_handle_get_native_ptr_)
460
# define MHD_thread_handle_ID_get_native_handle_ptr_(hndl_id_ptr) \
461
MHD_thread_handle_get_native_ptr_(&((hndl_id_ptr)->handle))
462
#endif
/* MHD_thread_handle_get_native_ptr_ */
463
467
#define MHD_thread_handle_ID_get_native_handle_(hndl_id) \
468
MHD_thread_handle_get_native_((hndl_id).handle)
469
474
#define MHD_thread_handle_ID_is_valid_ID_(hndl_id) \
475
MHD_thread_ID_is_valid_((hndl_id).ID)
476
477
#if defined(MHD_THREAD_HANDLE_ID_IS_UNION)
478
# if defined(MHD_USE_W32_THREADS)
479
# error MHD_thread_handle_ID_ cannot be a union with W32 threads
480
# endif
/* MHD_USE_W32_THREADS */
484
# define MHD_thread_handle_ID_set_current_thread_ID_(hndl_id_ptr) (void) 0
485
#else
/* ! MHD_THREAD_HANDLE_ID_IS_UNION */
489
# define MHD_thread_handle_ID_set_current_thread_ID_(hndl_id_ptr) \
490
MHD_thread_ID_set_current_thread_(&((hndl_id_ptr)->ID))
491
#endif
/* ! MHD_THREAD_HANDLE_ID_IS_UNION */
492
498
#define MHD_thread_handle_ID_is_current_thread_(hndl_id) \
499
MHD_thread_ID_is_current_thread_((hndl_id).ID)
500
506
#define MHD_thread_handle_ID_join_thread_(hndl_id) \
507
MHD_join_thread_(MHD_thread_handle_ID_get_native_handle_(hndl_id))
508
509
#if defined(MHD_USE_POSIX_THREADS)
510
# define MHD_THRD_RTRN_TYPE_ void*
511
# define MHD_THRD_CALL_SPEC_
512
#elif defined(MHD_USE_W32_THREADS)
513
# define MHD_THRD_RTRN_TYPE_ unsigned
514
# define MHD_THRD_CALL_SPEC_ __stdcall
515
#endif
516
523
typedef
MHD_THRD_RTRN_TYPE_
524
(MHD_THRD_CALL_SPEC_ *
MHD_THREAD_START_ROUTINE_
)(
void
*cls);
525
526
538
int
539
MHD_create_thread_
(
MHD_thread_handle_ID_
*handle_id,
540
size_t
stack_size,
541
MHD_THREAD_START_ROUTINE_
start_routine,
542
void
*arg);
543
544
#ifndef MHD_USE_THREAD_NAME_
545
#define MHD_create_named_thread_(t,n,s,r,a) MHD_create_thread_ ((t),(s),(r),(a))
546
#else
/* MHD_USE_THREAD_NAME_ */
557
int
558
MHD_create_named_thread_
(
MHD_thread_handle_ID_
*handle_id,
559
const
char
*thread_name,
560
size_t
stack_size,
561
MHD_THREAD_START_ROUTINE_
start_routine,
562
void
*arg);
563
564
#endif
/* MHD_USE_THREAD_NAME_ */
565
566
#endif
/* ! MHD_THREADS_H */
mhd_options.h
additional automatic macros for MHD_config.h
MHD_thread_handle_ID_
struct _MHD_thread_handle_ID_ MHD_thread_handle_ID_
Definition
mhd_threads.h:426
MHD_thread_handle_
struct MHD_thread_handle_struct_ MHD_thread_handle_
Definition
mhd_threads.h:160
MHD_create_thread_
int MHD_create_thread_(MHD_thread_handle_ID_ *handle_id, size_t stack_size, MHD_THREAD_START_ROUTINE_ start_routine, void *arg)
Definition
mhd_threads.c:187
MHD_thread_ID_
struct MHD_thread_ID_struct_ MHD_thread_ID_
Definition
mhd_threads.h:295
MHD_THREAD_START_ROUTINE_
MHD_THRD_RTRN_TYPE_(MHD_THRD_CALL_SPEC_ * MHD_THREAD_START_ROUTINE_)(void *cls)
Definition
mhd_threads.h:524
MHD_create_named_thread_
#define MHD_create_named_thread_(t, n, s, r, a)
Definition
mhd_threads.h:545
MHD_thread_ID_struct_
Definition
mhd_threads.h:288
MHD_thread_ID_struct_::valid
bool valid
Definition
mhd_threads.h:289
MHD_thread_ID_struct_::native
MHD_thread_ID_native_ native
Definition
mhd_threads.h:290
MHD_thread_handle_struct_
Definition
mhd_threads.h:153
MHD_thread_handle_struct_::valid
bool valid
Definition
mhd_threads.h:154
MHD_thread_handle_struct_::native
MHD_thread_handle_native_ native
Definition
mhd_threads.h:155
_MHD_thread_handle_ID_
Definition
mhd_threads.h:422
_MHD_thread_handle_ID_::ID
MHD_thread_ID_ ID
Definition
mhd_threads.h:424
_MHD_thread_handle_ID_::handle
MHD_thread_handle_ handle
Definition
mhd_threads.h:423
src
microhttpd
mhd_threads.h
Generated by
1.17.0