diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2016-08-10 13:52:38 +0000 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2016-08-10 13:52:38 +0000 |
commit | e18185c55f8d1b6d6efe1b6a35b4c8c7bd48754a (patch) | |
tree | f0944fff5d0918803b202eb40da58b9b942982c3 | |
parent | eb46a43bc014b1d5e151fc53996aef14c29fec55 (diff) | |
download | libmicrohttpd-e18185c55f8d1b6d6efe1b6a35b4c8c7bd48754a.tar.gz libmicrohttpd-e18185c55f8d1b6d6efe1b6a35b4c8c7bd48754a.zip |
Moved thread abstraction to mhd_threads.h/mhd_threads.c,
minor bugs fixed.
-rw-r--r-- | configure.ac | 10 | ||||
-rw-r--r-- | src/include/platform.h | 5 | ||||
-rw-r--r-- | src/include/platform_interface.h | 35 | ||||
-rw-r--r-- | src/include/w32functions.h | 13 | ||||
-rw-r--r-- | src/microhttpd/Makefile.am | 3 | ||||
-rw-r--r-- | src/microhttpd/daemon.c | 120 | ||||
-rw-r--r-- | src/microhttpd/internal.h | 1 | ||||
-rw-r--r-- | src/microhttpd/mhd_limits.h | 8 | ||||
-rw-r--r-- | src/microhttpd/mhd_threads.c | 274 | ||||
-rw-r--r-- | src/microhttpd/mhd_threads.h | 151 | ||||
-rw-r--r-- | src/microhttpd/test_shutdown_select.c | 4 | ||||
-rw-r--r-- | src/platform/w32functions.c | 36 | ||||
-rw-r--r-- | w32/common/MHD_config.h | 3 | ||||
-rw-r--r-- | w32/common/libmicrohttpd-files.vcxproj | 2 | ||||
-rw-r--r-- | w32/common/libmicrohttpd-filters.vcxproj | 6 |
15 files changed, 481 insertions, 190 deletions
diff --git a/configure.ac b/configure.ac index e5ea2590..b9918093 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -247,7 +247,11 @@ test "x$with_threads" = "xpthreads" && with_threads='posix' | |||
247 | 247 | ||
248 | # Check for posix threads support, regardless of configure parameters as | 248 | # Check for posix threads support, regardless of configure parameters as |
249 | # posix threads are used in some tests even on W32. | 249 | # posix threads are used in some tests even on W32. |
250 | AX_PTHREAD([HAVE_POSIX_THREADS='yes'],[HAVE_POSIX_THREADS='no']) | 250 | AX_PTHREAD( |
251 | [ | ||
252 | HAVE_POSIX_THREADS='yes' | ||
253 | AC_DEFINE([[HAVE_PTHREAD_H]],[[1]],[Define to 1 if you have the <pthread.h> header file.]) | ||
254 | ],[[HAVE_POSIX_THREADS='no']]) | ||
251 | AM_CONDITIONAL([HAVE_POSIX_THREADS],[test "x$HAVE_POSIX_THREADS" = "xyes"]) | 255 | AM_CONDITIONAL([HAVE_POSIX_THREADS],[test "x$HAVE_POSIX_THREADS" = "xyes"]) |
252 | 256 | ||
253 | HAVE_W32_THREADS='no' | 257 | HAVE_W32_THREADS='no' |
@@ -418,10 +422,10 @@ if test "x$HAVE_POSIX_THREADS" = "xyes"; then | |||
418 | fi | 422 | fi |
419 | 423 | ||
420 | # Check for headers that are ALWAYS required | 424 | # Check for headers that are ALWAYS required |
421 | AC_CHECK_HEADERS([fcntl.h math.h errno.h limits.h stdio.h locale.h sys/stat.h sys/types.h pthread.h],,AC_MSG_ERROR([Compiling libmicrohttpd requires standard UNIX headers files])) | 425 | AC_CHECK_HEADERS([fcntl.h math.h errno.h limits.h stdio.h locale.h sys/stat.h sys/types.h],,AC_MSG_ERROR([Compiling libmicrohttpd requires standard UNIX headers files])) |
422 | 426 | ||
423 | # Check for optional headers | 427 | # Check for optional headers |
424 | AC_CHECK_HEADERS([sys/types.h sys/time.h sys/msg.h netdb.h netinet/in.h netinet/tcp.h time.h sys/socket.h sys/mman.h arpa/inet.h sys/select.h search.h endian.h machine/endian.h sys/endian.h sys/param.h sys/machine.h sys/byteorder.h machine/param.h sys/isa_defs.h inttypes.h]) | 428 | AC_CHECK_HEADERS([sys/types.h sys/time.h sys/msg.h netdb.h netinet/in.h netinet/tcp.h time.h sys/socket.h sys/mman.h arpa/inet.h sys/select.h search.h endian.h machine/endian.h sys/endian.h sys/param.h sys/machine.h sys/byteorder.h machine/param.h sys/isa_defs.h inttypes.h stddef.h]) |
425 | AM_CONDITIONAL([HAVE_TSEARCH], [test "x$ac_cv_header_search_h" = "xyes"]) | 429 | AM_CONDITIONAL([HAVE_TSEARCH], [test "x$ac_cv_header_search_h" = "xyes"]) |
426 | 430 | ||
427 | AC_CHECK_MEMBER([struct sockaddr_in.sin_len], | 431 | AC_CHECK_MEMBER([struct sockaddr_in.sin_len], |
diff --git a/src/include/platform.h b/src/include/platform.h index ed09fc71..5ec2c16f 100644 --- a/src/include/platform.h +++ b/src/include/platform.h | |||
@@ -48,11 +48,6 @@ | |||
48 | #include <fcntl.h> | 48 | #include <fcntl.h> |
49 | #include <signal.h> | 49 | #include <signal.h> |
50 | #include <stddef.h> | 50 | #include <stddef.h> |
51 | #ifdef MHD_USE_POSIX_THREADS | ||
52 | #undef HAVE_CONFIG_H | ||
53 | #include <pthread.h> | ||
54 | #define HAVE_CONFIG_H 1 | ||
55 | #endif /* MHD_USE_POSIX_THREADS */ | ||
56 | 51 | ||
57 | /* different OSes have fd_set in | 52 | /* different OSes have fd_set in |
58 | a broad range of header files; | 53 | a broad range of header files; |
diff --git a/src/include/platform_interface.h b/src/include/platform_interface.h index eba7612b..13f54530 100644 --- a/src/include/platform_interface.h +++ b/src/include/platform_interface.h | |||
@@ -189,41 +189,6 @@ typedef int _MHD_socket_funcs_size; | |||
189 | #else | 189 | #else |
190 | #define MHD_random_() MHD_W32_random_() | 190 | #define MHD_random_() MHD_W32_random_() |
191 | #endif | 191 | #endif |
192 | |||
193 | #if defined(MHD_USE_POSIX_THREADS) | ||
194 | typedef pthread_t MHD_thread_handle_; | ||
195 | #elif defined(MHD_USE_W32_THREADS) | ||
196 | #include <windows.h> | ||
197 | typedef HANDLE MHD_thread_handle_; | ||
198 | #else | ||
199 | #error "No threading API is available." | ||
200 | #endif | ||
201 | |||
202 | #if defined(MHD_USE_POSIX_THREADS) | ||
203 | #define MHD_THRD_RTRN_TYPE_ void* | ||
204 | #define MHD_THRD_CALL_SPEC_ | ||
205 | #elif defined(MHD_USE_W32_THREADS) | ||
206 | #define MHD_THRD_RTRN_TYPE_ unsigned | ||
207 | #define MHD_THRD_CALL_SPEC_ __stdcall | ||
208 | #endif | ||
209 | |||
210 | #if defined(MHD_USE_POSIX_THREADS) | ||
211 | /** | ||
212 | * Wait until specified thread is ended | ||
213 | * @param thread ID to watch | ||
214 | * @return zero on success, nonzero on failure | ||
215 | */ | ||
216 | #define MHD_join_thread_(thread) pthread_join((thread), NULL) | ||
217 | #elif defined(MHD_USE_W32_THREADS) | ||
218 | /** | ||
219 | * Wait until specified thread is ended | ||
220 | * Close thread handle on success | ||
221 | * @param thread handle to watch | ||
222 | * @return zero on success, nonzero on failure | ||
223 | */ | ||
224 | #define MHD_join_thread_(thread) (WAIT_OBJECT_0 == WaitForSingleObject((thread), INFINITE) ? (CloseHandle((thread)), 0) : 1 ) | ||
225 | #endif | ||
226 | |||
227 | #if defined(MHD_USE_W32_THREADS) | 192 | #if defined(MHD_USE_W32_THREADS) |
228 | #define MHD_W32_MUTEX_ 1 | 193 | #define MHD_W32_MUTEX_ 1 |
229 | #include <windows.h> | 194 | #include <windows.h> |
diff --git a/src/include/w32functions.h b/src/include/w32functions.h index 057a989e..508778c9 100644 --- a/src/include/w32functions.h +++ b/src/include/w32functions.h | |||
@@ -194,19 +194,6 @@ int MHD_W32_random_(void); | |||
194 | /* Emulate snprintf function on W32 */ | 194 | /* Emulate snprintf function on W32 */ |
195 | int W32_snprintf(char *__restrict s, size_t n, const char *__restrict format, ...); | 195 | int W32_snprintf(char *__restrict s, size_t n, const char *__restrict format, ...); |
196 | 196 | ||
197 | #ifndef _MSC_FULL_VER | ||
198 | /* Thread name available only for VC-compiler */ | ||
199 | static void W32_SetThreadName(const DWORD thread_id, const char *thread_name) | ||
200 | { } | ||
201 | #else /* _MSC_FULL_VER */ | ||
202 | /** | ||
203 | * Set thread name | ||
204 | * @param thread_id ID of thread, -1 for current thread | ||
205 | * @param thread_name name to set | ||
206 | */ | ||
207 | void W32_SetThreadName(const DWORD thread_id, const char *thread_name); | ||
208 | #endif | ||
209 | |||
210 | #ifdef __cplusplus | 197 | #ifdef __cplusplus |
211 | } | 198 | } |
212 | #endif | 199 | #endif |
diff --git a/src/microhttpd/Makefile.am b/src/microhttpd/Makefile.am index 6cc40a87..e4b173ca 100644 --- a/src/microhttpd/Makefile.am +++ b/src/microhttpd/Makefile.am | |||
@@ -67,6 +67,7 @@ libmicrohttpd_la_SOURCES = \ | |||
67 | mhd_limits.h mhd_byteorder.h \ | 67 | mhd_limits.h mhd_byteorder.h \ |
68 | sysfdsetsize.c sysfdsetsize.h \ | 68 | sysfdsetsize.c sysfdsetsize.h \ |
69 | mhd_str.c mhd_str.h \ | 69 | mhd_str.c mhd_str.h \ |
70 | mhd_threads.c mhd_threads.h \ | ||
70 | response.c response.h | 71 | response.c response.h |
71 | libmicrohttpd_la_CPPFLAGS = \ | 72 | libmicrohttpd_la_CPPFLAGS = \ |
72 | $(AM_CPPFLAGS) $(MHD_LIB_CPPFLAGS) \ | 73 | $(AM_CPPFLAGS) $(MHD_LIB_CPPFLAGS) \ |
@@ -200,7 +201,7 @@ test_shutdown_select_LDADD = \ | |||
200 | endif | 201 | endif |
201 | 202 | ||
202 | test_shutdown_poll_SOURCES = \ | 203 | test_shutdown_poll_SOURCES = \ |
203 | test_shutdown_select.c | 204 | test_shutdown_select.c mhd_threads.h |
204 | if USE_POSIX_THREADS | 205 | if USE_POSIX_THREADS |
205 | test_shutdown_poll_CFLAGS = \ | 206 | test_shutdown_poll_CFLAGS = \ |
206 | $(AM_CFLAGS) $(PTHREAD_CFLAGS) | 207 | $(AM_CFLAGS) $(PTHREAD_CFLAGS) |
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c index fd8754ce..f493d19d 100644 --- a/src/microhttpd/daemon.c +++ b/src/microhttpd/daemon.c | |||
@@ -25,6 +25,7 @@ | |||
25 | * @author Christian Grothoff | 25 | * @author Christian Grothoff |
26 | */ | 26 | */ |
27 | #include "platform.h" | 27 | #include "platform.h" |
28 | #include "mhd_threads.h" | ||
28 | #include "internal.h" | 29 | #include "internal.h" |
29 | #include "response.h" | 30 | #include "response.h" |
30 | #include "connection.h" | 31 | #include "connection.h" |
@@ -61,7 +62,6 @@ | |||
61 | #define WIN32_LEAN_AND_MEAN 1 | 62 | #define WIN32_LEAN_AND_MEAN 1 |
62 | #endif /* !WIN32_LEAN_AND_MEAN */ | 63 | #endif /* !WIN32_LEAN_AND_MEAN */ |
63 | #include <windows.h> | 64 | #include <windows.h> |
64 | #include <process.h> | ||
65 | #endif | 65 | #endif |
66 | 66 | ||
67 | /** | 67 | /** |
@@ -1280,81 +1280,6 @@ send_param_adapter (struct MHD_Connection *connection, | |||
1280 | 1280 | ||
1281 | 1281 | ||
1282 | /** | 1282 | /** |
1283 | * Signature of main function for a thread. | ||
1284 | * | ||
1285 | * @param cls closure argument for the function | ||
1286 | * @return termination code from the thread | ||
1287 | */ | ||
1288 | typedef MHD_THRD_RTRN_TYPE_ | ||
1289 | (MHD_THRD_CALL_SPEC_ *ThreadStartRoutine)(void *cls); | ||
1290 | |||
1291 | |||
1292 | /** | ||
1293 | * Create a thread and set the attributes according to our options. | ||
1294 | * | ||
1295 | * @param thread handle to initialize | ||
1296 | * @param daemon daemon with options | ||
1297 | * @param start_routine main function of thread | ||
1298 | * @param arg argument for start_routine | ||
1299 | * @return 0 on success | ||
1300 | */ | ||
1301 | static int | ||
1302 | create_thread (MHD_thread_handle_ *thread, | ||
1303 | const struct MHD_Daemon *daemon, | ||
1304 | ThreadStartRoutine start_routine, | ||
1305 | void *arg) | ||
1306 | { | ||
1307 | #if defined(MHD_USE_POSIX_THREADS) | ||
1308 | pthread_attr_t attr; | ||
1309 | pthread_attr_t *pattr; | ||
1310 | int ret; | ||
1311 | |||
1312 | if (0 != daemon->thread_stack_size) | ||
1313 | { | ||
1314 | if (0 != (ret = pthread_attr_init (&attr))) | ||
1315 | goto ERR; | ||
1316 | if (0 != (ret = pthread_attr_setstacksize (&attr, daemon->thread_stack_size))) | ||
1317 | { | ||
1318 | pthread_attr_destroy (&attr); | ||
1319 | goto ERR; | ||
1320 | } | ||
1321 | pattr = &attr; | ||
1322 | } | ||
1323 | else | ||
1324 | { | ||
1325 | pattr = NULL; | ||
1326 | } | ||
1327 | ret = pthread_create (thread, pattr, | ||
1328 | start_routine, arg); | ||
1329 | #ifdef HAVE_PTHREAD_SETNAME_NP | ||
1330 | if (0 == ret) | ||
1331 | (void) pthread_setname_np (*thread, "libmicrohttpd"); | ||
1332 | #endif /* HAVE_PTHREAD_SETNAME_NP */ | ||
1333 | if (0 != daemon->thread_stack_size) | ||
1334 | pthread_attr_destroy (&attr); | ||
1335 | return ret; | ||
1336 | ERR: | ||
1337 | #ifdef HAVE_MESSAGES | ||
1338 | MHD_DLOG (daemon, | ||
1339 | "Failed to set thread stack size\n"); | ||
1340 | #endif | ||
1341 | errno = EINVAL; | ||
1342 | return ret; | ||
1343 | #elif defined(MHD_USE_W32_THREADS) | ||
1344 | unsigned threadID; | ||
1345 | *thread = (HANDLE)_beginthreadex(NULL, (unsigned)daemon->thread_stack_size, start_routine, | ||
1346 | arg, 0, &threadID); | ||
1347 | if (NULL == (*thread)) | ||
1348 | return errno; | ||
1349 | |||
1350 | W32_SetThreadName(threadID, "libmicrohttpd"); | ||
1351 | |||
1352 | return 0; | ||
1353 | #endif | ||
1354 | } | ||
1355 | |||
1356 | |||
1357 | /** | ||
1358 | * Add another client connection to the set of connections | 1283 | * Add another client connection to the set of connections |
1359 | * managed by MHD. This API is usually not needed (since | 1284 | * managed by MHD. This API is usually not needed (since |
1360 | * MHD will accept inbound connections on the server socket). | 1285 | * MHD will accept inbound connections on the server socket). |
@@ -1388,7 +1313,6 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
1388 | int external_add) | 1313 | int external_add) |
1389 | { | 1314 | { |
1390 | struct MHD_Connection *connection; | 1315 | struct MHD_Connection *connection; |
1391 | int res_thread_create; | ||
1392 | unsigned int i; | 1316 | unsigned int i; |
1393 | int eno; | 1317 | int eno; |
1394 | struct MHD_Daemon *worker; | 1318 | struct MHD_Daemon *worker; |
@@ -1635,17 +1559,17 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
1635 | /* attempt to create handler thread */ | 1559 | /* attempt to create handler thread */ |
1636 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | 1560 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
1637 | { | 1561 | { |
1638 | res_thread_create = create_thread (&connection->pid, | 1562 | if (!MHD_create_named_thread_(&connection->pid, |
1639 | daemon, | 1563 | "MHD-connection", |
1640 | &MHD_handle_connection, | 1564 | daemon->thread_stack_size, |
1641 | connection); | 1565 | &MHD_handle_connection, |
1642 | if (0 != res_thread_create) | 1566 | connection)) |
1643 | { | 1567 | { |
1644 | eno = errno; | 1568 | eno = errno; |
1645 | #ifdef HAVE_MESSAGES | 1569 | #ifdef HAVE_MESSAGES |
1646 | MHD_DLOG (daemon, | 1570 | MHD_DLOG (daemon, |
1647 | "Failed to create a thread: %s\n", | 1571 | "Failed to create a thread: %s\n", |
1648 | MHD_strerror_ (res_thread_create)); | 1572 | MHD_strerror_ (eno)); |
1649 | #endif | 1573 | #endif |
1650 | goto cleanup; | 1574 | goto cleanup; |
1651 | } | 1575 | } |
@@ -1723,9 +1647,7 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
1723 | MHD_pool_destroy (connection->pool); | 1647 | MHD_pool_destroy (connection->pool); |
1724 | free (connection->addr); | 1648 | free (connection->addr); |
1725 | free (connection); | 1649 | free (connection); |
1726 | #if EINVAL | ||
1727 | errno = eno; | 1650 | errno = eno; |
1728 | #endif | ||
1729 | return MHD_NO; | 1651 | return MHD_NO; |
1730 | } | 1652 | } |
1731 | 1653 | ||
@@ -2157,7 +2079,7 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon) | |||
2157 | if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && | 2079 | if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && |
2158 | (MHD_NO == pos->thread_joined) ) | 2080 | (MHD_NO == pos->thread_joined) ) |
2159 | { | 2081 | { |
2160 | if (0 != MHD_join_thread_ (pos->pid)) | 2082 | if (!MHD_join_thread_ (pos->pid)) |
2161 | { | 2083 | { |
2162 | MHD_PANIC ("Failed to join a thread\n"); | 2084 | MHD_PANIC ("Failed to join a thread\n"); |
2163 | } | 2085 | } |
@@ -3765,7 +3687,6 @@ MHD_start_daemon_va (unsigned int flags, | |||
3765 | const struct sockaddr *servaddr = NULL; | 3687 | const struct sockaddr *servaddr = NULL; |
3766 | socklen_t addrlen; | 3688 | socklen_t addrlen; |
3767 | unsigned int i; | 3689 | unsigned int i; |
3768 | int res_thread_create; | ||
3769 | int use_pipe; | 3690 | int use_pipe; |
3770 | 3691 | ||
3771 | #ifndef HAVE_INET6 | 3692 | #ifndef HAVE_INET6 |
@@ -4307,13 +4228,17 @@ MHD_start_daemon_va (unsigned int flags, | |||
4307 | ( (0 != (flags & MHD_USE_SELECT_INTERNALLY)) && | 4228 | ( (0 != (flags & MHD_USE_SELECT_INTERNALLY)) && |
4308 | (0 == daemon->worker_pool_size)) ) && | 4229 | (0 == daemon->worker_pool_size)) ) && |
4309 | (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) && | 4230 | (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) && |
4310 | (0 != (res_thread_create = | 4231 | (!MHD_create_named_thread_ (&daemon->pid, |
4311 | create_thread (&daemon->pid, daemon, &MHD_select_thread, daemon)))) | 4232 | (flags & MHD_USE_THREAD_PER_CONNECTION) ? |
4233 | "MHD-listen" : "MHD-single", | ||
4234 | daemon->thread_stack_size, | ||
4235 | &MHD_select_thread, | ||
4236 | daemon) ) ) | ||
4312 | { | 4237 | { |
4313 | #ifdef HAVE_MESSAGES | 4238 | #ifdef HAVE_MESSAGES |
4314 | MHD_DLOG (daemon, | 4239 | MHD_DLOG (daemon, |
4315 | "Failed to create listen thread: %s\n", | 4240 | "Failed to create listen thread: %s\n", |
4316 | MHD_strerror_ (res_thread_create)); | 4241 | MHD_strerror_ (errno)); |
4317 | #endif | 4242 | #endif |
4318 | (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex); | 4243 | (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex); |
4319 | (void) MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex); | 4244 | (void) MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex); |
@@ -4416,13 +4341,16 @@ MHD_start_daemon_va (unsigned int flags, | |||
4416 | } | 4341 | } |
4417 | 4342 | ||
4418 | /* Spawn the worker thread */ | 4343 | /* Spawn the worker thread */ |
4419 | if (0 != (res_thread_create = | 4344 | if (!MHD_create_named_thread_(&d->pid, |
4420 | create_thread (&d->pid, daemon, &MHD_select_thread, d))) | 4345 | "MHD-worker", |
4346 | daemon->thread_stack_size, | ||
4347 | &MHD_select_thread, | ||
4348 | d)) | ||
4421 | { | 4349 | { |
4422 | #ifdef HAVE_MESSAGES | 4350 | #ifdef HAVE_MESSAGES |
4423 | MHD_DLOG (daemon, | 4351 | MHD_DLOG (daemon, |
4424 | "Failed to create pool thread: %s\n", | 4352 | "Failed to create pool thread: %s\n", |
4425 | MHD_strerror_ (res_thread_create)); | 4353 | MHD_strerror_ (errno)); |
4426 | #endif | 4354 | #endif |
4427 | /* Free memory for this worker; cleanup below handles | 4355 | /* Free memory for this worker; cleanup below handles |
4428 | * all previously-created workers. */ | 4356 | * all previously-created workers. */ |
@@ -4564,7 +4492,7 @@ close_all_connections (struct MHD_Daemon *daemon) | |||
4564 | { | 4492 | { |
4565 | if (MHD_YES != pos->thread_joined) | 4493 | if (MHD_YES != pos->thread_joined) |
4566 | { | 4494 | { |
4567 | if (0 != MHD_join_thread_ (pos->pid)) | 4495 | if (!MHD_join_thread_ (pos->pid)) |
4568 | MHD_PANIC ("Failed to join a thread\n"); | 4496 | MHD_PANIC ("Failed to join a thread\n"); |
4569 | pos->thread_joined = MHD_YES; | 4497 | pos->thread_joined = MHD_YES; |
4570 | /* The thread may have concurrently modified the DLL, | 4498 | /* The thread may have concurrently modified the DLL, |
@@ -4690,7 +4618,7 @@ MHD_stop_daemon (struct MHD_Daemon *daemon) | |||
4690 | if (1 != MHD_pipe_write_ (daemon->worker_pool[i].wpipe[1], "e", 1)) | 4618 | if (1 != MHD_pipe_write_ (daemon->worker_pool[i].wpipe[1], "e", 1)) |
4691 | MHD_PANIC ("failed to signal shutdown via pipe"); | 4619 | MHD_PANIC ("failed to signal shutdown via pipe"); |
4692 | } | 4620 | } |
4693 | if (0 != MHD_join_thread_ (daemon->worker_pool[i].pid)) | 4621 | if (!MHD_join_thread_ (daemon->worker_pool[i].pid)) |
4694 | MHD_PANIC ("Failed to join a thread\n"); | 4622 | MHD_PANIC ("Failed to join a thread\n"); |
4695 | close_all_connections (&daemon->worker_pool[i]); | 4623 | close_all_connections (&daemon->worker_pool[i]); |
4696 | (void) MHD_mutex_destroy_ (&daemon->worker_pool[i].cleanup_connection_mutex); | 4624 | (void) MHD_mutex_destroy_ (&daemon->worker_pool[i].cleanup_connection_mutex); |
@@ -4720,7 +4648,7 @@ MHD_stop_daemon (struct MHD_Daemon *daemon) | |||
4720 | ( (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) && | 4648 | ( (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) && |
4721 | (0 == daemon->worker_pool_size) ) ) | 4649 | (0 == daemon->worker_pool_size) ) ) |
4722 | { | 4650 | { |
4723 | if (0 != MHD_join_thread_ (daemon->pid)) | 4651 | if (!MHD_join_thread_ (daemon->pid)) |
4724 | { | 4652 | { |
4725 | MHD_PANIC ("Failed to join a thread\n"); | 4653 | MHD_PANIC ("Failed to join a thread\n"); |
4726 | } | 4654 | } |
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h index 5c6a8b5d..aef6f17a 100644 --- a/src/microhttpd/internal.h +++ b/src/microhttpd/internal.h | |||
@@ -43,6 +43,7 @@ | |||
43 | /* for TCP_FASTOPEN */ | 43 | /* for TCP_FASTOPEN */ |
44 | #include <netinet/tcp.h> | 44 | #include <netinet/tcp.h> |
45 | #endif | 45 | #endif |
46 | #include "mhd_threads.h" | ||
46 | 47 | ||
47 | 48 | ||
48 | /** | 49 | /** |
diff --git a/src/microhttpd/mhd_limits.h b/src/microhttpd/mhd_limits.h index 264803b9..f0f0d577 100644 --- a/src/microhttpd/mhd_limits.h +++ b/src/microhttpd/mhd_limits.h | |||
@@ -32,6 +32,14 @@ | |||
32 | #include <limits.h> | 32 | #include <limits.h> |
33 | #endif /* HAVE_LIMITS_H */ | 33 | #endif /* HAVE_LIMITS_H */ |
34 | 34 | ||
35 | #ifndef UINT_MAX | ||
36 | #ifdef __UINT_MAX__ | ||
37 | #define UINT_MAX __UINT_MAX__ | ||
38 | #else /* ! __UINT_MAX__ */ | ||
39 | #define UINT_MAX ((unsigned int) ~((unsigned int)0)) | ||
40 | #endif /* ! __UINT_MAX__ */ | ||
41 | #endif /* !UINT_MAX */ | ||
42 | |||
35 | #ifndef LONG_MAX | 43 | #ifndef LONG_MAX |
36 | #ifdef __LONG_MAX__ | 44 | #ifdef __LONG_MAX__ |
37 | #define LONG_MAX __LONG_MAX__ | 45 | #define LONG_MAX __LONG_MAX__ |
diff --git a/src/microhttpd/mhd_threads.c b/src/microhttpd/mhd_threads.c new file mode 100644 index 00000000..07da4960 --- /dev/null +++ b/src/microhttpd/mhd_threads.c | |||
@@ -0,0 +1,274 @@ | |||
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.c | ||
23 | * @brief Implementation for thread functions | ||
24 | * @author Karlson2k (Evgeny Grin) | ||
25 | */ | ||
26 | |||
27 | #include "mhd_threads.h" | ||
28 | #ifdef MHD_USE_W32_THREADS | ||
29 | #include "mhd_limits.h" | ||
30 | #include <process.h> | ||
31 | #endif | ||
32 | #ifdef MHD_USE_THREAD_NAME_ | ||
33 | #include <stdlib.h> | ||
34 | #endif /* MHD_USE_THREAD_NAME_ */ | ||
35 | #include <errno.h> | ||
36 | |||
37 | |||
38 | |||
39 | #if defined(MHD_USE_POSIX_THREADS) | ||
40 | typedef pthread_t MHD_thread_ID_; | ||
41 | #elif defined(MHD_USE_W32_THREADS) | ||
42 | typedef DWORD MHD_thread_ID_; | ||
43 | #endif | ||
44 | |||
45 | |||
46 | #ifndef MHD_USE_THREAD_NAME_ | ||
47 | |||
48 | #define MHD_set_thread_name_(t, n) (void) | ||
49 | #define MHD_set_cur_thread_name_(n) (void) | ||
50 | |||
51 | #else /* MHD_USE_THREAD_NAME_ */ | ||
52 | |||
53 | #if defined(MHD_USE_POSIX_THREADS) | ||
54 | #ifdef HAVE_PTHREAD_SETNAME_NP | ||
55 | /** | ||
56 | * Set thread name | ||
57 | * @param thread_id ID of thread | ||
58 | * @param thread_name name to set | ||
59 | * @return non-zero on success, zero otherwise | ||
60 | */ | ||
61 | static int MHD_set_thread_name_(const MHD_thread_ID_ thread_id, const char *thread_name) | ||
62 | { | ||
63 | if (NULL == thread_name) | ||
64 | return 0; | ||
65 | |||
66 | return !pthread_setname_np (thread_id, thread_name); | ||
67 | } | ||
68 | |||
69 | /** | ||
70 | * Set current thread name | ||
71 | * @param n name to set | ||
72 | * @return non-zero on success, zero otherwise | ||
73 | */ | ||
74 | #define MHD_set_cur_thread_name_(n) MHD_set_thread_name_(pthread_self(),(n)) | ||
75 | #endif /* HAVE_PTHREAD_SETNAME_NP */ | ||
76 | |||
77 | #elif defined(MHD_USE_W32_THREADS) | ||
78 | #ifndef _MSC_FULL_VER | ||
79 | /* Thread name available only for VC-compiler */ | ||
80 | #else /* _MSC_FULL_VER */ | ||
81 | /** | ||
82 | * Set thread name | ||
83 | * @param thread_id ID of thread, -1 for current thread | ||
84 | * @param thread_name name to set | ||
85 | * @return non-zero on success, zero otherwise | ||
86 | */ | ||
87 | static int MHD_set_thread_name_(const MHD_thread_ID_ thread_id, const char *thread_name) | ||
88 | { | ||
89 | static const DWORD VC_SETNAME_EXC = 0x406D1388; | ||
90 | #pragma pack(push,8) | ||
91 | struct thread_info_struct | ||
92 | { | ||
93 | DWORD type; /* Must be 0x1000. */ | ||
94 | LPCSTR name; /* Pointer to name (in user address space). */ | ||
95 | DWORD ID; /* Thread ID (-1 = caller thread). */ | ||
96 | DWORD flags; /* Reserved for future use, must be zero. */ | ||
97 | } thread_info; | ||
98 | #pragma pack(pop) | ||
99 | |||
100 | if (NULL == thread_name) | ||
101 | return 0; | ||
102 | |||
103 | thread_info.type = 0x1000; | ||
104 | thread_info.name = thread_name; | ||
105 | thread_info.ID = thread_id; | ||
106 | thread_info.flags = 0; | ||
107 | |||
108 | __try | ||
109 | { /* This exception is intercepted by debugger */ | ||
110 | RaiseException(VC_SETNAME_EXC, 0, sizeof(thread_info) / sizeof(ULONG_PTR), (ULONG_PTR*)&thread_info); | ||
111 | } | ||
112 | __except (EXCEPTION_EXECUTE_HANDLER) | ||
113 | {} | ||
114 | |||
115 | return !0; | ||
116 | } | ||
117 | |||
118 | |||
119 | /** | ||
120 | * Set current thread name | ||
121 | * @param n name to set | ||
122 | * @return non-zero on success, zero otherwise | ||
123 | */ | ||
124 | #define MHD_set_cur_thread_name_(n) MHD_set_thread_name_(-1,(n)) | ||
125 | #endif /* _MSC_FULL_VER */ | ||
126 | #endif /* MHD_USE_W32_THREADS */ | ||
127 | |||
128 | #endif /* MHD_USE_THREAD_NAME_ */ | ||
129 | |||
130 | |||
131 | /** | ||
132 | * Create a thread and set the attributes according to our options. | ||
133 | * | ||
134 | * @param thread handle to initialize | ||
135 | * @param stack_size size of stack for new thread, 0 for default | ||
136 | * @param start_routine main function of thread | ||
137 | * @param arg argument for start_routine | ||
138 | * @return non-zero on success; zero otherwise (with errno set) | ||
139 | */ | ||
140 | int | ||
141 | MHD_create_thread_ (MHD_thread_handle_ *thread, | ||
142 | size_t stack_size, | ||
143 | MHD_THREAD_START_ROUTINE_ start_routine, | ||
144 | void *arg) | ||
145 | { | ||
146 | #if defined(MHD_USE_POSIX_THREADS) | ||
147 | int res; | ||
148 | |||
149 | if (0 != stack_size) | ||
150 | { | ||
151 | pthread_attr_t attr; | ||
152 | res = pthread_attr_init (&attr); | ||
153 | if (0 == res) | ||
154 | { | ||
155 | res = pthread_attr_setstacksize (&attr, stack_size); | ||
156 | if (0 == res) | ||
157 | res = pthread_create (thread, &attr, | ||
158 | start_routine, arg); | ||
159 | pthread_attr_destroy (&attr); | ||
160 | } | ||
161 | } | ||
162 | else | ||
163 | res = pthread_create (thread, NULL, start_routine, arg); | ||
164 | |||
165 | if (0 != res) | ||
166 | errno = res; | ||
167 | |||
168 | return !res; | ||
169 | #elif defined(MHD_USE_W32_THREADS) | ||
170 | #if SIZE_MAX != UINT_MAX | ||
171 | if (stack_size > UINT_MAX) | ||
172 | { | ||
173 | errno = EINVAL; | ||
174 | return 0; | ||
175 | } | ||
176 | #endif /* SIZE_MAX != UINT_MAX */ | ||
177 | |||
178 | *thread = (HANDLE)_beginthreadex(NULL, (unsigned)stack_size, start_routine, | ||
179 | arg, 0, NULL); | ||
180 | if ((MHD_thread_handle_)-1 == (*thread)) | ||
181 | return 0; | ||
182 | |||
183 | return !0; | ||
184 | #endif | ||
185 | } | ||
186 | |||
187 | #ifdef MHD_USE_THREAD_NAME_ | ||
188 | |||
189 | struct MHD_named_helper_param_ | ||
190 | { | ||
191 | /** | ||
192 | * Real thread start routine | ||
193 | */ | ||
194 | MHD_THREAD_START_ROUTINE_ start_routine; | ||
195 | |||
196 | /** | ||
197 | * Argument for thread start routine | ||
198 | */ | ||
199 | void *arg; | ||
200 | |||
201 | /** | ||
202 | * Name for thread | ||
203 | */ | ||
204 | const char *name; | ||
205 | }; | ||
206 | |||
207 | static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ | ||
208 | named_thread_starter (void *data) | ||
209 | { | ||
210 | struct MHD_named_helper_param_ * const param = | ||
211 | (struct MHD_named_helper_param_ *) data; | ||
212 | void * arg; | ||
213 | MHD_THREAD_START_ROUTINE_ thr_func; | ||
214 | |||
215 | if (NULL == data) | ||
216 | return (MHD_THRD_RTRN_TYPE_)0; | ||
217 | |||
218 | MHD_set_cur_thread_name_(param->name); | ||
219 | |||
220 | arg = param->arg; | ||
221 | thr_func = param->start_routine; | ||
222 | free(data); | ||
223 | |||
224 | return thr_func(arg); | ||
225 | } | ||
226 | |||
227 | |||
228 | |||
229 | /** | ||
230 | * Create a named thread and set the attributes according to our options. | ||
231 | * | ||
232 | * @param thread handle to initialize | ||
233 | * @param thread_name name for new thread | ||
234 | * @param stack_size size of stack for new thread, 0 for default | ||
235 | * @param start_routine main function of thread | ||
236 | * @param arg argument for start_routine | ||
237 | * @return non-zero on success; zero otherwise (with errno set) | ||
238 | */ | ||
239 | int | ||
240 | MHD_create_named_thread_ (MHD_thread_handle_ *thread, | ||
241 | const char* thread_name, | ||
242 | size_t stack_size, | ||
243 | MHD_THREAD_START_ROUTINE_ start_routine, | ||
244 | void *arg) | ||
245 | { | ||
246 | struct MHD_named_helper_param_ * param; | ||
247 | |||
248 | if (NULL == thread_name) | ||
249 | { | ||
250 | errno = EINVAL; | ||
251 | return 0; | ||
252 | } | ||
253 | |||
254 | param = malloc(sizeof(struct MHD_named_helper_param_)); | ||
255 | if (NULL == param) | ||
256 | return 0; | ||
257 | |||
258 | param->start_routine = start_routine; | ||
259 | param->arg = arg; | ||
260 | param->name = thread_name; | ||
261 | |||
262 | /* Set thread name in thread itself to avoid problems with | ||
263 | * threads which terminated before name is set in other thread. | ||
264 | */ | ||
265 | if (!MHD_create_thread_(thread, stack_size, &named_thread_starter, (void*)param)) | ||
266 | { | ||
267 | free(param); | ||
268 | return 0; | ||
269 | } | ||
270 | |||
271 | return !0; | ||
272 | } | ||
273 | |||
274 | #endif /* MHD_USE_THREAD_NAME_ */ | ||
diff --git a/src/microhttpd/mhd_threads.h b/src/microhttpd/mhd_threads.h new file mode 100644 index 00000000..23f21a28 --- /dev/null +++ b/src/microhttpd/mhd_threads.h | |||
@@ -0,0 +1,151 @@ | |||
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 | # ifdef HAVE_PTHREAD_SETNAME_NP | ||
62 | # define MHD_USE_THREAD_NAME_ | ||
63 | # endif /* HAVE_PTHREAD_SETNAME_NP */ | ||
64 | # elif defined(MHD_USE_W32_THREADS) | ||
65 | # ifdef _MSC_FULL_VER | ||
66 | /* Thread names only available with VC compiler */ | ||
67 | # define MHD_USE_THREAD_NAME_ | ||
68 | # endif /* _MSC_FULL_VER */ | ||
69 | # endif | ||
70 | #endif | ||
71 | |||
72 | #if defined(MHD_USE_POSIX_THREADS) | ||
73 | typedef pthread_t MHD_thread_handle_; | ||
74 | #elif defined(MHD_USE_W32_THREADS) | ||
75 | typedef HANDLE MHD_thread_handle_; | ||
76 | #endif | ||
77 | |||
78 | #if defined(MHD_USE_POSIX_THREADS) | ||
79 | # define MHD_THRD_RTRN_TYPE_ void* | ||
80 | # define MHD_THRD_CALL_SPEC_ | ||
81 | #elif defined(MHD_USE_W32_THREADS) | ||
82 | # define MHD_THRD_RTRN_TYPE_ unsigned | ||
83 | # define MHD_THRD_CALL_SPEC_ __stdcall | ||
84 | #endif | ||
85 | |||
86 | #if defined(MHD_USE_POSIX_THREADS) | ||
87 | /** | ||
88 | * Wait until specified thread is ended and free thread handle on success. | ||
89 | * @param thread handle to watch | ||
90 | * @return nonzero on success, zero otherwise | ||
91 | */ | ||
92 | #define MHD_join_thread_(thread) (!pthread_join((thread), NULL)) | ||
93 | #elif defined(MHD_USE_W32_THREADS) | ||
94 | /** | ||
95 | * Wait until specified thread is ended and free thread handle on success. | ||
96 | * @param thread handle to watch | ||
97 | * @return nonzero on success, zero otherwise | ||
98 | */ | ||
99 | #define MHD_join_thread_(thread) (WAIT_OBJECT_0 == WaitForSingleObject((thread), INFINITE) ? (CloseHandle((thread)), !0) : 0) | ||
100 | #endif | ||
101 | |||
102 | /** | ||
103 | * Signature of main function for a thread. | ||
104 | * | ||
105 | * @param cls closure argument for the function | ||
106 | * @return termination code from the thread | ||
107 | */ | ||
108 | typedef MHD_THRD_RTRN_TYPE_ | ||
109 | (MHD_THRD_CALL_SPEC_ *MHD_THREAD_START_ROUTINE_)(void *cls); | ||
110 | |||
111 | |||
112 | /** | ||
113 | * Create a thread and set the attributes according to our options. | ||
114 | * | ||
115 | * If thread is created, thread handle must be freed by #MHD_join_thread_(). | ||
116 | * | ||
117 | * @param thread handle to initialize | ||
118 | * @param stack_size size of stack for new thread, 0 for default | ||
119 | * @param start_routine main function of thread | ||
120 | * @param arg argument for start_routine | ||
121 | * @return non-zero on success; zero otherwise | ||
122 | */ | ||
123 | int | ||
124 | MHD_create_thread_ (MHD_thread_handle_ *thread, | ||
125 | size_t stack_size, | ||
126 | MHD_THREAD_START_ROUTINE_ start_routine, | ||
127 | void *arg); | ||
128 | |||
129 | #ifndef MHD_USE_THREAD_NAME_ | ||
130 | #define MHD_create_named_thread_(t,n,s,r,a) MHD_create_thread_((t),(s),(r),(a)) | ||
131 | #else /* MHD_USE_THREAD_NAME_ */ | ||
132 | /** | ||
133 | * Create a named thread and set the attributes according to our options. | ||
134 | * | ||
135 | * @param thread handle to initialize | ||
136 | * @param thread_name name for new thread | ||
137 | * @param stack_size size of stack for new thread, 0 for default | ||
138 | * @param start_routine main function of thread | ||
139 | * @param arg argument for start_routine | ||
140 | * @return non-zero on success; zero otherwise | ||
141 | */ | ||
142 | int | ||
143 | MHD_create_named_thread_ (MHD_thread_handle_ *thread, | ||
144 | const char* thread_name, | ||
145 | size_t stack_size, | ||
146 | MHD_THREAD_START_ROUTINE_ start_routine, | ||
147 | void *arg); | ||
148 | |||
149 | #endif /* MHD_USE_THREAD_NAME_ */ | ||
150 | |||
151 | #endif /* ! MHD_THREADS_H */ | ||
diff --git a/src/microhttpd/test_shutdown_select.c b/src/microhttpd/test_shutdown_select.c index df36b49c..e3aaa20f 100644 --- a/src/microhttpd/test_shutdown_select.c +++ b/src/microhttpd/test_shutdown_select.c | |||
@@ -77,6 +77,8 @@ | |||
77 | #include <stdbool.h> | 77 | #include <stdbool.h> |
78 | #endif /* HAVE_STDBOOL_H */ | 78 | #endif /* HAVE_STDBOOL_H */ |
79 | 79 | ||
80 | #include "mhd_threads.h" | ||
81 | |||
80 | #ifndef SOMAXCONN | 82 | #ifndef SOMAXCONN |
81 | #define SOMAXCONN 511 | 83 | #define SOMAXCONN 511 |
82 | #endif /* ! SOMAXCONN */ | 84 | #endif /* ! SOMAXCONN */ |
@@ -346,7 +348,7 @@ main (int argc, char *const *argv) | |||
346 | shutdown (listen_socket, SHUT_RDWR); | 348 | shutdown (listen_socket, SHUT_RDWR); |
347 | 349 | ||
348 | /* fprintf (stdout, "Waiting for thread to finish...\n"); */ | 350 | /* fprintf (stdout, "Waiting for thread to finish...\n"); */ |
349 | if (0 != MHD_join_thread_(sel_thrd)) | 351 | if (!MHD_join_thread_(sel_thrd)) |
350 | { | 352 | { |
351 | MHD_socket_close_(listen_socket); | 353 | MHD_socket_close_(listen_socket); |
352 | fprintf (stderr, "Can't join select() thread\n"); | 354 | fprintf (stderr, "Can't join select() thread\n"); |
diff --git a/src/platform/w32functions.c b/src/platform/w32functions.c index 0feafa5b..4b1e2c1c 100644 --- a/src/platform/w32functions.c +++ b/src/platform/w32functions.c | |||
@@ -667,39 +667,3 @@ int W32_snprintf(char *__restrict s, size_t n, const char *__restrict format, .. | |||
667 | 667 | ||
668 | return ret; | 668 | return ret; |
669 | } | 669 | } |
670 | |||
671 | #ifdef _MSC_FULL_VER | ||
672 | /** | ||
673 | * Set thread name | ||
674 | * @param thread_id ID of thread, -1 for current thread | ||
675 | * @param thread_name name to set | ||
676 | */ | ||
677 | void W32_SetThreadName(const DWORD thread_id, const char *thread_name) | ||
678 | { | ||
679 | static const DWORD VC_SETNAME_EXC = 0x406D1388; | ||
680 | #pragma pack(push,8) | ||
681 | struct thread_info_struct | ||
682 | { | ||
683 | DWORD type; /* Must be 0x1000. */ | ||
684 | LPCSTR name; /* Pointer to name (in user address space). */ | ||
685 | DWORD ID; /* Thread ID (-1=caller thread). */ | ||
686 | DWORD flags; /* Reserved for future use, must be zero. */ | ||
687 | } thread_info; | ||
688 | #pragma pack(pop) | ||
689 | |||
690 | if (NULL == thread_name) | ||
691 | return; | ||
692 | |||
693 | thread_info.type = 0x1000; | ||
694 | thread_info.name = thread_name; | ||
695 | thread_info.ID = thread_id; | ||
696 | thread_info.flags = 0; | ||
697 | |||
698 | __try | ||
699 | { /* This exception is intercepted by debugger */ | ||
700 | RaiseException(VC_SETNAME_EXC, 0, sizeof(thread_info) / sizeof(ULONG_PTR), (ULONG_PTR*)&thread_info); | ||
701 | } | ||
702 | __except (EXCEPTION_EXECUTE_HANDLER) | ||
703 | {} | ||
704 | } | ||
705 | #endif /* _MSC_FULL_VER */ | ||
diff --git a/w32/common/MHD_config.h b/w32/common/MHD_config.h index d147e984..c9205115 100644 --- a/w32/common/MHD_config.h +++ b/w32/common/MHD_config.h | |||
@@ -144,6 +144,9 @@ | |||
144 | /* Define to 1 if you have the <time.h> header file. */ | 144 | /* Define to 1 if you have the <time.h> header file. */ |
145 | #define HAVE_TIME_H 1 | 145 | #define HAVE_TIME_H 1 |
146 | 146 | ||
147 | /* Define to 1 if you have the <stddef.h> header file. */ | ||
148 | #define HAVE_STDDEF_H 1 | ||
149 | |||
147 | 150 | ||
148 | /* *** Other useful staff *** */ | 151 | /* *** Other useful staff *** */ |
149 | 152 | ||
diff --git a/w32/common/libmicrohttpd-files.vcxproj b/w32/common/libmicrohttpd-files.vcxproj index 4535f006..be50c277 100644 --- a/w32/common/libmicrohttpd-files.vcxproj +++ b/w32/common/libmicrohttpd-files.vcxproj | |||
@@ -16,6 +16,7 @@ | |||
16 | <ClCompile Include="$(MhdSrc)microhttpd\tsearch.c" /> | 16 | <ClCompile Include="$(MhdSrc)microhttpd\tsearch.c" /> |
17 | <ClCompile Include="$(MhdSrc)microhttpd\sysfdsetsize.c" /> | 17 | <ClCompile Include="$(MhdSrc)microhttpd\sysfdsetsize.c" /> |
18 | <ClCompile Include="$(MhdSrc)microhttpd\mhd_str.c" /> | 18 | <ClCompile Include="$(MhdSrc)microhttpd\mhd_str.c" /> |
19 | <ClCompile Include="$(MhdSrc)microhttpd\mhd_threads.c" /> | ||
19 | <ClCompile Include="$(MhdSrc)platform\w32functions.c" /> | 20 | <ClCompile Include="$(MhdSrc)platform\w32functions.c" /> |
20 | </ItemGroup> | 21 | </ItemGroup> |
21 | <ItemGroup> | 22 | <ItemGroup> |
@@ -37,6 +38,7 @@ | |||
37 | <ClInclude Include="$(MhdSrc)microhttpd\tsearch.h" /> | 38 | <ClInclude Include="$(MhdSrc)microhttpd\tsearch.h" /> |
38 | <ClInclude Include="$(MhdSrc)microhttpd\sysfdsetsize.h" /> | 39 | <ClInclude Include="$(MhdSrc)microhttpd\sysfdsetsize.h" /> |
39 | <ClInclude Include="$(MhdSrc)microhttpd\mhd_str.h" /> | 40 | <ClInclude Include="$(MhdSrc)microhttpd\mhd_str.h" /> |
41 | <ClInclude Include="$(MhdSrc)microhttpd\mhd_threads.h" /> | ||
40 | <ClInclude Include="$(MhdW32Common)MHD_config.h" /> | 42 | <ClInclude Include="$(MhdW32Common)MHD_config.h" /> |
41 | </ItemGroup> | 43 | </ItemGroup> |
42 | <ItemGroup> | 44 | <ItemGroup> |
diff --git a/w32/common/libmicrohttpd-filters.vcxproj b/w32/common/libmicrohttpd-filters.vcxproj index d43683ce..85232458 100644 --- a/w32/common/libmicrohttpd-filters.vcxproj +++ b/w32/common/libmicrohttpd-filters.vcxproj | |||
@@ -130,6 +130,12 @@ | |||
130 | <ClCompile Include="$(MhdSrc)microhttpd\mhd_str.c"> | 130 | <ClCompile Include="$(MhdSrc)microhttpd\mhd_str.c"> |
131 | <Filter>Source Files</Filter> | 131 | <Filter>Source Files</Filter> |
132 | </ClCompile> | 132 | </ClCompile> |
133 | <ClInclude Include="$(MhdSrc)microhttpd\mhd_threads.h"> | ||
134 | <Filter>Source Files</Filter> | ||
135 | </ClInclude> | ||
136 | <ClCompile Include="$(MhdSrc)microhttpd\mhd_threads.c"> | ||
137 | <Filter>Source Files</Filter> | ||
138 | </ClCompile> | ||
133 | </ItemGroup> | 139 | </ItemGroup> |
134 | <ItemGroup> | 140 | <ItemGroup> |
135 | <ResourceCompile Include="$(MhdW32Common)microhttpd_dll_res_vc.rc"> | 141 | <ResourceCompile Include="$(MhdW32Common)microhttpd_dll_res_vc.rc"> |