aboutsummaryrefslogtreecommitdiff
path: root/src/lib/mhd_threads.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/mhd_threads.h')
-rw-r--r--src/lib/mhd_threads.h229
1 files changed, 229 insertions, 0 deletions
diff --git a/src/lib/mhd_threads.h b/src/lib/mhd_threads.h
new file mode 100644
index 00000000..6d69b9ed
--- /dev/null
+++ b/src/lib/mhd_threads.h
@@ -0,0 +1,229 @@
1/*
2 This file is part of libmicrohttpd
3 Copyright (C) 2016 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
21/**
22 * @file microhttpd/mhd_threads.h
23 * @brief Header for platform-independent threads abstraction
24 * @author Karlson2k (Evgeny Grin)
25 *
26 * Provides basic abstraction for threads.
27 * Any functions can be implemented as macro on some platforms
28 * unless explicitly marked otherwise.
29 * Any function argument can be skipped in macro, so avoid
30 * variable modification in function parameters.
31 *
32 * @warning Unlike pthread functions, most of functions return
33 * nonzero on success.
34 */
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#else /* ! HAVE_STDDEF_H */
43# include <stdlib.h> /* for size_t */
44#endif /* ! HAVE_STDDEF_H */
45
46#if defined(MHD_USE_POSIX_THREADS)
47# undef HAVE_CONFIG_H
48# include <pthread.h>
49# define HAVE_CONFIG_H 1
50#elif defined(MHD_USE_W32_THREADS)
51# ifndef WIN32_LEAN_AND_MEAN
52# define WIN32_LEAN_AND_MEAN 1
53# endif /* !WIN32_LEAN_AND_MEAN */
54# include <windows.h>
55#else
56# error No threading API is available.
57#endif
58
59#ifndef MHD_NO_THREAD_NAMES
60# if defined(MHD_USE_POSIX_THREADS)
61# if defined(HAVE_PTHREAD_SETNAME_NP_GNU) || defined(HAVE_PTHREAD_SET_NAME_NP_FREEBSD) || \
62 defined(HAVE_PTHREAD_SETNAME_NP_DARWIN) || defined(HAVE_PTHREAD_SETNAME_NP_NETBSD) || \
63 defined(HAVE_PTHREAD_ATTR_SETNAME_NP_NETBSD) || defined(HAVE_PTHREAD_ATTR_SETNAME_NP_IBMI)
64# define MHD_USE_THREAD_NAME_
65# endif /* HAVE_PTHREAD_SETNAME_NP */
66# elif defined(MHD_USE_W32_THREADS)
67# ifdef _MSC_FULL_VER
68 /* Thread names only available with VC compiler */
69# define MHD_USE_THREAD_NAME_
70# endif /* _MSC_FULL_VER */
71# endif
72#endif
73
74#if defined(MHD_USE_POSIX_THREADS)
75 typedef pthread_t MHD_thread_handle_;
76#elif defined(MHD_USE_W32_THREADS)
77 typedef HANDLE MHD_thread_handle_;
78#endif
79
80#if defined(MHD_USE_POSIX_THREADS)
81# define MHD_THRD_RTRN_TYPE_ void*
82# define MHD_THRD_CALL_SPEC_
83#elif defined(MHD_USE_W32_THREADS)
84# define MHD_THRD_RTRN_TYPE_ unsigned
85# define MHD_THRD_CALL_SPEC_ __stdcall
86#endif
87
88#if defined(MHD_USE_POSIX_THREADS)
89 typedef pthread_t MHD_thread_ID_;
90#elif defined(MHD_USE_W32_THREADS)
91 typedef DWORD MHD_thread_ID_;
92#endif
93
94/* Depending on implementation, pthread_create() MAY set thread ID into
95 * provided pointer and after it start thread OR start thread and after
96 * if set thread ID. In latter case, to avoid data races, additional
97 * pthread_self() call is required in thread routine. Is some platform
98 * is known for setting thread ID BEFORE starting thread macro
99 * MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD could be defined
100 * to save some resources. */
101#if defined(MHD_USE_POSIX_THREADS)
102# ifdef MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD
103 union _MHD_thread_handle_ID_
104 {
105 MHD_thread_handle_ handle; /**< To be used in other threads */
106 MHD_thread_ID_ ID; /**< To be used in thread itself */
107 };
108 typedef union _MHD_thread_handle_ID_ MHD_thread_handle_ID_;
109# else /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */
110 struct _MHD_thread_handle_ID_
111 {
112 MHD_thread_handle_ handle; /**< To be used in other threads */
113 MHD_thread_ID_ ID; /**< To be used in thread itself */
114 };
115 typedef struct _MHD_thread_handle_ID_ MHD_thread_handle_ID_;
116# endif /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */
117#elif defined(MHD_USE_W32_THREADS)
118 struct _MHD_thread_handle_ID_
119 {
120 MHD_thread_handle_ handle; /**< To be used in other threads */
121 MHD_thread_ID_ ID; /**< To be used in thread itself */
122 };
123 typedef struct _MHD_thread_handle_ID_ MHD_thread_handle_ID_;
124#endif
125
126#if defined(MHD_USE_POSIX_THREADS)
127/**
128 * Wait until specified thread is ended and free thread handle on success.
129 * @param thread handle to watch
130 * @return nonzero on success, zero otherwise
131 */
132#define MHD_join_thread_(thread) (!pthread_join((thread), NULL))
133#elif defined(MHD_USE_W32_THREADS)
134/**
135 * Wait until specified thread is ended and free thread handle on success.
136 * @param thread handle to watch
137 * @return nonzero on success, zero otherwise
138 */
139#define MHD_join_thread_(thread) (WAIT_OBJECT_0 == WaitForSingleObject((thread), INFINITE) ? (CloseHandle((thread)), !0) : 0)
140#endif
141
142#if defined(MHD_USE_POSIX_THREADS)
143/**
144 * Check whether provided thread ID match current thread.
145 * @param ID thread ID to match
146 * @return nonzero on match, zero otherwise
147 */
148#define MHD_thread_ID_match_current_(ID) (pthread_equal((ID), pthread_self()))
149#elif defined(MHD_USE_W32_THREADS)
150/**
151 * Check whether provided thread ID match current thread.
152 * @param ID thread ID to match
153 * @return nonzero on match, zero otherwise
154 */
155#define MHD_thread_ID_match_current_(ID) (GetCurrentThreadId() == (ID))
156#endif
157
158#if defined(MHD_USE_POSIX_THREADS)
159# ifdef MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD
160/**
161 * Initialise thread ID.
162 * @param thread_handle_ID_ptr pointer to thread handle-ID
163 */
164#define MHD_thread_init_(thread_handle_ID_ptr) (void)0
165# else /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */
166/**
167 * Initialise thread ID.
168 * @param thread_handle_ID_ptr pointer to thread handle-ID
169 */
170#define MHD_thread_init_(thread_handle_ID_ptr) ((thread_handle_ID_ptr)->ID=pthread_self())
171# endif /* ! MHD_PTHREAD_CREATE__SET_ID_BEFORE_START_THREAD */
172#elif defined(MHD_USE_W32_THREADS)
173/**
174 * Initialise thread ID.
175 * @param thread_handle_ID_ptr pointer to thread handle-ID
176 */
177#define MHD_thread_init_(thread_handle_ID_ptr) ((thread_handle_ID_ptr)->ID=GetCurrentThreadId())
178#endif
179
180/**
181 * Signature of main function for a thread.
182 *
183 * @param cls closure argument for the function
184 * @return termination code from the thread
185 */
186typedef MHD_THRD_RTRN_TYPE_
187(MHD_THRD_CALL_SPEC_ *MHD_THREAD_START_ROUTINE_)(void *cls);
188
189
190/**
191 * Create a thread and set the attributes according to our options.
192 *
193 * If thread is created, thread handle must be freed by MHD_join_thread_().
194 *
195 * @param thread handle to initialize
196 * @param stack_size size of stack for new thread, 0 for default
197 * @param start_routine main function of thread
198 * @param arg argument for start_routine
199 * @return non-zero on success; zero otherwise
200 */
201int
202MHD_create_thread_ (MHD_thread_handle_ID_ *thread,
203 size_t stack_size,
204 MHD_THREAD_START_ROUTINE_ start_routine,
205 void *arg);
206
207#ifndef MHD_USE_THREAD_NAME_
208#define MHD_create_named_thread_(t,n,s,r,a) MHD_create_thread_((t),(s),(r),(a))
209#else /* MHD_USE_THREAD_NAME_ */
210/**
211 * Create a named thread and set the attributes according to our options.
212 *
213 * @param thread handle to initialize
214 * @param thread_name name for new thread
215 * @param stack_size size of stack for new thread, 0 for default
216 * @param start_routine main function of thread
217 * @param arg argument for start_routine
218 * @return non-zero on success; zero otherwise
219 */
220int
221MHD_create_named_thread_ (MHD_thread_handle_ID_ *thread,
222 const char* thread_name,
223 size_t stack_size,
224 MHD_THREAD_START_ROUTINE_ start_routine,
225 void *arg);
226
227#endif /* MHD_USE_THREAD_NAME_ */
228
229#endif /* ! MHD_THREADS_H */