aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2018-12-07 12:40:32 +0100
committerChristian Grothoff <christian@grothoff.org>2018-12-07 12:40:40 +0100
commit0eefd20ba370509d93fb7b0220e6d1c5739efac5 (patch)
tree9d3d33e14d8862b061b23a41b4c2bc90616fe636
parent22c08b5fd71091e84247f43bd36ce08184736f17 (diff)
downloadlibmicrohttpd-0eefd20ba370509d93fb7b0220e6d1c5739efac5.tar.gz
libmicrohttpd-0eefd20ba370509d93fb7b0220e6d1c5739efac5.zip
add build option to compile MHD without threads
-rw-r--r--ChangeLog4
-rw-r--r--configure.ac36
-rw-r--r--doc/libmicrohttpd.texi3
-rw-r--r--src/include/microhttpd.h9
-rw-r--r--src/microhttpd/Makefile.am28
-rw-r--r--src/microhttpd/connection.c44
-rw-r--r--src/microhttpd/daemon.c174
-rw-r--r--src/microhttpd/digestauth.c10
-rw-r--r--src/microhttpd/internal.h17
-rw-r--r--src/microhttpd/response.c18
-rw-r--r--src/microhttpd/test_start_stop.c26
-rw-r--r--src/testcurl/Makefile.am68
-rw-r--r--src/testcurl/https/Makefile.am43
-rw-r--r--src/testcurl/https/tls_test_common.c4
-rw-r--r--src/testcurl/perf_get.c33
-rw-r--r--src/testcurl/test_delete.c9
-rw-r--r--src/testcurl/test_get.c51
-rw-r--r--src/testcurl/test_get_chunked.c9
-rw-r--r--src/testcurl/test_get_response_cleanup.c9
-rw-r--r--src/testcurl/test_get_sendfile.c11
-rw-r--r--src/testcurl/test_large_put.c63
-rw-r--r--src/testcurl/test_post.c11
-rw-r--r--src/testcurl/test_post_loop.c63
-rw-r--r--src/testcurl/test_postform.c9
-rw-r--r--src/testcurl/test_process_headers.c9
-rw-r--r--src/testcurl/test_put.c9
-rw-r--r--src/testcurl/test_put_chunked.c9
-rw-r--r--src/testcurl/test_quiesce.c33
-rw-r--r--src/testzzuf/Makefile.am16
-rw-r--r--src/testzzuf/test_get.c7
-rw-r--r--src/testzzuf/test_get_chunked.c7
-rw-r--r--src/testzzuf/test_post.c7
-rw-r--r--src/testzzuf/test_post_form.c7
-rw-r--r--src/testzzuf/test_put.c7
-rw-r--r--src/testzzuf/test_put_chunked.c7
-rw-r--r--src/testzzuf/test_put_large.c7
36 files changed, 622 insertions, 255 deletions
diff --git a/ChangeLog b/ChangeLog
index 9d7df977..ee824d98 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
1Fri Dec 7 12:37:17 CET 2018
2 Add option to build MHD without any threads
3 and MHD_FEATURE_THREADS to test for it. -CG
4
1Thu Dec 6 13:25:08 BRT 2018 5Thu Dec 6 13:25:08 BRT 2018
2 Renamed all occurrences from _model(s)_ to _mode(s)_. -SC 6 Renamed all occurrences from _model(s)_ to _mode(s)_. -SC
3 7
diff --git a/configure.ac b/configure.ac
index 3e840234..d2d2bfb7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -361,13 +361,14 @@ AM_CONDITIONAL([CYGWIN_TARGET], [[test "x$os_is_windows" = "xyes" && \
361 test "x${os_is_native_w32}" != "xyes"]]) 361 test "x${os_is_native_w32}" != "xyes"]])
362 362
363AC_ARG_WITH([threads], 363AC_ARG_WITH([threads],
364 [AS_HELP_STRING([--with-threads=LIB],[choose threading library (posix, w32, auto) [auto]])], 364 [AS_HELP_STRING([--with-threads=LIB],[choose threading library (posix, w32, auto, none) [auto]])],
365 [], [with_threads='auto']) 365 [], [with_threads='auto'])
366AS_CASE([[$with_threads]], 366AS_CASE([[$with_threads]],
367 [[win32]], [[with_threads='w32']], 367 [[win32]], [[with_threads='w32']],
368 [[pthreads]], [[with_threads='posix']], 368 [[pthreads]], [[with_threads='posix']],
369 [[posix]], [[:]], 369 [[posix]], [[:]],
370 [[w32]], [[:]], 370 [[w32]], [[:]],
371 [[none]], [[with_threads='none']],
371 [[auto]], [[:]], 372 [[auto]], [[:]],
372 [AC_MSG_ERROR([[incorrect parameter "$with_threads" specified for --with-threads]])] 373 [AC_MSG_ERROR([[incorrect parameter "$with_threads" specified for --with-threads]])]
373) 374)
@@ -398,41 +399,44 @@ AS_IF([[test "x$with_threads" = "xauto"]],
398 ] 399 ]
399) 400)
400 401
401AC_MSG_CHECKING([[for threading lib to use with libmicrohttpd]]) 402AC_MSG_CHECKING([[for threading lib to use with libmicrohttpd ($with_threads)]])
402AS_IF([[test "x$with_threads" = "xposix"]], 403AS_IF([test "x$with_threads" = "xposix"],
403 [ # forced posix threads 404 [ # forced posix threads
404 AS_IF([[test "x$mhd_have_posix_threads" = "xyes"]], [[ USE_THREADS='posix' ]], 405 AS_IF([test "x$mhd_have_posix_threads" = "xyes"], [USE_THREADS='posix'],
405 [ AS_IF([[test "x$os_is_windows" = "xyes"]] , 406 [ AS_IF([[test "x$os_is_windows" = "xyes"]] ,
406 [ AC_MSG_ERROR([[Posix threads are not available. Try to configure --with-threads=auto]])], 407 [ AC_MSG_ERROR([[Posix threads are not available. Try to configure --with-threads=auto]])],
407 [ AC_MSG_ERROR([[No threading lib is available. Consider installing pthreads]])] ) 408 [ AC_MSG_ERROR([[No threading lib is available. Consider installing pthreads]])] )
408 ]) 409 ])
409 ] , 410 ])
410 [[ test "x$with_threads" = "xw32" ]] , 411AS_IF([test "x$with_threads" = "xw32"],
411 [ # forced w32 threads 412 [ # forced w32 threads
412 AS_IF([[test "x$mhd_have_w32_threads" = "xyes"]], 413 AS_IF([[test "x$mhd_have_w32_threads" = "xyes"]],
413 [[ USE_THREADS='w32' ]], 414 [[ USE_THREADS='w32' ]],
414 [ AC_MSG_ERROR([[W32 threads are not available. Try to configure --with-threads=auto]])]) 415 [ AC_MSG_ERROR([[W32 threads are not available. Try to configure --with-threads=auto]])])
415 ] , 416 ])
416 [ # automatic threads lib selection 417AS_IF([test "x$with_threads" = "xauto"],
417 AS_IF([[test "x$os_is_native_w32" = "xyes" && test "x$mhd_have_w32_threads" = "xyes"]] , 418 [# automatic threads lib selection
419 AS_IF([[test "x$os_is_native_w32" = "xyes" && test "x$mhd_have_w32_threads" = "xyes"]] ,
418 [[ USE_THREADS='w32' ]] , 420 [[ USE_THREADS='w32' ]] ,
419 [[ test "x$mhd_have_posix_threads" = "xyes" ]], [[ USE_THREADS='posix' ]], 421 [[ test "x$mhd_have_posix_threads" = "xyes" ]], [[ USE_THREADS='posix' ]],
420 [[ test "x$mhd_have_w32_threads" = "xyes" ]], [[ USE_THREADS='w32' ]], 422 [[ test "x$mhd_have_w32_threads" = "xyes" ]], [[ USE_THREADS='w32' ]],
421 [ AC_MSG_ERROR([[No threading lib is available. Consider installing pthreads]]) ] 423 [ AC_MSG_ERROR([[No threading lib is available. Consider installing pthreads]]) ]
422 ) 424 )])
423 ] 425AS_IF([test "x$with_threads" = "xnone"],
424 ) 426 [USE_THREADS='none'])
427
425AS_IF([test "x$USE_THREADS" = "xposix"], 428AS_IF([test "x$USE_THREADS" = "xposix"],
426 [CC="$PTHREAD_CC" 429 [CC="$PTHREAD_CC"
427 AC_DEFINE([MHD_USE_POSIX_THREADS],[1],[define to use pthreads]) 430 AC_DEFINE([MHD_USE_POSIX_THREADS],[1],[define to use pthreads])
428 MHD_LIB_CFLAGS="$MHD_LIB_CFLAGS $PTHREAD_CFLAGS" 431 MHD_LIB_CFLAGS="$MHD_LIB_CFLAGS $PTHREAD_CFLAGS"
429 MHD_LIBDEPS="$PTHREAD_LIBS $MHD_LIBDEPS" 432 MHD_LIBDEPS="$PTHREAD_LIBS $MHD_LIBDEPS"
430 MHD_LIBDEPS_PKGCFG="$PTHREAD_LIBS $MHD_LIBDEPS_PKGCFG" 433 MHD_LIBDEPS_PKGCFG="$PTHREAD_LIBS $MHD_LIBDEPS_PKGCFG"],
431elif test "x$USE_THREADS" = "xw32"; then 434 [AS_IF([test "x$USE_THREADS" = "xw32"],
432 AC_DEFINE([MHD_USE_W32_THREADS],[1],[define to use W32 threads])]) 435 [AC_DEFINE([MHD_USE_W32_THREADS],[1],[define to use W32 threads])])])
433AM_CONDITIONAL([USE_POSIX_THREADS], [test "x$USE_THREADS" = "xposix"]) 436AM_CONDITIONAL([USE_POSIX_THREADS], [test "x$USE_THREADS" = "xposix"])
434AM_CONDITIONAL([USE_W32_THREADS], [test "x$USE_THREADS" = "xw32"]) 437AM_CONDITIONAL([USE_W32_THREADS], [test "x$USE_THREADS" = "xw32"])
435AC_MSG_RESULT([[$USE_THREADS]]) 438AM_CONDITIONAL([DISABLE_THREADS], [test "x$USE_THREADS" = "xnone"])
439AC_MSG_RESULT([$USE_THREADS])
436 440
437AC_ARG_ENABLE([[thread-names]], 441AC_ARG_ENABLE([[thread-names]],
438 [AS_HELP_STRING([--disable-thread-names [auto] ],[do not set names on MHD generated threads])], 442 [AS_HELP_STRING([--disable-thread-names [auto] ],[do not set names on MHD generated threads])],
diff --git a/doc/libmicrohttpd.texi b/doc/libmicrohttpd.texi
index 7c573736..0776dace 100644
--- a/doc/libmicrohttpd.texi
+++ b/doc/libmicrohttpd.texi
@@ -277,6 +277,9 @@ do not include epoll support, even if it supported (minimally smaller binary siz
277@item ``--enable-coverage'' 277@item ``--enable-coverage''
278set flags for analysis of code-coverage with gcc/gcov (results in slow, large binaries) 278set flags for analysis of code-coverage with gcc/gcov (results in slow, large binaries)
279 279
280@item ``--with-threads={posix,w32,none,auto}''
281sets threading library to use. With use ``none'' to not support threads. In this case, MHD will only support the ``external'' threading modes and not perform any locking of data structures! Use @code{MHD_is_feature_supported(MHD_FEATURE_THREADS)} to test if threads are available. Default is ``auto''.
282
280@item ``--with-gcrypt=PATH'' 283@item ``--with-gcrypt=PATH''
281specifies path to libgcrypt installation 284specifies path to libgcrypt installation
282 285
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index 61d1edef..b9a9bcf9 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -126,7 +126,7 @@ typedef intptr_t ssize_t;
126 * Current version of the library. 126 * Current version of the library.
127 * 0x01093001 = 1.9.30-1. 127 * 0x01093001 = 1.9.30-1.
128 */ 128 */
129#define MHD_VERSION 0x00096100 129#define MHD_VERSION 0x00096101
130 130
131/** 131/**
132 * MHD-internal return code for "YES". 132 * MHD-internal return code for "YES".
@@ -3574,7 +3574,12 @@ enum MHD_FEATURE
3574 * file-FD based responses over non-TLS connections. 3574 * file-FD based responses over non-TLS connections.
3575 * @note Since v0.9.56 3575 * @note Since v0.9.56
3576 */ 3576 */
3577 MHD_FEATURE_SENDFILE = 21 3577 MHD_FEATURE_SENDFILE = 21,
3578
3579 /**
3580 * Get whether MHD supports threads.
3581 */
3582 MHD_FEATURE_THREADS
3578}; 3583};
3579 3584
3580 3585
diff --git a/src/microhttpd/Makefile.am b/src/microhttpd/Makefile.am
index f303b3f9..2c59876a 100644
--- a/src/microhttpd/Makefile.am
+++ b/src/microhttpd/Makefile.am
@@ -62,13 +62,23 @@ libmicrohttpd_la_SOURCES = \
62 mhd_limits.h mhd_byteorder.h \ 62 mhd_limits.h mhd_byteorder.h \
63 sysfdsetsize.c sysfdsetsize.h \ 63 sysfdsetsize.c sysfdsetsize.h \
64 mhd_str.c mhd_str.h \ 64 mhd_str.c mhd_str.h \
65 mhd_threads.c mhd_threads.h \ 65 mhd_assert.h \
66 mhd_locks.h mhd_assert.h \
67 mhd_sockets.c mhd_sockets.h \ 66 mhd_sockets.c mhd_sockets.h \
68 mhd_itc.c mhd_itc.h mhd_itc_types.h \ 67 mhd_itc.c mhd_itc.h mhd_itc_types.h \
69 mhd_compat.c mhd_compat.h \ 68 mhd_compat.c mhd_compat.h \
70 response.c response.h 69 response.c response.h
71 70
71if USE_POSIX_THREADS
72libmicrohttpd_la_SOURCES += \
73 mhd_threads.c mhd_threads.h \
74 mhd_locks.h
75endif
76if USE_W32_THREADS
77libmicrohttpd_la_SOURCES += \
78 mhd_threads.c mhd_threads.h \
79 mhd_locks.h
80endif
81
72libmicrohttpd_la_CPPFLAGS = \ 82libmicrohttpd_la_CPPFLAGS = \
73 $(AM_CPPFLAGS) $(MHD_LIB_CPPFLAGS) $(MHD_TLS_LIB_CPPFLAGS) \ 83 $(AM_CPPFLAGS) $(MHD_LIB_CPPFLAGS) $(MHD_TLS_LIB_CPPFLAGS) \
74 -DBUILDING_MHD_LIB=1 84 -DBUILDING_MHD_LIB=1
@@ -150,9 +160,19 @@ check_PROGRAMS = \
150 160
151if HAVE_POSIX_THREADS 161if HAVE_POSIX_THREADS
152if ENABLE_UPGRADE 162if ENABLE_UPGRADE
163if USE_POSIX_THREADS
164 check_PROGRAMS += test_upgrade
165endif
166if USE_W32_THREADS
153 check_PROGRAMS += test_upgrade 167 check_PROGRAMS += test_upgrade
168endif
154if ENABLE_HTTPS 169if ENABLE_HTTPS
155 check_PROGRAMS += test_upgrade_tls 170if USE_POSIX_THREADS
171check_PROGRAMS += test_upgrade_tls
172endif
173if USE_W32_THREADS
174check_PROGRAMS += test_upgrade_tls
175endif
156endif 176endif
157endif 177endif
158endif 178endif
@@ -170,6 +190,7 @@ TESTS = $(check_PROGRAMS)
170# on Cygwin as this ability is deliberately ignored on Cygwin 190# on Cygwin as this ability is deliberately ignored on Cygwin
171# to improve compatibility with core OS. 191# to improve compatibility with core OS.
172if !CYGWIN_TARGET 192if !CYGWIN_TARGET
193if USE_POSIX_THREADS
173if HAVE_LISTEN_SHUTDOWN 194if HAVE_LISTEN_SHUTDOWN
174check_PROGRAMS += \ 195check_PROGRAMS += \
175 test_shutdown_select \ 196 test_shutdown_select \
@@ -180,6 +201,7 @@ check_PROGRAMS += \
180 test_shutdown_poll_ignore 201 test_shutdown_poll_ignore
181endif 202endif
182endif 203endif
204endif
183 205
184test_start_stop_SOURCES = \ 206test_start_stop_SOURCES = \
185 test_start_stop.c 207 test_start_stop.c
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index cd4e8257..542c5a40 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -32,7 +32,9 @@
32#include "response.h" 32#include "response.h"
33#include "mhd_mono_clock.h" 33#include "mhd_mono_clock.h"
34#include "mhd_str.h" 34#include "mhd_str.h"
35#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
35#include "mhd_locks.h" 36#include "mhd_locks.h"
37#endif
36#include "mhd_sockets.h" 38#include "mhd_sockets.h"
37#include "mhd_compat.h" 39#include "mhd_compat.h"
38#include "mhd_itc.h" 40#include "mhd_itc.h"
@@ -1104,7 +1106,9 @@ try_ready_normal_body (struct MHD_Connection *connection)
1104 { 1106 {
1105 /* either error or http 1.0 transfer, close socket! */ 1107 /* either error or http 1.0 transfer, close socket! */
1106 response->total_size = connection->response_write_position; 1108 response->total_size = connection->response_write_position;
1109#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1107 MHD_mutex_unlock_chk_ (&response->mutex); 1110 MHD_mutex_unlock_chk_ (&response->mutex);
1111#endif
1108 if ( ((ssize_t)MHD_CONTENT_READER_END_OF_STREAM) == ret) 1112 if ( ((ssize_t)MHD_CONTENT_READER_END_OF_STREAM) == ret)
1109 MHD_connection_close_ (connection, 1113 MHD_connection_close_ (connection,
1110 MHD_REQUEST_TERMINATED_COMPLETED_OK); 1114 MHD_REQUEST_TERMINATED_COMPLETED_OK);
@@ -1118,7 +1122,9 @@ try_ready_normal_body (struct MHD_Connection *connection)
1118 if (0 == ret) 1122 if (0 == ret)
1119 { 1123 {
1120 connection->state = MHD_CONNECTION_NORMAL_BODY_UNREADY; 1124 connection->state = MHD_CONNECTION_NORMAL_BODY_UNREADY;
1125#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1121 MHD_mutex_unlock_chk_ (&response->mutex); 1126 MHD_mutex_unlock_chk_ (&response->mutex);
1127#endif
1122 return MHD_NO; 1128 return MHD_NO;
1123 } 1129 }
1124 return MHD_YES; 1130 return MHD_YES;
@@ -1156,7 +1162,9 @@ try_ready_chunked_body (struct MHD_Connection *connection)
1156 size /= 2; 1162 size /= 2;
1157 if (size < 128) 1163 if (size < 128)
1158 { 1164 {
1165#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1159 MHD_mutex_unlock_chk_ (&response->mutex); 1166 MHD_mutex_unlock_chk_ (&response->mutex);
1167#endif
1160 /* not enough memory */ 1168 /* not enough memory */
1161 CONNECTION_CLOSE_ERROR (connection, 1169 CONNECTION_CLOSE_ERROR (connection,
1162 _("Closing connection (out of memory)\n")); 1170 _("Closing connection (out of memory)\n"));
@@ -1202,7 +1210,9 @@ try_ready_chunked_body (struct MHD_Connection *connection)
1202 { 1210 {
1203 /* error, close socket! */ 1211 /* error, close socket! */
1204 response->total_size = connection->response_write_position; 1212 response->total_size = connection->response_write_position;
1213#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1205 MHD_mutex_unlock_chk_ (&response->mutex); 1214 MHD_mutex_unlock_chk_ (&response->mutex);
1215#endif
1206 CONNECTION_CLOSE_ERROR (connection, 1216 CONNECTION_CLOSE_ERROR (connection,
1207 _("Closing connection (application error generating response)\n")); 1217 _("Closing connection (application error generating response)\n"));
1208 return MHD_NO; 1218 return MHD_NO;
@@ -1222,7 +1232,9 @@ try_ready_chunked_body (struct MHD_Connection *connection)
1222 if (0 == ret) 1232 if (0 == ret)
1223 { 1233 {
1224 connection->state = MHD_CONNECTION_CHUNKED_BODY_UNREADY; 1234 connection->state = MHD_CONNECTION_CHUNKED_BODY_UNREADY;
1235#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1225 MHD_mutex_unlock_chk_ (&response->mutex); 1236 MHD_mutex_unlock_chk_ (&response->mutex);
1237#endif
1226 return MHD_NO; 1238 return MHD_NO;
1227 } 1239 }
1228 if (ret > 0xFFFFFF) 1240 if (ret > 0xFFFFFF)
@@ -2861,8 +2873,9 @@ MHD_update_last_activity_ (struct MHD_Connection *connection)
2861 2873
2862 if (connection->connection_timeout != daemon->connection_timeout) 2874 if (connection->connection_timeout != daemon->connection_timeout)
2863 return; /* custom timeout, no need to move it in "normal" DLL */ 2875 return; /* custom timeout, no need to move it in "normal" DLL */
2864 2876#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2865 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 2877 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
2878#endif
2866 /* move connection to head of timeout list (by remove + add operation) */ 2879 /* move connection to head of timeout list (by remove + add operation) */
2867 XDLL_remove (daemon->normal_timeout_head, 2880 XDLL_remove (daemon->normal_timeout_head,
2868 daemon->normal_timeout_tail, 2881 daemon->normal_timeout_tail,
@@ -2870,7 +2883,9 @@ MHD_update_last_activity_ (struct MHD_Connection *connection)
2870 XDLL_insert (daemon->normal_timeout_head, 2883 XDLL_insert (daemon->normal_timeout_head,
2871 daemon->normal_timeout_tail, 2884 daemon->normal_timeout_tail,
2872 connection); 2885 connection);
2886#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2873 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 2887 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
2888#endif
2874} 2889}
2875 2890
2876 2891
@@ -3088,8 +3103,10 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
3088 { 3103 {
3089 uint64_t data_write_offset; 3104 uint64_t data_write_offset;
3090 3105
3106#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3091 if (NULL != response->crc) 3107 if (NULL != response->crc)
3092 MHD_mutex_lock_chk_ (&response->mutex); 3108 MHD_mutex_lock_chk_ (&response->mutex);
3109#endif
3093 if (MHD_YES != try_ready_normal_body (connection)) 3110 if (MHD_YES != try_ready_normal_body (connection))
3094 { 3111 {
3095 /* mutex was already unlocked by try_ready_normal_body */ 3112 /* mutex was already unlocked by try_ready_normal_body */
@@ -3124,8 +3141,10 @@ MHD_connection_handle_write (struct MHD_Connection *connection)
3124 response->data_start]); 3141 response->data_start]);
3125#endif 3142#endif
3126 } 3143 }
3144#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3127 if (NULL != response->crc) 3145 if (NULL != response->crc)
3128 MHD_mutex_unlock_chk_ (&response->mutex); 3146 MHD_mutex_unlock_chk_ (&response->mutex);
3147#endif
3129 if (ret < 0) 3148 if (ret < 0)
3130 { 3149 {
3131 if (MHD_ERR_AGAIN_ == ret) 3150 if (MHD_ERR_AGAIN_ == ret)
@@ -3239,7 +3258,9 @@ cleanup_connection (struct MHD_Connection *connection)
3239 MHD_destroy_response (connection->response); 3258 MHD_destroy_response (connection->response);
3240 connection->response = NULL; 3259 connection->response = NULL;
3241 } 3260 }
3261#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3242 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 3262 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
3263#endif
3243 if (connection->suspended) 3264 if (connection->suspended)
3244 { 3265 {
3245 DLL_remove (daemon->suspended_connections_head, 3266 DLL_remove (daemon->suspended_connections_head,
@@ -3269,7 +3290,9 @@ cleanup_connection (struct MHD_Connection *connection)
3269 connection); 3290 connection);
3270 connection->resuming = false; 3291 connection->resuming = false;
3271 connection->in_idle = false; 3292 connection->in_idle = false;
3293#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3272 MHD_mutex_unlock_chk_(&daemon->cleanup_connection_mutex); 3294 MHD_mutex_unlock_chk_(&daemon->cleanup_connection_mutex);
3295#endif
3273 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) 3296 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
3274 { 3297 {
3275 /* if we were at the connection limit before and are in 3298 /* if we were at the connection limit before and are in
@@ -3610,19 +3633,25 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
3610 /* nothing to do here */ 3633 /* nothing to do here */
3611 break; 3634 break;
3612 case MHD_CONNECTION_NORMAL_BODY_UNREADY: 3635 case MHD_CONNECTION_NORMAL_BODY_UNREADY:
3636#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3613 if (NULL != connection->response->crc) 3637 if (NULL != connection->response->crc)
3614 MHD_mutex_lock_chk_ (&connection->response->mutex); 3638 MHD_mutex_lock_chk_ (&connection->response->mutex);
3639#endif
3615 if (0 == connection->response->total_size) 3640 if (0 == connection->response->total_size)
3616 { 3641 {
3642#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3617 if (NULL != connection->response->crc) 3643 if (NULL != connection->response->crc)
3618 MHD_mutex_unlock_chk_ (&connection->response->mutex); 3644 MHD_mutex_unlock_chk_ (&connection->response->mutex);
3645#endif
3619 connection->state = MHD_CONNECTION_BODY_SENT; 3646 connection->state = MHD_CONNECTION_BODY_SENT;
3620 continue; 3647 continue;
3621 } 3648 }
3622 if (MHD_YES == try_ready_normal_body (connection)) 3649 if (MHD_YES == try_ready_normal_body (connection))
3623 { 3650 {
3651#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3624 if (NULL != connection->response->crc) 3652 if (NULL != connection->response->crc)
3625 MHD_mutex_unlock_chk_ (&connection->response->mutex); 3653 MHD_mutex_unlock_chk_ (&connection->response->mutex);
3654#endif
3626 connection->state = MHD_CONNECTION_NORMAL_BODY_READY; 3655 connection->state = MHD_CONNECTION_NORMAL_BODY_READY;
3627 /* Buffering for flushable socket was already enabled*/ 3656 /* Buffering for flushable socket was already enabled*/
3628 if (MHD_NO == socket_flush_possible (connection)) 3657 if (MHD_NO == socket_flush_possible (connection))
@@ -3636,21 +3665,27 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
3636 /* nothing to do here */ 3665 /* nothing to do here */
3637 break; 3666 break;
3638 case MHD_CONNECTION_CHUNKED_BODY_UNREADY: 3667 case MHD_CONNECTION_CHUNKED_BODY_UNREADY:
3668#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3639 if (NULL != connection->response->crc) 3669 if (NULL != connection->response->crc)
3640 MHD_mutex_lock_chk_ (&connection->response->mutex); 3670 MHD_mutex_lock_chk_ (&connection->response->mutex);
3671#endif
3641 if ( (0 == connection->response->total_size) || 3672 if ( (0 == connection->response->total_size) ||
3642 (connection->response_write_position == 3673 (connection->response_write_position ==
3643 connection->response->total_size) ) 3674 connection->response->total_size) )
3644 { 3675 {
3676#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3645 if (NULL != connection->response->crc) 3677 if (NULL != connection->response->crc)
3646 MHD_mutex_unlock_chk_ (&connection->response->mutex); 3678 MHD_mutex_unlock_chk_ (&connection->response->mutex);
3679#endif
3647 connection->state = MHD_CONNECTION_BODY_SENT; 3680 connection->state = MHD_CONNECTION_BODY_SENT;
3648 continue; 3681 continue;
3649 } 3682 }
3650 if (MHD_YES == try_ready_chunked_body (connection)) 3683 if (MHD_YES == try_ready_chunked_body (connection))
3651 { 3684 {
3685#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3652 if (NULL != connection->response->crc) 3686 if (NULL != connection->response->crc)
3653 MHD_mutex_unlock_chk_ (&connection->response->mutex); 3687 MHD_mutex_unlock_chk_ (&connection->response->mutex);
3688#endif
3654 connection->state = MHD_CONNECTION_CHUNKED_BODY_READY; 3689 connection->state = MHD_CONNECTION_CHUNKED_BODY_READY;
3655 /* Buffering for flushable socket was already enabled */ 3690 /* Buffering for flushable socket was already enabled */
3656 if (MHD_NO == socket_flush_possible (connection)) 3691 if (MHD_NO == socket_flush_possible (connection))
@@ -3937,8 +3972,9 @@ MHD_set_connection_option (struct MHD_Connection *connection,
3937 case MHD_CONNECTION_OPTION_TIMEOUT: 3972 case MHD_CONNECTION_OPTION_TIMEOUT:
3938 if (0 == connection->connection_timeout) 3973 if (0 == connection->connection_timeout)
3939 connection->last_activity = MHD_monotonic_sec_counter(); 3974 connection->last_activity = MHD_monotonic_sec_counter();
3940 3975#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3941 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 3976 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
3977#endif
3942 if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 3978 if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
3943 (! connection->suspended) ) 3979 (! connection->suspended) )
3944 { 3980 {
@@ -3967,7 +4003,9 @@ MHD_set_connection_option (struct MHD_Connection *connection,
3967 daemon->manual_timeout_tail, 4003 daemon->manual_timeout_tail,
3968 connection); 4004 connection);
3969 } 4005 }
4006#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3970 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 4007 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
4008#endif
3971 return MHD_YES; 4009 return MHD_YES;
3972 default: 4010 default:
3973 return MHD_NO; 4011 return MHD_NO;
@@ -4005,6 +4043,7 @@ MHD_queue_response (struct MHD_Connection *connection,
4005 return MHD_YES; /* If daemon was shut down in parallel, 4043 return MHD_YES; /* If daemon was shut down in parallel,
4006 * response will be aborted now or on later stage. */ 4044 * response will be aborted now or on later stage. */
4007 4045
4046#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4008 if ( (!connection->suspended) && 4047 if ( (!connection->suspended) &&
4009 (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) && 4048 (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) &&
4010 (!MHD_thread_ID_match_current_(connection->pid.ID)) ) 4049 (!MHD_thread_ID_match_current_(connection->pid.ID)) )
@@ -4015,6 +4054,7 @@ MHD_queue_response (struct MHD_Connection *connection,
4015#endif 4054#endif
4016 return MHD_NO; 4055 return MHD_NO;
4017 } 4056 }
4057#endif
4018#ifdef UPGRADE_SUPPORT 4058#ifdef UPGRADE_SUPPORT
4019 if ( (NULL != response->upgrade_handler) && 4059 if ( (NULL != response->upgrade_handler) &&
4020 (0 == (daemon->options & MHD_ALLOW_UPGRADE)) ) 4060 (0 == (daemon->options & MHD_ALLOW_UPGRADE)) )
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 7a310c1f..926a983e 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -26,7 +26,9 @@
26 * @author Karlson2k (Evgeny Grin) 26 * @author Karlson2k (Evgeny Grin)
27 */ 27 */
28#include "platform.h" 28#include "platform.h"
29#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
29#include "mhd_threads.h" 30#include "mhd_threads.h"
31#endif
30#include "internal.h" 32#include "internal.h"
31#include "response.h" 33#include "response.h"
32#include "connection.h" 34#include "connection.h"
@@ -34,7 +36,9 @@
34#include "mhd_limits.h" 36#include "mhd_limits.h"
35#include "autoinit_funcs.h" 37#include "autoinit_funcs.h"
36#include "mhd_mono_clock.h" 38#include "mhd_mono_clock.h"
39#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
37#include "mhd_locks.h" 40#include "mhd_locks.h"
41#endif
38#include "mhd_sockets.h" 42#include "mhd_sockets.h"
39#include "mhd_itc.h" 43#include "mhd_itc.h"
40#include "mhd_compat.h" 44#include "mhd_compat.h"
@@ -181,12 +185,17 @@ static int mhd_winsock_inited_ = 0;
181 * Track global initialisation 185 * Track global initialisation
182 */ 186 */
183volatile int global_init_count = 0; 187volatile int global_init_count = 0;
188
189#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
184#ifdef MHD_MUTEX_STATIC_DEFN_INIT_ 190#ifdef MHD_MUTEX_STATIC_DEFN_INIT_
185/** 191/**
186 * Global initialisation mutex 192 * Global initialisation mutex
187 */ 193 */
188MHD_MUTEX_STATIC_DEFN_INIT_(global_init_mutex_); 194MHD_MUTEX_STATIC_DEFN_INIT_(global_init_mutex_);
189#endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */ 195#endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
196#endif
197
198
190/** 199/**
191 * Check whether global initialisation was performed 200 * Check whether global initialisation was performed
192 * and call initialiser if necessary. 201 * and call initialiser if necessary.
@@ -194,14 +203,18 @@ MHD_MUTEX_STATIC_DEFN_INIT_(global_init_mutex_);
194void 203void
195MHD_check_global_init_ (void) 204MHD_check_global_init_ (void)
196{ 205{
206#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
197#ifdef MHD_MUTEX_STATIC_DEFN_INIT_ 207#ifdef MHD_MUTEX_STATIC_DEFN_INIT_
198 MHD_mutex_lock_chk_(&global_init_mutex_); 208 MHD_mutex_lock_chk_(&global_init_mutex_);
199#endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */ 209#endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
210#endif
200 if (0 == global_init_count++) 211 if (0 == global_init_count++)
201 MHD_init (); 212 MHD_init ();
213#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
202#ifdef MHD_MUTEX_STATIC_DEFN_INIT_ 214#ifdef MHD_MUTEX_STATIC_DEFN_INIT_
203 MHD_mutex_unlock_chk_(&global_init_mutex_); 215 MHD_mutex_unlock_chk_(&global_init_mutex_);
204#endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */ 216#endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
217#endif
205} 218}
206#endif /* ! _AUTOINIT_FUNCS_ARE_SUPPORTED */ 219#endif /* ! _AUTOINIT_FUNCS_ARE_SUPPORTED */
207 220
@@ -263,7 +276,11 @@ struct MHD_IPCount
263static void 276static void
264MHD_ip_count_lock (struct MHD_Daemon *daemon) 277MHD_ip_count_lock (struct MHD_Daemon *daemon)
265{ 278{
279#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
266 MHD_mutex_lock_chk_(&daemon->per_ip_connection_mutex); 280 MHD_mutex_lock_chk_(&daemon->per_ip_connection_mutex);
281#else
282 (void) daemon;
283#endif
267} 284}
268 285
269 286
@@ -275,7 +292,11 @@ MHD_ip_count_lock (struct MHD_Daemon *daemon)
275static void 292static void
276MHD_ip_count_unlock (struct MHD_Daemon *daemon) 293MHD_ip_count_unlock (struct MHD_Daemon *daemon)
277{ 294{
295#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
278 MHD_mutex_unlock_chk_(&daemon->per_ip_connection_mutex); 296 MHD_mutex_unlock_chk_(&daemon->per_ip_connection_mutex);
297#else
298 (void) daemon;
299#endif
279} 300}
280 301
281 302
@@ -1177,7 +1198,7 @@ call_handlers (struct MHD_Connection *con,
1177 /* Note: no need to check for read buffer availability for 1198 /* Note: no need to check for read buffer availability for
1178 * TLS read-ready connection in 'read info' state as connection 1199 * TLS read-ready connection in 'read info' state as connection
1179 * without space in read buffer will be market as 'info block'. */ 1200 * without space in read buffer will be market as 'info block'. */
1180 if ( (!con->daemon->data_already_pending) && 1201 if ( (! con->daemon->data_already_pending) &&
1181 (0 == (con->daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ) 1202 (0 == (con->daemon->options & MHD_USE_THREAD_PER_CONNECTION)) )
1182 { 1203 {
1183 if (MHD_EVENT_LOOP_INFO_BLOCK == con->event_loop_info) 1204 if (MHD_EVENT_LOOP_INFO_BLOCK == con->event_loop_info)
@@ -1230,7 +1251,7 @@ cleanup_upgraded_connection (struct MHD_Connection *connection)
1230/** 1251/**
1231 * Performs bi-directional forwarding on upgraded HTTPS connections 1252 * Performs bi-directional forwarding on upgraded HTTPS connections
1232 * based on the readyness state stored in the @a urh handle. 1253 * based on the readyness state stored in the @a urh handle.
1233 * @remark To be called only from thread that process 1254 * @remark To be called only from thread that processes
1234 * connection's recv(), send() and response. 1255 * connection's recv(), send() and response.
1235 * 1256 *
1236 * @param urh handle to process 1257 * @param urh handle to process
@@ -1573,7 +1594,7 @@ process_urh (struct MHD_UpgradeResponseHandle *urh)
1573} 1594}
1574#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 1595#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
1575 1596
1576 1597#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1577#ifdef UPGRADE_SUPPORT 1598#ifdef UPGRADE_SUPPORT
1578/** 1599/**
1579 * Main function of the thread that handles an individual connection 1600 * Main function of the thread that handles an individual connection
@@ -2108,6 +2129,7 @@ exit:
2108 } 2129 }
2109 return (MHD_THRD_RTRN_TYPE_) 0; 2130 return (MHD_THRD_RTRN_TYPE_) 0;
2110} 2131}
2132#endif
2111 2133
2112 2134
2113/** 2135/**
@@ -2253,10 +2275,13 @@ internal_add_connection (struct MHD_Daemon *daemon,
2253 bool non_blck) 2275 bool non_blck)
2254{ 2276{
2255 struct MHD_Connection *connection; 2277 struct MHD_Connection *connection;
2278#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2256 unsigned int i; 2279 unsigned int i;
2280#endif
2257 int eno = 0; 2281 int eno = 0;
2258 2282
2259 /* Direct add to master daemon could happen only with "external" add mode. */ 2283 /* Direct add to master daemon could happen only with "external" add mode. */
2284#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2260 mhd_assert ((NULL == daemon->worker_pool) || (external_add)); 2285 mhd_assert ((NULL == daemon->worker_pool) || (external_add));
2261 if ((external_add) && (NULL != daemon->worker_pool)) 2286 if ((external_add) && (NULL != daemon->worker_pool))
2262 { 2287 {
@@ -2282,6 +2307,7 @@ internal_add_connection (struct MHD_Daemon *daemon,
2282#endif 2307#endif
2283 return MHD_NO; 2308 return MHD_NO;
2284 } 2309 }
2310#endif
2285 2311
2286 if ( (! MHD_SCKT_FD_FITS_FDSET_(client_socket, 2312 if ( (! MHD_SCKT_FD_FITS_FDSET_(client_socket,
2287 NULL)) && 2313 NULL)) &&
@@ -2502,11 +2528,15 @@ internal_add_connection (struct MHD_Daemon *daemon,
2502#endif /* ! HTTPS_SUPPORT */ 2528#endif /* ! HTTPS_SUPPORT */
2503 } 2529 }
2504 2530
2531#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2505 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 2532 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
2533#endif
2506 /* Firm check under lock. */ 2534 /* Firm check under lock. */
2507 if (daemon->connections >= daemon->connection_limit) 2535 if (daemon->connections >= daemon->connection_limit)
2508 { 2536 {
2537#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2509 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 2538 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
2539#endif
2510 /* above connection limit - reject */ 2540 /* above connection limit - reject */
2511#ifdef HAVE_MESSAGES 2541#ifdef HAVE_MESSAGES
2512 MHD_DLOG (daemon, 2542 MHD_DLOG (daemon,
@@ -2527,14 +2557,15 @@ internal_add_connection (struct MHD_Daemon *daemon,
2527 DLL_insert (daemon->connections_head, 2557 DLL_insert (daemon->connections_head,
2528 daemon->connections_tail, 2558 daemon->connections_tail,
2529 connection); 2559 connection);
2560#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2530 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 2561 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
2531 2562#endif
2532 if (NULL != daemon->notify_connection) 2563 if (NULL != daemon->notify_connection)
2533 daemon->notify_connection (daemon->notify_connection_cls, 2564 daemon->notify_connection (daemon->notify_connection_cls,
2534 connection, 2565 connection,
2535 &connection->socket_context, 2566 &connection->socket_context,
2536 MHD_CONNECTION_NOTIFY_STARTED); 2567 MHD_CONNECTION_NOTIFY_STARTED);
2537 2568#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2538 /* attempt to create handler thread */ 2569 /* attempt to create handler thread */
2539 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) 2570 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2540 { 2571 {
@@ -2555,6 +2586,7 @@ internal_add_connection (struct MHD_Daemon *daemon,
2555 } 2586 }
2556 else 2587 else
2557 connection->pid = daemon->pid; 2588 connection->pid = daemon->pid;
2589#endif
2558#ifdef EPOLL_SUPPORT 2590#ifdef EPOLL_SUPPORT
2559 if (0 != (daemon->options & MHD_USE_EPOLL)) 2591 if (0 != (daemon->options & MHD_USE_EPOLL))
2560 { 2592 {
@@ -2615,7 +2647,9 @@ internal_add_connection (struct MHD_Daemon *daemon,
2615 MHD_ip_limit_del (daemon, 2647 MHD_ip_limit_del (daemon,
2616 addr, 2648 addr,
2617 addrlen); 2649 addrlen);
2650#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2618 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 2651 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
2652#endif
2619 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) 2653 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2620 { 2654 {
2621 XDLL_remove (daemon->normal_timeout_head, 2655 XDLL_remove (daemon->normal_timeout_head,
@@ -2625,7 +2659,9 @@ internal_add_connection (struct MHD_Daemon *daemon,
2625 DLL_remove (daemon->connections_head, 2659 DLL_remove (daemon->connections_head,
2626 daemon->connections_tail, 2660 daemon->connections_tail,
2627 connection); 2661 connection);
2662#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2628 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 2663 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
2664#endif
2629 MHD_pool_destroy (connection->pool); 2665 MHD_pool_destroy (connection->pool);
2630 free (connection->addr); 2666 free (connection->addr);
2631 free (connection); 2667 free (connection);
@@ -2651,12 +2687,16 @@ internal_suspend_connection_ (struct MHD_Connection *connection)
2651{ 2687{
2652 struct MHD_Daemon *daemon = connection->daemon; 2688 struct MHD_Daemon *daemon = connection->daemon;
2653 2689
2690#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2654 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 2691 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
2692#endif
2655 if (connection->resuming) 2693 if (connection->resuming)
2656 { 2694 {
2657 /* suspending again while we didn't even complete resuming yet */ 2695 /* suspending again while we didn't even complete resuming yet */
2658 connection->resuming = false; 2696 connection->resuming = false;
2697#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2659 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 2698 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
2699#endif
2660 return; 2700 return;
2661 } 2701 }
2662 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) 2702 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
@@ -2700,7 +2740,9 @@ internal_suspend_connection_ (struct MHD_Connection *connection)
2700 connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED; 2740 connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED;
2701 } 2741 }
2702#endif 2742#endif
2743#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2703 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 2744 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
2745#endif
2704} 2746}
2705 2747
2706 2748
@@ -2771,10 +2813,14 @@ MHD_resume_connection (struct MHD_Connection *connection)
2771 2813
2772 if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) 2814 if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
2773 MHD_PANIC (_("Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n")); 2815 MHD_PANIC (_("Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
2816#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2774 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 2817 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
2818#endif
2775 connection->resuming = true; 2819 connection->resuming = true;
2776 daemon->resuming = true; 2820 daemon->resuming = true;
2821#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2777 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 2822 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
2823#endif
2778 if ( (MHD_ITC_IS_VALID_(daemon->itc)) && 2824 if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
2779 (! MHD_itc_activate_ (daemon->itc, "r")) ) 2825 (! MHD_itc_activate_ (daemon->itc, "r")) )
2780 { 2826 {
@@ -2802,11 +2848,13 @@ resume_suspended_connections (struct MHD_Daemon *daemon)
2802 struct MHD_Connection *prev = NULL; 2848 struct MHD_Connection *prev = NULL;
2803 int ret; 2849 int ret;
2804 const bool used_thr_p_c = (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)); 2850 const bool used_thr_p_c = (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION));
2851#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2805 mhd_assert (NULL == daemon->worker_pool); 2852 mhd_assert (NULL == daemon->worker_pool);
2806 2853#endif
2807 ret = MHD_NO; 2854 ret = MHD_NO;
2855#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2808 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 2856 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
2809 2857#endif
2810 if (daemon->resuming) 2858 if (daemon->resuming)
2811 { 2859 {
2812 prev = daemon->suspended_connections_tail; 2860 prev = daemon->suspended_connections_tail;
@@ -2899,7 +2947,9 @@ resume_suspended_connections (struct MHD_Daemon *daemon)
2899#endif /* UPGRADE_SUPPORT */ 2947#endif /* UPGRADE_SUPPORT */
2900 pos->resuming = false; 2948 pos->resuming = false;
2901 } 2949 }
2950#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2902 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 2951 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
2952#endif
2903 if ( (used_thr_p_c) && 2953 if ( (used_thr_p_c) &&
2904 (MHD_NO != ret) ) 2954 (MHD_NO != ret) )
2905 { /* Wake up suspended connections. */ 2955 { /* Wake up suspended connections. */
@@ -3062,9 +3112,13 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
3062 } 3112 }
3063 else 3113 else
3064 { 3114 {
3115#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3065 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 3116 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
3117#endif
3066 daemon->at_limit = true; 3118 daemon->at_limit = true;
3119#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3067 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 3120 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
3121#endif
3068#ifdef HAVE_MESSAGES 3122#ifdef HAVE_MESSAGES
3069 MHD_DLOG (daemon, 3123 MHD_DLOG (daemon,
3070 _("Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"), 3124 _("Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"),
@@ -3126,18 +3180,21 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon)
3126{ 3180{
3127 struct MHD_Connection *pos; 3181 struct MHD_Connection *pos;
3128 3182
3183#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3129 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 3184 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
3185#endif
3130 while (NULL != (pos = daemon->cleanup_tail)) 3186 while (NULL != (pos = daemon->cleanup_tail))
3131 { 3187 {
3132 DLL_remove (daemon->cleanup_head, 3188 DLL_remove (daemon->cleanup_head,
3133 daemon->cleanup_tail, 3189 daemon->cleanup_tail,
3134 pos); 3190 pos);
3191#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3135 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 3192 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
3136
3137 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 3193 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
3138 (! pos->thread_joined) && 3194 (! pos->thread_joined) &&
3139 (! MHD_join_thread_ (pos->pid.handle)) ) 3195 (! MHD_join_thread_ (pos->pid.handle)) )
3140 MHD_PANIC (_("Failed to join a thread\n")); 3196 MHD_PANIC (_("Failed to join a thread\n"));
3197#endif
3141#ifdef UPGRADE_SUPPORT 3198#ifdef UPGRADE_SUPPORT
3142 cleanup_upgraded_connection (pos); 3199 cleanup_upgraded_connection (pos);
3143#endif /* UPGRADE_SUPPORT */ 3200#endif /* UPGRADE_SUPPORT */
@@ -3195,11 +3252,15 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon)
3195 free (pos->addr); 3252 free (pos->addr);
3196 free (pos); 3253 free (pos);
3197 3254
3255#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3198 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 3256 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
3257#endif
3199 daemon->connections--; 3258 daemon->connections--;
3200 daemon->at_limit = false; 3259 daemon->at_limit = false;
3201 } 3260 }
3261#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3202 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 3262 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
3263#endif
3203} 3264}
3204 3265
3205 3266
@@ -4489,9 +4550,9 @@ close_connection (struct MHD_Connection *pos)
4489 } 4550 }
4490 MHD_connection_close_ (pos, 4551 MHD_connection_close_ (pos,
4491 MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN); 4552 MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN);
4492 4553#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4493 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 4554 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
4494 4555#endif
4495 mhd_assert (! pos->suspended); 4556 mhd_assert (! pos->suspended);
4496 mhd_assert (! pos->resuming); 4557 mhd_assert (! pos->resuming);
4497 if (pos->connection_timeout == daemon->connection_timeout) 4558 if (pos->connection_timeout == daemon->connection_timeout)
@@ -4508,11 +4569,13 @@ close_connection (struct MHD_Connection *pos)
4508 DLL_insert (daemon->cleanup_head, 4569 DLL_insert (daemon->cleanup_head,
4509 daemon->cleanup_tail, 4570 daemon->cleanup_tail,
4510 pos); 4571 pos);
4511 4572#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4512 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 4573 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
4574#endif
4513} 4575}
4514 4576
4515 4577
4578#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4516/** 4579/**
4517 * Thread that runs the polling loop until the daemon 4580 * Thread that runs the polling loop until the daemon
4518 * is explicitly shut down. 4581 * is explicitly shut down.
@@ -4548,6 +4611,7 @@ MHD_polling_thread (void *cls)
4548 4611
4549 return (MHD_THRD_RTRN_TYPE_)0; 4612 return (MHD_THRD_RTRN_TYPE_)0;
4550} 4613}
4614#endif
4551 4615
4552 4616
4553/** 4617/**
@@ -4567,6 +4631,7 @@ unescape_wrapper (void *cls,
4567 char *val) 4631 char *val)
4568{ 4632{
4569 (void) cls; /* Mute compiler warning. */ 4633 (void) cls; /* Mute compiler warning. */
4634
4570 (void) connection; /* Mute compiler warning. */ 4635 (void) connection; /* Mute compiler warning. */
4571 return MHD_http_unescape (val); 4636 return MHD_http_unescape (val);
4572} 4637}
@@ -4640,7 +4705,9 @@ MHD_start_daemon (unsigned int flags,
4640MHD_socket 4705MHD_socket
4641MHD_quiesce_daemon (struct MHD_Daemon *daemon) 4706MHD_quiesce_daemon (struct MHD_Daemon *daemon)
4642{ 4707{
4708#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4643 unsigned int i; 4709 unsigned int i;
4710#endif
4644 MHD_socket ret; 4711 MHD_socket ret;
4645 4712
4646 ret = daemon->listen_fd; 4713 ret = daemon->listen_fd;
@@ -4655,7 +4722,8 @@ MHD_quiesce_daemon (struct MHD_Daemon *daemon)
4655#endif 4722#endif
4656 return MHD_INVALID_SOCKET; 4723 return MHD_INVALID_SOCKET;
4657 } 4724 }
4658 4725
4726#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4659 if (NULL != daemon->worker_pool) 4727 if (NULL != daemon->worker_pool)
4660 for (i = 0; i < daemon->worker_pool_size; i++) 4728 for (i = 0; i < daemon->worker_pool_size; i++)
4661 { 4729 {
@@ -4680,6 +4748,7 @@ MHD_quiesce_daemon (struct MHD_Daemon *daemon)
4680 MHD_PANIC (_("Failed to signal quiesce via inter-thread communication channel")); 4748 MHD_PANIC (_("Failed to signal quiesce via inter-thread communication channel"));
4681 } 4749 }
4682 } 4750 }
4751#endif
4683 daemon->was_quiesced = true; 4752 daemon->was_quiesced = true;
4684#ifdef EPOLL_SUPPORT 4753#ifdef EPOLL_SUPPORT
4685 if ( (0 != (daemon->options & MHD_USE_EPOLL)) && 4754 if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
@@ -4839,6 +4908,7 @@ parse_options_va (struct MHD_Daemon *daemon,
4839 daemon->uri_log_callback_cls = va_arg (ap, 4908 daemon->uri_log_callback_cls = va_arg (ap,
4840 void *); 4909 void *);
4841 break; 4910 break;
4911#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4842 case MHD_OPTION_THREAD_POOL_SIZE: 4912 case MHD_OPTION_THREAD_POOL_SIZE:
4843 daemon->worker_pool_size = va_arg (ap, 4913 daemon->worker_pool_size = va_arg (ap,
4844 unsigned int); 4914 unsigned int);
@@ -4893,6 +4963,7 @@ parse_options_va (struct MHD_Daemon *daemon,
4893 } 4963 }
4894 } 4964 }
4895 break; 4965 break;
4966#endif
4896#ifdef HTTPS_SUPPORT 4967#ifdef HTTPS_SUPPORT
4897 case MHD_OPTION_HTTPS_MEM_KEY: 4968 case MHD_OPTION_HTTPS_MEM_KEY:
4898 pstr = va_arg (ap, 4969 pstr = va_arg (ap,
@@ -5071,10 +5142,12 @@ parse_options_va (struct MHD_Daemon *daemon,
5071 void *); 5142 void *);
5072#endif 5143#endif
5073 break; 5144 break;
5145#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5074 case MHD_OPTION_THREAD_STACK_SIZE: 5146 case MHD_OPTION_THREAD_STACK_SIZE:
5075 daemon->thread_stack_size = va_arg (ap, 5147 daemon->thread_stack_size = va_arg (ap,
5076 size_t); 5148 size_t);
5077 break; 5149 break;
5150#endif
5078#ifdef TCP_FASTOPEN 5151#ifdef TCP_FASTOPEN
5079 case MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE: 5152 case MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE:
5080 daemon->fastopen_queue_size = va_arg (ap, 5153 daemon->fastopen_queue_size = va_arg (ap,
@@ -5400,7 +5473,9 @@ MHD_start_daemon_va (unsigned int flags,
5400#endif 5473#endif
5401 const struct sockaddr *servaddr = NULL; 5474 const struct sockaddr *servaddr = NULL;
5402 socklen_t addrlen; 5475 socklen_t addrlen;
5476#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5403 unsigned int i; 5477 unsigned int i;
5478#endif
5404 enum MHD_FLAG eflags; /* same type as in MHD_Daemon */ 5479 enum MHD_FLAG eflags; /* same type as in MHD_Daemon */
5405 enum MHD_FLAG *pflags; 5480 enum MHD_FLAG *pflags;
5406 5481
@@ -5580,8 +5655,11 @@ MHD_start_daemon_va (unsigned int flags,
5580#endif /* HAVE_MESSAGES */ 5655#endif /* HAVE_MESSAGES */
5581#endif /* ! NDEBUG */ 5656#endif /* ! NDEBUG */
5582 5657
5583 if ( (0 != (*pflags & MHD_USE_ITC)) && 5658 if ( (0 != (*pflags & MHD_USE_ITC))
5584 (0 == daemon->worker_pool_size) ) 5659#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5660 && (0 == daemon->worker_pool_size)
5661#endif
5662 )
5585 { 5663 {
5586 if (! MHD_itc_init_ (daemon->itc)) 5664 if (! MHD_itc_init_ (daemon->itc))
5587 { 5665 {
@@ -5649,6 +5727,7 @@ MHD_start_daemon_va (unsigned int flags,
5649 } 5727 }
5650 } 5728 }
5651 5729
5730#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5652 if (! MHD_mutex_init_ (&daemon->nnc_lock)) 5731 if (! MHD_mutex_init_ (&daemon->nnc_lock))
5653 { 5732 {
5654#ifdef HAVE_MESSAGES 5733#ifdef HAVE_MESSAGES
@@ -5664,10 +5743,16 @@ MHD_start_daemon_va (unsigned int flags,
5664 return NULL; 5743 return NULL;
5665 } 5744 }
5666#endif 5745#endif
5746#endif
5667 5747
5748<<<<<<< HEAD
5668 /* Thread pooling currently works only with internal select thread mode */ 5749 /* Thread pooling currently works only with internal select thread mode */
5750=======
5751 /* Thread pooling currently works only with internal select thread model */
5752#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5753>>>>>>> add build option to compile MHD without threads
5669 if ( (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) && 5754 if ( (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) &&
5670 (daemon->worker_pool_size > 0) ) 5755 (daemon->worker_pool_size > 0) )
5671 { 5756 {
5672#ifdef HAVE_MESSAGES 5757#ifdef HAVE_MESSAGES
5673 MHD_DLOG (daemon, 5758 MHD_DLOG (daemon,
@@ -5675,7 +5760,7 @@ MHD_start_daemon_va (unsigned int flags,
5675#endif 5760#endif
5676 goto free_and_fail; 5761 goto free_and_fail;
5677 } 5762 }
5678 5763#endif
5679 if ( (MHD_INVALID_SOCKET == daemon->listen_fd) && 5764 if ( (MHD_INVALID_SOCKET == daemon->listen_fd) &&
5680 (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) ) 5765 (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) )
5681 { 5766 {
@@ -6000,8 +6085,11 @@ MHD_start_daemon_va (unsigned int flags,
6000 _("Failed to set nonblocking mode on listening socket: %s\n"), 6085 _("Failed to set nonblocking mode on listening socket: %s\n"),
6001 MHD_socket_last_strerr_()); 6086 MHD_socket_last_strerr_());
6002#endif 6087#endif
6003 if (0 != (*pflags & MHD_USE_EPOLL) || 6088 if (0 != (*pflags & MHD_USE_EPOLL)
6004 daemon->worker_pool_size > 0) 6089#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6090 || (daemon->worker_pool_size > 0)
6091#endif
6092 )
6005 { 6093 {
6006 /* Accept must be non-blocking. Multiple children may wake up 6094 /* Accept must be non-blocking. Multiple children may wake up
6007 * to handle a new connection, but only one will win the race. 6095 * to handle a new connection, but only one will win the race.
@@ -6026,8 +6114,11 @@ MHD_start_daemon_va (unsigned int flags,
6026 } 6114 }
6027 6115
6028#ifdef EPOLL_SUPPORT 6116#ifdef EPOLL_SUPPORT
6029 if ( (0 != (*pflags & MHD_USE_EPOLL)) && 6117 if ( (0 != (*pflags & MHD_USE_EPOLL))
6030 (0 == daemon->worker_pool_size) ) 6118#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6119 && (0 == daemon->worker_pool_size)
6120#endif
6121 )
6031 { 6122 {
6032 if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION)) 6123 if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION))
6033 { 6124 {
@@ -6042,6 +6133,7 @@ MHD_start_daemon_va (unsigned int flags,
6042 } 6133 }
6043#endif /* EPOLL_SUPPORT */ 6134#endif /* EPOLL_SUPPORT */
6044 6135
6136#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6045 if (! MHD_mutex_init_ (&daemon->per_ip_connection_mutex)) 6137 if (! MHD_mutex_init_ (&daemon->per_ip_connection_mutex))
6046 { 6138 {
6047#ifdef HAVE_MESSAGES 6139#ifdef HAVE_MESSAGES
@@ -6061,12 +6153,15 @@ MHD_start_daemon_va (unsigned int flags,
6061 MHD_DLOG (daemon, 6153 MHD_DLOG (daemon,
6062 _("MHD failed to initialize IP connection limit mutex\n")); 6154 _("MHD failed to initialize IP connection limit mutex\n"));
6063#endif 6155#endif
6156#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6064 MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex); 6157 MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
6158#endif
6065 if (MHD_INVALID_SOCKET != listen_fd) 6159 if (MHD_INVALID_SOCKET != listen_fd)
6066 MHD_socket_close_chk_ (listen_fd); 6160 MHD_socket_close_chk_ (listen_fd);
6067 goto free_and_fail; 6161 goto free_and_fail;
6068 } 6162 }
6069 } 6163 }
6164#endif
6070 6165
6071#ifdef HTTPS_SUPPORT 6166#ifdef HTTPS_SUPPORT
6072 /* initialize HTTPS daemon certificate aspects & send / recv functions */ 6167 /* initialize HTTPS daemon certificate aspects & send / recv functions */
@@ -6079,12 +6174,15 @@ MHD_start_daemon_va (unsigned int flags,
6079#endif 6174#endif
6080 if (MHD_INVALID_SOCKET != listen_fd) 6175 if (MHD_INVALID_SOCKET != listen_fd)
6081 MHD_socket_close_chk_ (listen_fd); 6176 MHD_socket_close_chk_ (listen_fd);
6177#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6082 if (0 == daemon->worker_pool_size) 6178 if (0 == daemon->worker_pool_size)
6083 MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex); 6179 MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
6084 MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); 6180 MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
6181#endif
6085 goto free_and_fail; 6182 goto free_and_fail;
6086 } 6183 }
6087#endif /* HTTPS_SUPPORT */ 6184#endif /* HTTPS_SUPPORT */
6185#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6088 if ( (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) && 6186 if ( (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) &&
6089 (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) ) 6187 (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) )
6090 { 6188 {
@@ -6208,6 +6306,7 @@ MHD_start_daemon_va (unsigned int flags,
6208 } 6306 }
6209 } 6307 }
6210 } 6308 }
6309#endif
6211#ifdef HTTPS_SUPPORT 6310#ifdef HTTPS_SUPPORT
6212 /* API promises to never use the password after initialization, 6311 /* API promises to never use the password after initialization,
6213 so we additionally NULL it here to not deref a dangling pointer. */ 6312 so we additionally NULL it here to not deref a dangling pointer. */
@@ -6216,6 +6315,7 @@ MHD_start_daemon_va (unsigned int flags,
6216 6315
6217 return daemon; 6316 return daemon;
6218 6317
6318#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6219thread_failed: 6319thread_failed:
6220 /* If no worker threads created, then shut down normally. Calling 6320 /* If no worker threads created, then shut down normally. Calling
6221 MHD_stop_daemon (as we do below) doesn't work here since it 6321 MHD_stop_daemon (as we do below) doesn't work here since it
@@ -6238,6 +6338,7 @@ thread_failed:
6238 daemon->worker_pool_size = i; 6338 daemon->worker_pool_size = i;
6239 MHD_stop_daemon (daemon); 6339 MHD_stop_daemon (daemon);
6240 return NULL; 6340 return NULL;
6341#endif
6241 6342
6242 free_and_fail: 6343 free_and_fail:
6243 /* clean up basic memory state in 'daemon' and return NULL to 6344 /* clean up basic memory state in 'daemon' and return NULL to
@@ -6263,8 +6364,10 @@ thread_failed:
6263#endif /* EPOLL_SUPPORT */ 6364#endif /* EPOLL_SUPPORT */
6264#ifdef DAUTH_SUPPORT 6365#ifdef DAUTH_SUPPORT
6265 free (daemon->nnc); 6366 free (daemon->nnc);
6367#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6266 MHD_mutex_destroy_chk_ (&daemon->nnc_lock); 6368 MHD_mutex_destroy_chk_ (&daemon->nnc_lock);
6267#endif 6369#endif
6370#endif
6268#ifdef HTTPS_SUPPORT 6371#ifdef HTTPS_SUPPORT
6269 if (0 != (*pflags & MHD_USE_TLS)) 6372 if (0 != (*pflags & MHD_USE_TLS))
6270 gnutls_priority_deinit (daemon->priority_cache); 6373 gnutls_priority_deinit (daemon->priority_cache);
@@ -6297,7 +6400,9 @@ close_all_connections (struct MHD_Daemon *daemon)
6297 struct MHD_UpgradeResponseHandle *urhn; 6400 struct MHD_UpgradeResponseHandle *urhn;
6298 const bool used_tls = (0 != (daemon->options & MHD_USE_TLS)); 6401 const bool used_tls = (0 != (daemon->options & MHD_USE_TLS));
6299 6402
6403#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6300 mhd_assert (NULL == daemon->worker_pool); 6404 mhd_assert (NULL == daemon->worker_pool);
6405#endif
6301 mhd_assert (daemon->shutdown); 6406 mhd_assert (daemon->shutdown);
6302 /* give upgraded HTTPS connections a chance to finish */ 6407 /* give upgraded HTTPS connections a chance to finish */
6303 /* 'daemon->urh_head' is not used in thread-per-connection mode. */ 6408 /* 'daemon->urh_head' is not used in thread-per-connection mode. */
@@ -6325,7 +6430,9 @@ close_all_connections (struct MHD_Daemon *daemon)
6325 } 6430 }
6326 /* first, make sure all threads are aware of shutdown; need to 6431 /* first, make sure all threads are aware of shutdown; need to
6327 traverse DLLs in peace... */ 6432 traverse DLLs in peace... */
6433#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6328 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); 6434 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
6435#endif
6329#ifdef UPGRADE_SUPPORT 6436#ifdef UPGRADE_SUPPORT
6330 if (upg_allowed) 6437 if (upg_allowed)
6331 { 6438 {
@@ -6379,6 +6486,7 @@ close_all_connections (struct MHD_Daemon *daemon)
6379#endif 6486#endif
6380 } 6487 }
6381 6488
6489#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6382 /* now, collect per-connection threads */ 6490 /* now, collect per-connection threads */
6383 if (used_thr_p_c) 6491 if (used_thr_p_c)
6384 { 6492 {
@@ -6401,6 +6509,7 @@ close_all_connections (struct MHD_Daemon *daemon)
6401 } 6509 }
6402 } 6510 }
6403 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); 6511 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
6512#endif
6404 6513
6405#ifdef UPGRADE_SUPPORT 6514#ifdef UPGRADE_SUPPORT
6406 /* Finished threads with "upgraded" connections need to be moved 6515 /* Finished threads with "upgraded" connections need to be moved
@@ -6417,9 +6526,11 @@ close_all_connections (struct MHD_Daemon *daemon)
6417 /* now that we're alone, move everyone to cleanup */ 6526 /* now that we're alone, move everyone to cleanup */
6418 while (NULL != (pos = daemon->connections_tail)) 6527 while (NULL != (pos = daemon->connections_tail))
6419 { 6528 {
6529#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6420 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 6530 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
6421 (! pos->thread_joined) ) 6531 (! pos->thread_joined) )
6422 MHD_PANIC (_("Failed to join a thread\n")); 6532 MHD_PANIC (_("Failed to join a thread\n"));
6533#endif
6423 close_connection (pos); 6534 close_connection (pos);
6424 } 6535 }
6425 MHD_cleanup_connections (daemon); 6536 MHD_cleanup_connections (daemon);
@@ -6436,8 +6547,10 @@ void
6436MHD_stop_daemon (struct MHD_Daemon *daemon) 6547MHD_stop_daemon (struct MHD_Daemon *daemon)
6437{ 6548{
6438 MHD_socket fd; 6549 MHD_socket fd;
6550#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6439 unsigned int i; 6551 unsigned int i;
6440 6552#endif
6553
6441 if (NULL == daemon) 6554 if (NULL == daemon)
6442 return; 6555 return;
6443 6556
@@ -6447,6 +6560,7 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
6447 else 6560 else
6448 fd = daemon->listen_fd; 6561 fd = daemon->listen_fd;
6449 6562
6563#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6450 if (NULL != daemon->worker_pool) 6564 if (NULL != daemon->worker_pool)
6451 { /* Master daemon with worker pool. */ 6565 { /* Master daemon with worker pool. */
6452 mhd_assert (1 < daemon->worker_pool_size); 6566 mhd_assert (1 < daemon->worker_pool_size);
@@ -6486,7 +6600,9 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
6486#endif /* EPOLL_SUPPORT */ 6600#endif /* EPOLL_SUPPORT */
6487 } 6601 }
6488 else 6602 else
6603#endif
6489 { /* Worker daemon or single daemon. */ 6604 { /* Worker daemon or single daemon. */
6605#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6490 if (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) 6606 if (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))
6491 { /* Worker daemon or single daemon with internal thread(s). */ 6607 { /* Worker daemon or single daemon with internal thread(s). */
6492 mhd_assert (0 == daemon->worker_pool_size); 6608 mhd_assert (0 == daemon->worker_pool_size);
@@ -6518,6 +6634,7 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
6518 /* close_all_connections() was called in daemon thread. */ 6634 /* close_all_connections() was called in daemon thread. */
6519 } 6635 }
6520 else 6636 else
6637#endif
6521 { 6638 {
6522 /* No internal threads are used for polling sockets. */ 6639 /* No internal threads are used for polling sockets. */
6523 close_all_connections (daemon); 6640 close_all_connections (daemon);
@@ -6536,7 +6653,9 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
6536#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 6653#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
6537#endif /* EPOLL_SUPPORT */ 6654#endif /* EPOLL_SUPPORT */
6538 6655
6656#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6539 MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex); 6657 MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
6658#endif
6540 } 6659 }
6541 6660
6542 if (NULL == daemon->master) 6661 if (NULL == daemon->master)
@@ -6565,10 +6684,13 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
6565 6684
6566#ifdef DAUTH_SUPPORT 6685#ifdef DAUTH_SUPPORT
6567 free (daemon->nnc); 6686 free (daemon->nnc);
6687#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6568 MHD_mutex_destroy_chk_ (&daemon->nnc_lock); 6688 MHD_mutex_destroy_chk_ (&daemon->nnc_lock);
6569#endif 6689#endif
6690#endif
6691#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6570 MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); 6692 MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
6571 6693#endif
6572 free (daemon); 6694 free (daemon);
6573 } 6695 }
6574} 6696}
@@ -6611,6 +6733,7 @@ MHD_get_daemon_info (struct MHD_Daemon *daemon,
6611 * at the same time. */ 6733 * at the same time. */
6612 MHD_cleanup_connections (daemon); 6734 MHD_cleanup_connections (daemon);
6613 } 6735 }
6736#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6614 else if (daemon->worker_pool) 6737 else if (daemon->worker_pool)
6615 { 6738 {
6616 unsigned int i; 6739 unsigned int i;
@@ -6622,6 +6745,7 @@ MHD_get_daemon_info (struct MHD_Daemon *daemon,
6622 daemon->connections += daemon->worker_pool[i].connections; 6745 daemon->connections += daemon->worker_pool[i].connections;
6623 } 6746 }
6624 } 6747 }
6748#endif
6625 return (const union MHD_DaemonInfo *) &daemon->connections; 6749 return (const union MHD_DaemonInfo *) &daemon->connections;
6626 case MHD_DAEMON_INFO_FLAGS: 6750 case MHD_DAEMON_INFO_FLAGS:
6627 return (const union MHD_DaemonInfo *) &daemon->options; 6751 return (const union MHD_DaemonInfo *) &daemon->options;
@@ -6833,6 +6957,12 @@ MHD_is_feature_supported(enum MHD_FEATURE feature)
6833#else 6957#else
6834 return MHD_NO; 6958 return MHD_NO;
6835#endif 6959#endif
6960 case MHD_FEATURE_THREADS:
6961#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6962 return MHD_YES;
6963#else
6964 return MHD_NO;
6965#endif
6836 6966
6837 } 6967 }
6838 return MHD_NO; 6968 return MHD_NO;
diff --git a/src/microhttpd/digestauth.c b/src/microhttpd/digestauth.c
index 33352bc7..80cba836 100644
--- a/src/microhttpd/digestauth.c
+++ b/src/microhttpd/digestauth.c
@@ -448,7 +448,9 @@ check_nonce_nc (struct MHD_Connection *connection,
448 * then only increase the nonce counter by one. 448 * then only increase the nonce counter by one.
449 */ 449 */
450 nn = &daemon->nnc[off]; 450 nn = &daemon->nnc[off];
451#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
451 MHD_mutex_lock_chk_ (&daemon->nnc_lock); 452 MHD_mutex_lock_chk_ (&daemon->nnc_lock);
453#endif
452 if (0 == nc) 454 if (0 == nc)
453 { 455 {
454 /* Fresh nonce, reinitialize array */ 456 /* Fresh nonce, reinitialize array */
@@ -457,7 +459,9 @@ check_nonce_nc (struct MHD_Connection *connection,
457 noncelen); 459 noncelen);
458 nn->nc = 0; 460 nn->nc = 0;
459 nn->nmask = 0; 461 nn->nmask = 0;
462#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
460 MHD_mutex_unlock_chk_ (&daemon->nnc_lock); 463 MHD_mutex_unlock_chk_ (&daemon->nnc_lock);
464#endif
461 return MHD_YES; 465 return MHD_YES;
462 } 466 }
463 /* Note that we use 64 here, as we do not store the 467 /* Note that we use 64 here, as we do not store the
@@ -469,7 +473,9 @@ check_nonce_nc (struct MHD_Connection *connection,
469 { 473 {
470 /* Out-of-order nonce, but within 64-bit bitmask, set bit */ 474 /* Out-of-order nonce, but within 64-bit bitmask, set bit */
471 nn->nmask |= (1LLU << (nn->nc - nc - 1)); 475 nn->nmask |= (1LLU << (nn->nc - nc - 1));
476#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
472 MHD_mutex_unlock_chk_ (&daemon->nnc_lock); 477 MHD_mutex_unlock_chk_ (&daemon->nnc_lock);
478#endif
473 return MHD_YES; 479 return MHD_YES;
474 } 480 }
475 481
@@ -478,7 +484,9 @@ check_nonce_nc (struct MHD_Connection *connection,
478 nonce)) ) 484 nonce)) )
479 { 485 {
480 /* Nonce does not match, fail */ 486 /* Nonce does not match, fail */
487#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
481 MHD_mutex_unlock_chk_ (&daemon->nnc_lock); 488 MHD_mutex_unlock_chk_ (&daemon->nnc_lock);
489#endif
482#ifdef HAVE_MESSAGES 490#ifdef HAVE_MESSAGES
483 MHD_DLOG (daemon, 491 MHD_DLOG (daemon,
484 _("Stale nonce received. If this happens a lot, you should probably increase the size of the nonce array.\n")); 492 _("Stale nonce received. If this happens a lot, you should probably increase the size of the nonce array.\n"));
@@ -491,7 +499,9 @@ check_nonce_nc (struct MHD_Connection *connection,
491 else 499 else
492 nn->nmask = 0; /* big jump, unset all bits in the mask */ 500 nn->nmask = 0; /* big jump, unset all bits in the mask */
493 nn->nc = nc; 501 nn->nc = nc;
502#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
494 MHD_mutex_unlock_chk_ (&daemon->nnc_lock); 503 MHD_mutex_unlock_chk_ (&daemon->nnc_lock);
504#endif
495 return MHD_YES; 505 return MHD_YES;
496} 506}
497 507
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index 4ae577de..aa6af5e8 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -65,8 +65,10 @@
65#define MHD_PANIC(msg) do { mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL); BUILTIN_NOT_REACHED; } while (0) 65#define MHD_PANIC(msg) do { mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL); BUILTIN_NOT_REACHED; } while (0)
66#endif 66#endif
67 67
68#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
68#include "mhd_threads.h" 69#include "mhd_threads.h"
69#include "mhd_locks.h" 70#include "mhd_locks.h"
71#endif
70#include "mhd_sockets.h" 72#include "mhd_sockets.h"
71#include "mhd_itc_types.h" 73#include "mhd_itc_types.h"
72 74
@@ -333,11 +335,13 @@ struct MHD_Response
333 void *upgrade_handler_cls; 335 void *upgrade_handler_cls;
334#endif /* UPGRADE_SUPPORT */ 336#endif /* UPGRADE_SUPPORT */
335 337
338#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
336 /** 339 /**
337 * Mutex to synchronize access to @e data, @e size and 340 * Mutex to synchronize access to @e data, @e size and
338 * @e reference_count. 341 * @e reference_count.
339 */ 342 */
340 MHD_mutex_ mutex; 343 MHD_mutex_ mutex;
344#endif
341 345
342 /** 346 /**
343 * Set to #MHD_SIZE_UNKNOWN if size is not known. 347 * Set to #MHD_SIZE_UNKNOWN if size is not known.
@@ -746,11 +750,13 @@ struct MHD_Connection
746 */ 750 */
747 struct sockaddr *addr; 751 struct sockaddr *addr;
748 752
753#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
749 /** 754 /**
750 * Thread handle for this connection (if we are using 755 * Thread handle for this connection (if we are using
751 * one thread per connection). 756 * one thread per connection).
752 */ 757 */
753 MHD_thread_handle_ID_ pid; 758 MHD_thread_handle_ID_ pid;
759#endif
754 760
755 /** 761 /**
756 * Size of @e read_buffer (in bytes). This value indicates 762 * Size of @e read_buffer (in bytes). This value indicates
@@ -864,10 +870,12 @@ struct MHD_Connection
864 */ 870 */
865 bool read_closed; 871 bool read_closed;
866 872
873#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
867 /** 874 /**
868 * Set to `true` if the thread has been joined. 875 * Set to `true` if the thread has been joined.
869 */ 876 */
870 bool thread_joined; 877 bool thread_joined;
878#endif
871 879
872 /** 880 /**
873 * Are we currently inside the "idle" handler (to avoid recursively 881 * Are we currently inside the "idle" handler (to avoid recursively
@@ -1404,10 +1412,12 @@ struct MHD_Daemon
1404 */ 1412 */
1405 struct MHD_Daemon *master; 1413 struct MHD_Daemon *master;
1406 1414
1415#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1407 /** 1416 /**
1408 * Worker daemons (one per thread) 1417 * Worker daemons (one per thread)
1409 */ 1418 */
1410 struct MHD_Daemon *worker_pool; 1419 struct MHD_Daemon *worker_pool;
1420#endif
1411 1421
1412 /** 1422 /**
1413 * Table storing number of connections per IP 1423 * Table storing number of connections per IP
@@ -1424,6 +1434,7 @@ struct MHD_Daemon
1424 */ 1434 */
1425 size_t pool_increment; 1435 size_t pool_increment;
1426 1436
1437#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1427 /** 1438 /**
1428 * Size of threads created by MHD. 1439 * Size of threads created by MHD.
1429 */ 1440 */
@@ -1449,6 +1460,7 @@ struct MHD_Daemon
1449 * "manual_timeout" DLLs. 1460 * "manual_timeout" DLLs.
1450 */ 1461 */
1451 MHD_mutex_ cleanup_connection_mutex; 1462 MHD_mutex_ cleanup_connection_mutex;
1463#endif
1452 1464
1453 /** 1465 /**
1454 * Listen socket. 1466 * Listen socket.
@@ -1495,7 +1507,8 @@ struct MHD_Daemon
1495#endif 1507#endif
1496 1508
1497 /** 1509 /**
1498 * Inter-thread communication channel. 1510 * Inter-thread communication channel (also used to unblock
1511 * select() in non-threaded code).
1499 */ 1512 */
1500 struct MHD_itc_ itc; 1513 struct MHD_itc_ itc;
1501 1514
@@ -1678,10 +1691,12 @@ struct MHD_Daemon
1678 */ 1691 */
1679 struct MHD_NonceNc *nnc; 1692 struct MHD_NonceNc *nnc;
1680 1693
1694#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1681 /** 1695 /**
1682 * A rw-lock for synchronizing access to @e nnc. 1696 * A rw-lock for synchronizing access to @e nnc.
1683 */ 1697 */
1684 MHD_mutex_ nnc_lock; 1698 MHD_mutex_ nnc_lock;
1699#endif
1685 1700
1686 /** 1701 /**
1687 * Size of `digest_auth_random. 1702 * Size of `digest_auth_random.
diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c
index 29edef4f..263f8303 100644
--- a/src/microhttpd/response.c
+++ b/src/microhttpd/response.c
@@ -350,11 +350,13 @@ MHD_create_response_from_callback (uint64_t size,
350 response->fd = -1; 350 response->fd = -1;
351 response->data = (void *) &response[1]; 351 response->data = (void *) &response[1];
352 response->data_buffer_size = block_size; 352 response->data_buffer_size = block_size;
353#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
353 if (! MHD_mutex_init_ (&response->mutex)) 354 if (! MHD_mutex_init_ (&response->mutex))
354 { 355 {
355 free (response); 356 free (response);
356 return NULL; 357 return NULL;
357 } 358 }
359#endif
358 response->crc = crc; 360 response->crc = crc;
359 response->crfc = crfc; 361 response->crfc = crfc;
360 response->crc_cls = crc_cls; 362 response->crc_cls = crc_cls;
@@ -649,16 +651,20 @@ MHD_create_response_from_data (size_t size,
649 if (NULL == (response = MHD_calloc_ (1, sizeof (struct MHD_Response)))) 651 if (NULL == (response = MHD_calloc_ (1, sizeof (struct MHD_Response))))
650 return NULL; 652 return NULL;
651 response->fd = -1; 653 response->fd = -1;
654#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
652 if (! MHD_mutex_init_ (&response->mutex)) 655 if (! MHD_mutex_init_ (&response->mutex))
653 { 656 {
654 free (response); 657 free (response);
655 return NULL; 658 return NULL;
656 } 659 }
660#endif
657 if ((must_copy) && (size > 0)) 661 if ((must_copy) && (size > 0))
658 { 662 {
659 if (NULL == (tmp = malloc (size))) 663 if (NULL == (tmp = malloc (size)))
660 { 664 {
665#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
661 MHD_mutex_destroy_chk_ (&response->mutex); 666 MHD_mutex_destroy_chk_ (&response->mutex);
667#endif
662 free (response); 668 free (response);
663 return NULL; 669 return NULL;
664 } 670 }
@@ -1084,11 +1090,13 @@ MHD_create_response_for_upgrade (MHD_UpgradeHandler upgrade_handler,
1084 response = MHD_calloc_ (1, sizeof (struct MHD_Response)); 1090 response = MHD_calloc_ (1, sizeof (struct MHD_Response));
1085 if (NULL == response) 1091 if (NULL == response)
1086 return NULL; 1092 return NULL;
1093#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1087 if (! MHD_mutex_init_ (&response->mutex)) 1094 if (! MHD_mutex_init_ (&response->mutex))
1088 { 1095 {
1089 free (response); 1096 free (response);
1090 return NULL; 1097 return NULL;
1091 } 1098 }
1099#endif
1092 response->upgrade_handler = upgrade_handler; 1100 response->upgrade_handler = upgrade_handler;
1093 response->upgrade_handler_cls = upgrade_handler_cls; 1101 response->upgrade_handler_cls = upgrade_handler_cls;
1094 response->total_size = MHD_SIZE_UNKNOWN; 1102 response->total_size = MHD_SIZE_UNKNOWN;
@@ -1122,14 +1130,20 @@ MHD_destroy_response (struct MHD_Response *response)
1122 1130
1123 if (NULL == response) 1131 if (NULL == response)
1124 return; 1132 return;
1133#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1125 MHD_mutex_lock_chk_ (&response->mutex); 1134 MHD_mutex_lock_chk_ (&response->mutex);
1135#endif
1126 if (0 != --(response->reference_count)) 1136 if (0 != --(response->reference_count))
1127 { 1137 {
1138#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1128 MHD_mutex_unlock_chk_ (&response->mutex); 1139 MHD_mutex_unlock_chk_ (&response->mutex);
1140#endif
1129 return; 1141 return;
1130 } 1142 }
1143#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1131 MHD_mutex_unlock_chk_ (&response->mutex); 1144 MHD_mutex_unlock_chk_ (&response->mutex);
1132 MHD_mutex_destroy_chk_ (&response->mutex); 1145 MHD_mutex_destroy_chk_ (&response->mutex);
1146#endif
1133 if (NULL != response->crfc) 1147 if (NULL != response->crfc)
1134 response->crfc (response->crc_cls); 1148 response->crfc (response->crc_cls);
1135 while (NULL != response->first_header) 1149 while (NULL != response->first_header)
@@ -1152,9 +1166,13 @@ MHD_destroy_response (struct MHD_Response *response)
1152void 1166void
1153MHD_increment_response_rc (struct MHD_Response *response) 1167MHD_increment_response_rc (struct MHD_Response *response)
1154{ 1168{
1169#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1155 MHD_mutex_lock_chk_ (&response->mutex); 1170 MHD_mutex_lock_chk_ (&response->mutex);
1171#endif
1156 (response->reference_count)++; 1172 (response->reference_count)++;
1173#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1157 MHD_mutex_unlock_chk_ (&response->mutex); 1174 MHD_mutex_unlock_chk_ (&response->mutex);
1175#endif
1158} 1176}
1159 1177
1160 1178
diff --git a/src/microhttpd/test_start_stop.c b/src/microhttpd/test_start_stop.c
index d2e160b0..d27291b8 100644
--- a/src/microhttpd/test_start_stop.c
+++ b/src/microhttpd/test_start_stop.c
@@ -52,6 +52,7 @@ ahc_echo (void *cls,
52} 52}
53 53
54 54
55#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
55static int 56static int
56testInternalGet (int poll_flag) 57testInternalGet (int poll_flag)
57{ 58{
@@ -78,6 +79,7 @@ testMultithreadedGet (int poll_flag)
78 return 0; 79 return 0;
79} 80}
80 81
82
81static int 83static int
82testMultithreadedPoolGet (int poll_flag) 84testMultithreadedPoolGet (int poll_flag)
83{ 85{
@@ -91,6 +93,8 @@ testMultithreadedPoolGet (int poll_flag)
91 MHD_stop_daemon (d); 93 MHD_stop_daemon (d);
92 return 0; 94 return 0;
93} 95}
96#endif
97
94 98
95static int 99static int
96testExternalGet () 100testExternalGet ()
@@ -98,8 +102,10 @@ testExternalGet ()
98 struct MHD_Daemon *d; 102 struct MHD_Daemon *d;
99 103
100 d = MHD_start_daemon (MHD_USE_ERROR_LOG, 104 d = MHD_start_daemon (MHD_USE_ERROR_LOG,
101 0, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END); 105 0, NULL, NULL,
102 if (d == NULL) 106 &ahc_echo, "GET",
107 MHD_OPTION_END);
108 if (NULL == d)
103 return 8; 109 return 8;
104 MHD_stop_daemon (d); 110 MHD_stop_daemon (d);
105 return 0; 111 return 0;
@@ -107,15 +113,20 @@ testExternalGet ()
107 113
108 114
109int 115int
110main (int argc, char *const *argv) 116main (int argc,
117 char *const *argv)
111{ 118{
112 unsigned int errorCount = 0; 119 unsigned int errorCount = 0;
113 (void)argc; (void)argv; /* Unused. Silent compiler warning. */ 120 (void) argc;
121 (void) argv; /* Unused. Silence compiler warning. */
114 122
123#if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
115 errorCount += testInternalGet (0); 124 errorCount += testInternalGet (0);
116 errorCount += testMultithreadedGet (0); 125 errorCount += testMultithreadedGet (0);
117 errorCount += testMultithreadedPoolGet (0); 126 errorCount += testMultithreadedPoolGet (0);
127#endif
118 errorCount += testExternalGet (); 128 errorCount += testExternalGet ();
129#if defined (MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
119 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_POLL)) 130 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_POLL))
120 { 131 {
121 errorCount += testInternalGet(MHD_USE_POLL); 132 errorCount += testInternalGet(MHD_USE_POLL);
@@ -127,7 +138,10 @@ main (int argc, char *const *argv)
127 errorCount += testInternalGet(MHD_USE_EPOLL); 138 errorCount += testInternalGet(MHD_USE_EPOLL);
128 errorCount += testMultithreadedPoolGet(MHD_USE_EPOLL); 139 errorCount += testMultithreadedPoolGet(MHD_USE_EPOLL);
129 } 140 }
130 if (errorCount != 0) 141#endif
131 fprintf (stderr, "Error (code: %u)\n", errorCount); 142 if (0 != errorCount)
143 fprintf (stderr,
144 "Error (code: %u)\n",
145 errorCount);
132 return errorCount != 0; /* 0 == pass */ 146 return errorCount != 0; /* 0 == pass */
133} 147}
diff --git a/src/testcurl/Makefile.am b/src/testcurl/Makefile.am
index 796ea9e2..3e703772 100644
--- a/src/testcurl/Makefile.am
+++ b/src/testcurl/Makefile.am
@@ -16,11 +16,39 @@ AM_CPPFLAGS = \
16-I$(top_srcdir)/src/include \ 16-I$(top_srcdir)/src/include \
17$(LIBCURL_CPPFLAGS) 17$(LIBCURL_CPPFLAGS)
18 18
19
20THREAD_ONLY_TESTS = \
21 test_urlparse \
22 test_long_header \
23 test_long_header11 \
24 test_iplimit11 \
25 test_termination \
26 test_timeout
27
28
29
30if HAVE_POSIX_THREADS
31THREAD_ONLY_TESTS += \
32 test_quiesce \
33 test_concurrent_stop \
34 perf_get_concurrent
35
36if HAVE_CURL_BINARY
37THREAD_ONLY_TESTS += \
38 test_quiesce_stream
39endif
40endif
41
42if ENABLE_DAUTH
43 THREAD_ONLY_TESTS += \
44 test_digestauth \
45 test_digestauth_with_arguments
46endif
47
19if HAVE_CURL 48if HAVE_CURL
20check_PROGRAMS = \ 49check_PROGRAMS = \
21 test_get \ 50 test_get \
22 test_get_sendfile \ 51 test_get_sendfile \
23 test_urlparse \
24 test_delete \ 52 test_delete \
25 test_put \ 53 test_put \
26 test_process_headers \ 54 test_process_headers \
@@ -32,33 +60,11 @@ check_PROGRAMS = \
32 test_put11 \ 60 test_put11 \
33 test_large_put11 \ 61 test_large_put11 \
34 test_large_put_inc11 \ 62 test_large_put_inc11 \
35 test_long_header \
36 test_long_header11 \
37 test_get_chunked \ 63 test_get_chunked \
38 test_put_chunked \ 64 test_put_chunked \
39 test_iplimit11 \
40 test_termination \
41 test_timeout \
42 test_callback \ 65 test_callback \
43 perf_get 66 perf_get
44 67
45if HAVE_FORK_WAITPID
46if HAVE_CURL_BINARY
47check_PROGRAMS += test_get_response_cleanup
48endif
49endif
50
51if HAVE_POSIX_THREADS
52check_PROGRAMS += \
53 test_quiesce \
54 test_concurrent_stop \
55 perf_get_concurrent
56
57if HAVE_CURL_BINARY
58check_PROGRAMS += test_quiesce_stream
59endif
60endif
61
62if HAVE_POSTPROCESSOR 68if HAVE_POSTPROCESSOR
63 check_PROGRAMS += \ 69 check_PROGRAMS += \
64 test_post \ 70 test_post \
@@ -69,9 +75,19 @@ if HAVE_POSTPROCESSOR
69 test_post_loop11 75 test_post_loop11
70endif 76endif
71 77
72if ENABLE_DAUTH 78if HAVE_FORK_WAITPID
73 check_PROGRAMS += \ 79if HAVE_CURL_BINARY
74 test_digestauth test_digestauth_with_arguments 80check_PROGRAMS += test_get_response_cleanup
81endif
82endif
83
84if USE_POSIX_THREADS
85check_PROGRAMS +=
86 $(THREAD_ONLY_TESTS)
87endif
88if USE_W32_THREADS
89check_PROGRAMS +=
90 $(THREAD_ONLY_TESTS)
75endif 91endif
76 92
77TESTS = $(check_PROGRAMS) 93TESTS = $(check_PROGRAMS)
diff --git a/src/testcurl/https/Makefile.am b/src/testcurl/https/Makefile.am
index 239ce2ca..7454ab06 100644
--- a/src/testcurl/https/Makefile.am
+++ b/src/testcurl/https/Makefile.am
@@ -10,8 +10,9 @@ if HAVE_GNUTLS_SNI
10endif 10endif
11 11
12if HAVE_POSIX_THREADS 12if HAVE_POSIX_THREADS
13 HTTPS_PARALLEL_TESTS = test_https_get_parallel \ 13 HTTPS_PARALLEL_TESTS = \
14 test_https_get_parallel_threads 14 test_https_get_parallel \
15 test_https_get_parallel_threads
15endif 16endif
16 17
17CPU_COUNT_DEF = -DCPU_COUNT=$(CPU_COUNT) 18CPU_COUNT_DEF = -DCPU_COUNT=$(CPU_COUNT)
@@ -22,32 +23,36 @@ AM_CPPFLAGS = \
22 -I$(top_srcdir)/src/platform \ 23 -I$(top_srcdir)/src/platform \
23 $(LIBCURL_CPPFLAGS) $(MHD_TLS_LIB_CPPFLAGS) 24 $(LIBCURL_CPPFLAGS) $(MHD_TLS_LIB_CPPFLAGS)
24 25
25check_PROGRAMS = \ 26THREAD_ONLY_TESTS = \
26 test_tls_options \ 27 test_tls_options \
27 test_tls_authentication \ 28 test_tls_authentication \
28 test_https_multi_daemon \
29 test_https_get \
30 $(TEST_HTTPS_SNI) \
31 test_https_get_select \
32 $(HTTPS_PARALLEL_TESTS) \ 29 $(HTTPS_PARALLEL_TESTS) \
30 $(TEST_HTTPS_SNI) \
33 test_https_session_info \ 31 test_https_session_info \
34 test_https_time_out \ 32 test_https_time_out \
33 test_https_multi_daemon \
34 test_https_get \
35 test_empty_response 35 test_empty_response
36 36
37EXTRA_DIST = cert.pem key.pem \ 37check_PROGRAMS = \
38 host1.crt host1.key host2.crt host2.key 38 test_https_get_select
39
40if USE_POSIX_THREADS
41check_PROGRAMS +=
42 $(THREAD_ONLY_TESTS)
43endif
44if USE_W32_THREADS
45check_PROGRAMS +=
46 $(THREAD_ONLY_TESTS)
47endif
48
49EXTRA_DIST = \
50 cert.pem key.pem \
51 host1.crt host1.key \
52 host2.crt host2.key
39 53
40TESTS = \ 54TESTS = \
41 test_tls_options \ 55 $(check_PROGRAMS)
42 test_https_multi_daemon \
43 test_https_get \
44 $(TEST_HTTPS_SNI) \
45 test_https_get_select \
46 $(HTTPS_PARALLEL_TESTS) \
47 test_https_session_info \
48 test_https_time_out \
49 test_tls_authentication \
50 test_empty_response
51 56
52 57
53test_https_time_out_SOURCES = \ 58test_https_time_out_SOURCES = \
diff --git a/src/testcurl/https/tls_test_common.c b/src/testcurl/https/tls_test_common.c
index a3a7df24..3641f098 100644
--- a/src/testcurl/https/tls_test_common.c
+++ b/src/testcurl/https/tls_test_common.c
@@ -526,7 +526,9 @@ test_wrap (const char *test_name, int
526 return ret; 526 return ret;
527} 527}
528 528
529int testsuite_curl_global_init (void) 529
530int
531testsuite_curl_global_init (void)
530{ 532{
531 CURLcode res; 533 CURLcode res;
532#if LIBCURL_VERSION_NUM >= 0x073800 534#if LIBCURL_VERSION_NUM >= 0x073800
diff --git a/src/testcurl/perf_get.c b/src/testcurl/perf_get.c
index ac6a23f3..b5d754a8 100644
--- a/src/testcurl/perf_get.c
+++ b/src/testcurl/perf_get.c
@@ -589,22 +589,25 @@ main (int argc, char *const *argv)
589 "/hello_world", 589 "/hello_world",
590 MHD_RESPMEM_MUST_COPY); 590 MHD_RESPMEM_MUST_COPY);
591 errorCount += testExternalGet (port++); 591 errorCount += testExternalGet (port++);
592 errorCount += testInternalGet (port++, MHD_USE_AUTO); 592 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_THREADS))
593 errorCount += testMultithreadedGet (port++, MHD_USE_AUTO);
594 errorCount += testMultithreadedPoolGet (port++, MHD_USE_AUTO);
595 errorCount += testInternalGet (port++, 0);
596 errorCount += testMultithreadedGet (port++, 0);
597 errorCount += testMultithreadedPoolGet (port++, 0);
598 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_POLL))
599 { 593 {
600 errorCount += testInternalGet(port++, MHD_USE_POLL); 594 errorCount += testInternalGet (port++, MHD_USE_AUTO);
601 errorCount += testMultithreadedGet(port++, MHD_USE_POLL); 595 errorCount += testMultithreadedGet (port++, MHD_USE_AUTO);
602 errorCount += testMultithreadedPoolGet(port++, MHD_USE_POLL); 596 errorCount += testMultithreadedPoolGet (port++, MHD_USE_AUTO);
603 } 597 errorCount += testInternalGet (port++, 0);
604 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_EPOLL)) 598 errorCount += testMultithreadedGet (port++, 0);
605 { 599 errorCount += testMultithreadedPoolGet (port++, 0);
606 errorCount += testInternalGet(port++, MHD_USE_EPOLL); 600 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_POLL))
607 errorCount += testMultithreadedPoolGet(port++, MHD_USE_EPOLL); 601 {
602 errorCount += testInternalGet(port++, MHD_USE_POLL);
603 errorCount += testMultithreadedGet(port++, MHD_USE_POLL);
604 errorCount += testMultithreadedPoolGet(port++, MHD_USE_POLL);
605 }
606 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_EPOLL))
607 {
608 errorCount += testInternalGet(port++, MHD_USE_EPOLL);
609 errorCount += testMultithreadedPoolGet(port++, MHD_USE_EPOLL);
610 }
608 } 611 }
609 MHD_destroy_response (response); 612 MHD_destroy_response (response);
610 if (errorCount != 0) 613 if (errorCount != 0)
diff --git a/src/testcurl/test_delete.c b/src/testcurl/test_delete.c
index 70f0f509..35f7f6a2 100644
--- a/src/testcurl/test_delete.c
+++ b/src/testcurl/test_delete.c
@@ -512,9 +512,12 @@ main (int argc, char *const *argv)
512 (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0; 512 (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
513 if (0 != curl_global_init (CURL_GLOBAL_WIN32)) 513 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
514 return 2; 514 return 2;
515 errorCount += testInternalDelete (); 515 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_THREADS))
516 errorCount += testMultithreadedDelete (); 516 {
517 errorCount += testMultithreadedPoolDelete (); 517 errorCount += testInternalDelete ();
518 errorCount += testMultithreadedDelete ();
519 errorCount += testMultithreadedPoolDelete ();
520 }
518 errorCount += testExternalDelete (); 521 errorCount += testExternalDelete ();
519 if (errorCount != 0) 522 if (errorCount != 0)
520 fprintf (stderr, "Error (code: %u)\n", errorCount); 523 fprintf (stderr, "Error (code: %u)\n", errorCount);
diff --git a/src/testcurl/test_get.c b/src/testcurl/test_get.c
index 1c9796f7..cb81283f 100644
--- a/src/testcurl/test_get.c
+++ b/src/testcurl/test_get.c
@@ -739,38 +739,43 @@ int
739main (int argc, char *const *argv) 739main (int argc, char *const *argv)
740{ 740{
741 unsigned int errorCount = 0; 741 unsigned int errorCount = 0;
742 (void)argc; /* Unused. Silent compiler warning. */ 742 (void) argc; /* Unused. Silence compiler warning. */
743 743
744 oneone = (NULL != strrchr (argv[0], (int) '/')) ? 744 oneone = (NULL != strrchr (argv[0], (int) '/')) ?
745 (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0; 745 (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
746 if (0 != curl_global_init (CURL_GLOBAL_WIN32)) 746 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
747 return 2; 747 return 2;
748 global_port = 0; 748 global_port = 0;
749 errorCount += testInternalGet (0);
750 errorCount += testMultithreadedGet (0);
751 errorCount += testMultithreadedPoolGet (0);
752 errorCount += testUnknownPortGet (0);
753 errorCount += testStopRace (0);
754 errorCount += testExternalGet (); 749 errorCount += testExternalGet ();
755 errorCount += testEmptyGet (0); 750 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_THREADS))
756 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_POLL))
757 { 751 {
758 errorCount += testInternalGet(MHD_USE_POLL); 752 errorCount += testInternalGet (0);
759 errorCount += testMultithreadedGet(MHD_USE_POLL); 753 errorCount += testMultithreadedGet (0);
760 errorCount += testMultithreadedPoolGet(MHD_USE_POLL); 754 errorCount += testMultithreadedPoolGet (0);
761 errorCount += testUnknownPortGet(MHD_USE_POLL); 755 errorCount += testUnknownPortGet (0);
762 errorCount += testStopRace(MHD_USE_POLL); 756 errorCount += testStopRace (0);
763 errorCount += testEmptyGet(MHD_USE_POLL); 757 errorCount += testEmptyGet (0);
758 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_POLL))
759 {
760 errorCount += testInternalGet(MHD_USE_POLL);
761 errorCount += testMultithreadedGet(MHD_USE_POLL);
762 errorCount += testMultithreadedPoolGet(MHD_USE_POLL);
763 errorCount += testUnknownPortGet(MHD_USE_POLL);
764 errorCount += testStopRace(MHD_USE_POLL);
765 errorCount += testEmptyGet(MHD_USE_POLL);
766 }
767 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_EPOLL))
768 {
769 errorCount += testInternalGet(MHD_USE_EPOLL);
770 errorCount += testMultithreadedPoolGet(MHD_USE_EPOLL);
771 errorCount += testUnknownPortGet(MHD_USE_EPOLL);
772 errorCount += testEmptyGet(MHD_USE_EPOLL);
773 }
764 } 774 }
765 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_EPOLL)) 775 if (0 != errorCount)
766 { 776 fprintf (stderr,
767 errorCount += testInternalGet(MHD_USE_EPOLL); 777 "Error (code: %u)\n",
768 errorCount += testMultithreadedPoolGet(MHD_USE_EPOLL); 778 errorCount);
769 errorCount += testUnknownPortGet(MHD_USE_EPOLL);
770 errorCount += testEmptyGet(MHD_USE_EPOLL);
771 }
772 if (errorCount != 0)
773 fprintf (stderr, "Error (code: %u)\n", errorCount);
774 curl_global_cleanup (); 779 curl_global_cleanup ();
775 return errorCount != 0; /* 0 == pass */ 780 return errorCount != 0; /* 0 == pass */
776} 781}
diff --git a/src/testcurl/test_get_chunked.c b/src/testcurl/test_get_chunked.c
index d813566c..66a9fbde 100644
--- a/src/testcurl/test_get_chunked.c
+++ b/src/testcurl/test_get_chunked.c
@@ -506,9 +506,12 @@ main (int argc, char *const *argv)
506 506
507 if (0 != curl_global_init (CURL_GLOBAL_WIN32)) 507 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
508 return 2; 508 return 2;
509 errorCount += testInternalGet (); 509 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_THREADS))
510 errorCount += testMultithreadedGet (); 510 {
511 errorCount += testMultithreadedPoolGet (); 511 errorCount += testInternalGet ();
512 errorCount += testMultithreadedGet ();
513 errorCount += testMultithreadedPoolGet ();
514 }
512 errorCount += testExternalGet (); 515 errorCount += testExternalGet ();
513 if (errorCount != 0) 516 if (errorCount != 0)
514 fprintf (stderr, "Error (code: %u)\n", errorCount); 517 fprintf (stderr, "Error (code: %u)\n", errorCount);
diff --git a/src/testcurl/test_get_response_cleanup.c b/src/testcurl/test_get_response_cleanup.c
index d3d45d2f..457c646f 100644
--- a/src/testcurl/test_get_response_cleanup.c
+++ b/src/testcurl/test_get_response_cleanup.c
@@ -417,9 +417,12 @@ main (int argc, char *const *argv)
417 417
418 oneone = (NULL != strrchr (argv[0], (int) '/')) ? 418 oneone = (NULL != strrchr (argv[0], (int) '/')) ?
419 (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0; 419 (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
420 errorCount += testInternalGet (); 420 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_THREADS))
421 errorCount += testMultithreadedGet (); 421 {
422 errorCount += testMultithreadedPoolGet (); 422 errorCount += testInternalGet ();
423 errorCount += testMultithreadedGet ();
424 errorCount += testMultithreadedPoolGet ();
425 }
423 errorCount += testExternalGet (); 426 errorCount += testExternalGet ();
424 if (errorCount != 0) 427 if (errorCount != 0)
425 fprintf (stderr, "Error (code: %u)\n", errorCount); 428 fprintf (stderr, "Error (code: %u)\n", errorCount);
diff --git a/src/testcurl/test_get_sendfile.c b/src/testcurl/test_get_sendfile.c
index c7e94945..3d820fc8 100644
--- a/src/testcurl/test_get_sendfile.c
+++ b/src/testcurl/test_get_sendfile.c
@@ -603,11 +603,14 @@ main (int argc, char *const *argv)
603 fclose (f); 603 fclose (f);
604 if (0 != curl_global_init (CURL_GLOBAL_WIN32)) 604 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
605 return 2; 605 return 2;
606 errorCount += testInternalGet (); 606 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_THREADS))
607 errorCount += testMultithreadedGet (); 607 {
608 errorCount += testMultithreadedPoolGet (); 608 errorCount += testInternalGet ();
609 errorCount += testMultithreadedGet ();
610 errorCount += testMultithreadedPoolGet ();
611 errorCount += testUnknownPortGet ();
612 }
609 errorCount += testExternalGet (); 613 errorCount += testExternalGet ();
610 errorCount += testUnknownPortGet ();
611 if (errorCount != 0) 614 if (errorCount != 0)
612 fprintf (stderr, "Error (code: %u)\n", errorCount); 615 fprintf (stderr, "Error (code: %u)\n", errorCount);
613 curl_global_cleanup (); 616 curl_global_cleanup ();
diff --git a/src/testcurl/test_large_put.c b/src/testcurl/test_large_put.c
index b7a87c8f..f4c767cc 100644
--- a/src/testcurl/test_large_put.c
+++ b/src/testcurl/test_large_put.c
@@ -605,47 +605,50 @@ main (int argc, char *const *argv)
605 put_buffer = alloc_init (PUT_SIZE); 605 put_buffer = alloc_init (PUT_SIZE);
606 if (NULL == put_buffer) 606 if (NULL == put_buffer)
607 return 99; 607 return 99;
608 lastErr = testPutInternalThread (0);
609 if (verbose && 0 != lastErr)
610 fprintf (stderr, "Error during testing with internal thread with select().\n");
611 errorCount += lastErr;
612 lastErr = testPutThreadPerConn (0);
613 if (verbose && 0 != lastErr)
614 fprintf (stderr, "Error during testing with internal thread per connection with select().\n");
615 errorCount += lastErr;
616 lastErr = testPutThreadPool (0);
617 if (verbose && 0 != lastErr)
618 fprintf (stderr, "Error during testing with thread pool per connection with select().\n");
619 errorCount += lastErr;
620 lastErr = testPutExternal (); 608 lastErr = testPutExternal ();
621 if (verbose && 0 != lastErr) 609 if (verbose && 0 != lastErr)
622 fprintf (stderr, "Error during testing with external select().\n"); 610 fprintf (stderr, "Error during testing with external select().\n");
623 errorCount += lastErr; 611 errorCount += lastErr;
624 if (MHD_is_feature_supported(MHD_FEATURE_POLL)) 612 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_THREADS))
625 { 613 {
626 lastErr = testPutInternalThread (MHD_USE_POLL); 614 lastErr = testPutInternalThread (0);
627 if (verbose && 0 != lastErr) 615 if (verbose && 0 != lastErr)
628 fprintf (stderr, "Error during testing with internal thread with poll().\n"); 616 fprintf (stderr, "Error during testing with internal thread with select().\n");
629 errorCount += lastErr; 617 errorCount += lastErr;
630 lastErr = testPutThreadPerConn (MHD_USE_POLL); 618 lastErr = testPutThreadPerConn (0);
631 if (verbose && 0 != lastErr)
632 fprintf (stderr, "Error during testing with internal thread per connection with poll().\n");
633 errorCount += lastErr;
634 lastErr = testPutThreadPool (MHD_USE_POLL);
635 if (verbose && 0 != lastErr)
636 fprintf (stderr, "Error during testing with thread pool per connection with poll().\n");
637 errorCount += lastErr;
638 }
639 if (MHD_is_feature_supported(MHD_FEATURE_EPOLL))
640 {
641 lastErr = testPutInternalThread (MHD_USE_EPOLL);
642 if (verbose && 0 != lastErr) 619 if (verbose && 0 != lastErr)
643 fprintf (stderr, "Error during testing with internal thread with epoll.\n"); 620 fprintf (stderr, "Error during testing with internal thread per connection with select().\n");
644 errorCount += lastErr; 621 errorCount += lastErr;
645 lastErr = testPutThreadPool (MHD_USE_EPOLL); 622 lastErr = testPutThreadPool (0);
646 if (verbose && 0 != lastErr) 623 if (verbose && 0 != lastErr)
647 fprintf (stderr, "Error during testing with thread pool per connection with epoll.\n"); 624 fprintf (stderr, "Error during testing with thread pool per connection with select().\n");
648 errorCount += lastErr; 625 errorCount += lastErr;
626 if (MHD_is_feature_supported(MHD_FEATURE_POLL))
627 {
628 lastErr = testPutInternalThread (MHD_USE_POLL);
629 if (verbose && 0 != lastErr)
630 fprintf (stderr, "Error during testing with internal thread with poll().\n");
631 errorCount += lastErr;
632 lastErr = testPutThreadPerConn (MHD_USE_POLL);
633 if (verbose && 0 != lastErr)
634 fprintf (stderr, "Error during testing with internal thread per connection with poll().\n");
635 errorCount += lastErr;
636 lastErr = testPutThreadPool (MHD_USE_POLL);
637 if (verbose && 0 != lastErr)
638 fprintf (stderr, "Error during testing with thread pool per connection with poll().\n");
639 errorCount += lastErr;
640 }
641 if (MHD_is_feature_supported(MHD_FEATURE_EPOLL))
642 {
643 lastErr = testPutInternalThread (MHD_USE_EPOLL);
644 if (verbose && 0 != lastErr)
645 fprintf (stderr, "Error during testing with internal thread with epoll.\n");
646 errorCount += lastErr;
647 lastErr = testPutThreadPool (MHD_USE_EPOLL);
648 if (verbose && 0 != lastErr)
649 fprintf (stderr, "Error during testing with thread pool per connection with epoll.\n");
650 errorCount += lastErr;
651 }
649 } 652 }
650 free (put_buffer); 653 free (put_buffer);
651 if (errorCount != 0) 654 if (errorCount != 0)
diff --git a/src/testcurl/test_post.c b/src/testcurl/test_post.c
index 6b91b9cc..cfef2c46 100644
--- a/src/testcurl/test_post.c
+++ b/src/testcurl/test_post.c
@@ -774,10 +774,13 @@ main (int argc, char *const *argv)
774 (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0; 774 (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
775 if (0 != curl_global_init (CURL_GLOBAL_WIN32)) 775 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
776 return 2; 776 return 2;
777 errorCount += testMultithreadedPostCancel (); 777 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_THREADS))
778 errorCount += testInternalPost (); 778 {
779 errorCount += testMultithreadedPost (); 779 errorCount += testMultithreadedPostCancel ();
780 errorCount += testMultithreadedPoolPost (); 780 errorCount += testInternalPost ();
781 errorCount += testMultithreadedPost ();
782 errorCount += testMultithreadedPoolPost ();
783 }
781 errorCount += testExternalPost (); 784 errorCount += testExternalPost ();
782 if (errorCount != 0) 785 if (errorCount != 0)
783 fprintf (stderr, "Error (code: %u)\n", errorCount); 786 fprintf (stderr, "Error (code: %u)\n", errorCount);
diff --git a/src/testcurl/test_post_loop.c b/src/testcurl/test_post_loop.c
index 6da06b45..aae297d4 100644
--- a/src/testcurl/test_post_loop.c
+++ b/src/testcurl/test_post_loop.c
@@ -583,36 +583,39 @@ main (int argc, char *const *argv)
583 (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0; 583 (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
584 if (0 != curl_global_init (CURL_GLOBAL_WIN32)) 584 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
585 return 2; 585 return 2;
586 start_time = now(); 586 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_THREADS))
587 errorCount += testInternalPost (); 587 {
588 fprintf (stderr, 588 start_time = now();
589 oneone ? "%s: Sequential POSTs (http/1.1) %f/s\n" : "%s: Sequential POSTs (http/1.0) %f/s\n", 589 errorCount += testInternalPost ();
590 "internal select", 590 fprintf (stderr,
591 (double) 1000 * LOOPCOUNT / (now() - start_time + 1.0)); 591 oneone ? "%s: Sequential POSTs (http/1.1) %f/s\n" : "%s: Sequential POSTs (http/1.0) %f/s\n",
592 GAUGER ("internal select", 592 "internal select",
593 oneone ? "Sequential POSTs (http/1.1)" : "Sequential POSTs (http/1.0)", 593 (double) 1000 * LOOPCOUNT / (now() - start_time + 1.0));
594 (double) 1000 * LOOPCOUNT / (now() - start_time + 1.0), 594 GAUGER ("internal select",
595 "requests/s"); 595 oneone ? "Sequential POSTs (http/1.1)" : "Sequential POSTs (http/1.0)",
596 start_time = now(); 596 (double) 1000 * LOOPCOUNT / (now() - start_time + 1.0),
597 errorCount += testMultithreadedPost (); 597 "requests/s");
598 fprintf (stderr, 598 start_time = now();
599 oneone ? "%s: Sequential POSTs (http/1.1) %f/s\n" : "%s: Sequential POSTs (http/1.0) %f/s\n", 599 errorCount += testMultithreadedPost ();
600 "multithreaded post", 600 fprintf (stderr,
601 (double) 1000 * LOOPCOUNT / (now() - start_time + 1.0)); 601 oneone ? "%s: Sequential POSTs (http/1.1) %f/s\n" : "%s: Sequential POSTs (http/1.0) %f/s\n",
602 GAUGER ("Multithreaded select", 602 "multithreaded post",
603 oneone ? "Sequential POSTs (http/1.1)" : "Sequential POSTs (http/1.0)", 603 (double) 1000 * LOOPCOUNT / (now() - start_time + 1.0));
604 (double) 1000 * LOOPCOUNT / (now() - start_time + 1.0), 604 GAUGER ("Multithreaded select",
605 "requests/s"); 605 oneone ? "Sequential POSTs (http/1.1)" : "Sequential POSTs (http/1.0)",
606 start_time = now(); 606 (double) 1000 * LOOPCOUNT / (now() - start_time + 1.0),
607 errorCount += testMultithreadedPoolPost (); 607 "requests/s");
608 fprintf (stderr, 608 start_time = now();
609 oneone ? "%s: Sequential POSTs (http/1.1) %f/s\n" : "%s: Sequential POSTs (http/1.0) %f/s\n", 609 errorCount += testMultithreadedPoolPost ();
610 "thread with pool", 610 fprintf (stderr,
611 (double) 1000 * LOOPCOUNT / (now() - start_time + 1.0)); 611 oneone ? "%s: Sequential POSTs (http/1.1) %f/s\n" : "%s: Sequential POSTs (http/1.0) %f/s\n",
612 GAUGER ("thread with pool", 612 "thread with pool",
613 oneone ? "Sequential POSTs (http/1.1)" : "Sequential POSTs (http/1.0)", 613 (double) 1000 * LOOPCOUNT / (now() - start_time + 1.0));
614 (double) 1000 * LOOPCOUNT / (now() - start_time + 1.0), 614 GAUGER ("thread with pool",
615 "requests/s"); 615 oneone ? "Sequential POSTs (http/1.1)" : "Sequential POSTs (http/1.0)",
616 (double) 1000 * LOOPCOUNT / (now() - start_time + 1.0),
617 "requests/s");
618 }
616 start_time = now(); 619 start_time = now();
617 errorCount += testExternalPost (); 620 errorCount += testExternalPost ();
618 fprintf (stderr, 621 fprintf (stderr,
diff --git a/src/testcurl/test_postform.c b/src/testcurl/test_postform.c
index f94ed1f8..746d6baa 100644
--- a/src/testcurl/test_postform.c
+++ b/src/testcurl/test_postform.c
@@ -589,9 +589,12 @@ main (int argc, char *const *argv)
589 (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0; 589 (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
590 if (0 != curl_global_init (CURL_GLOBAL_WIN32)) 590 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
591 return 2; 591 return 2;
592 errorCount += testInternalPost (); 592 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_THREADS))
593 errorCount += testMultithreadedPost (); 593 {
594 errorCount += testMultithreadedPoolPost (); 594 errorCount += testInternalPost ();
595 errorCount += testMultithreadedPost ();
596 errorCount += testMultithreadedPoolPost ();
597 }
595 errorCount += testExternalPost (); 598 errorCount += testExternalPost ();
596 if (errorCount != 0) 599 if (errorCount != 0)
597 fprintf (stderr, "Error (code: %u)\n", errorCount); 600 fprintf (stderr, "Error (code: %u)\n", errorCount);
diff --git a/src/testcurl/test_process_headers.c b/src/testcurl/test_process_headers.c
index d123c441..f9c7cd03 100644
--- a/src/testcurl/test_process_headers.c
+++ b/src/testcurl/test_process_headers.c
@@ -520,9 +520,12 @@ main (int argc, char *const *argv)
520 520
521 oneone = (NULL != strrchr (argv[0], (int) '/')) ? 521 oneone = (NULL != strrchr (argv[0], (int) '/')) ?
522 (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0; 522 (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
523 errorCount += testInternalGet (); 523 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_THREADS))
524 errorCount += testMultithreadedGet (); 524 {
525 errorCount += testMultithreadedPoolGet (); 525 errorCount += testInternalGet ();
526 errorCount += testMultithreadedGet ();
527 errorCount += testMultithreadedPoolGet ();
528 }
526 errorCount += testExternalGet (); 529 errorCount += testExternalGet ();
527 if (errorCount != 0) 530 if (errorCount != 0)
528 fprintf (stderr, "Error (code: %u)\n", errorCount); 531 fprintf (stderr, "Error (code: %u)\n", errorCount);
diff --git a/src/testcurl/test_put.c b/src/testcurl/test_put.c
index eba7afa0..3df97526 100644
--- a/src/testcurl/test_put.c
+++ b/src/testcurl/test_put.c
@@ -525,9 +525,12 @@ main (int argc, char *const *argv)
525 (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0; 525 (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
526 if (0 != curl_global_init (CURL_GLOBAL_WIN32)) 526 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
527 return 2; 527 return 2;
528 errorCount += testInternalPut (); 528 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_THREADS))
529 errorCount += testMultithreadedPut (); 529 {
530 errorCount += testMultithreadedPoolPut (); 530 errorCount += testInternalPut ();
531 errorCount += testMultithreadedPut ();
532 errorCount += testMultithreadedPoolPut ();
533 }
531 errorCount += testExternalPut (); 534 errorCount += testExternalPut ();
532 if (errorCount != 0) 535 if (errorCount != 0)
533 fprintf (stderr, "Error (code: %u)\n", errorCount); 536 fprintf (stderr, "Error (code: %u)\n", errorCount);
diff --git a/src/testcurl/test_put_chunked.c b/src/testcurl/test_put_chunked.c
index 71e10b77..017bff99 100644
--- a/src/testcurl/test_put_chunked.c
+++ b/src/testcurl/test_put_chunked.c
@@ -518,9 +518,12 @@ main (int argc, char *const *argv)
518 518
519 if (0 != curl_global_init (CURL_GLOBAL_WIN32)) 519 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
520 return 2; 520 return 2;
521 errorCount += testInternalPut (); 521 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_THREADS))
522 errorCount += testMultithreadedPut (); 522 {
523 errorCount += testMultithreadedPoolPut (); 523 errorCount += testInternalPut ();
524 errorCount += testMultithreadedPut ();
525 errorCount += testMultithreadedPoolPut ();
526 }
524 errorCount += testExternalPut (); 527 errorCount += testExternalPut ();
525 if (errorCount != 0) 528 if (errorCount != 0)
526 fprintf (stderr, "Error (code: %u)\n", errorCount); 529 fprintf (stderr, "Error (code: %u)\n", errorCount);
diff --git a/src/testcurl/test_quiesce.c b/src/testcurl/test_quiesce.c
index f9fd9690..5795898a 100644
--- a/src/testcurl/test_quiesce.c
+++ b/src/testcurl/test_quiesce.c
@@ -530,23 +530,28 @@ main (int argc, char *const *argv)
530 530
531 if (0 != curl_global_init (CURL_GLOBAL_WIN32)) 531 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
532 return 2; 532 return 2;
533 errorCount += testGet (MHD_USE_INTERNAL_POLLING_THREAD, 0, 0);
534 errorCount += testGet (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD, 0, 0);
535 errorCount += testGet (MHD_USE_INTERNAL_POLLING_THREAD, CPU_COUNT, 0);
536 errorCount += testExternalGet (); 533 errorCount += testExternalGet ();
537 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_POLL)) 534 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_THREADS))
538 { 535 {
539 errorCount += testGet(MHD_USE_INTERNAL_POLLING_THREAD, 0, MHD_USE_POLL); 536 errorCount += testGet (MHD_USE_INTERNAL_POLLING_THREAD, 0, 0);
540 errorCount += testGet (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD, 0, MHD_USE_POLL); 537 errorCount += testGet (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD, 0, 0);
541 errorCount += testGet (MHD_USE_INTERNAL_POLLING_THREAD, CPU_COUNT, MHD_USE_POLL); 538 errorCount += testGet (MHD_USE_INTERNAL_POLLING_THREAD, CPU_COUNT, 0);
539 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_POLL))
540 {
541 errorCount += testGet(MHD_USE_INTERNAL_POLLING_THREAD, 0, MHD_USE_POLL);
542 errorCount += testGet (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD, 0, MHD_USE_POLL);
543 errorCount += testGet (MHD_USE_INTERNAL_POLLING_THREAD, CPU_COUNT, MHD_USE_POLL);
544 }
545 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_EPOLL))
546 {
547 errorCount += testGet (MHD_USE_INTERNAL_POLLING_THREAD, 0, MHD_USE_EPOLL);
548 errorCount += testGet (MHD_USE_INTERNAL_POLLING_THREAD, CPU_COUNT, MHD_USE_EPOLL);
549 }
542 } 550 }
543 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_EPOLL)) 551 if (0 != errorCount)
544 { 552 fprintf (stderr,
545 errorCount += testGet (MHD_USE_INTERNAL_POLLING_THREAD, 0, MHD_USE_EPOLL); 553 "Error (code: %u)\n",
546 errorCount += testGet (MHD_USE_INTERNAL_POLLING_THREAD, CPU_COUNT, MHD_USE_EPOLL); 554 errorCount);
547 }
548 if (errorCount != 0)
549 fprintf (stderr, "Error (code: %u)\n", errorCount);
550 curl_global_cleanup (); 555 curl_global_cleanup ();
551 return errorCount != 0; /* 0 == pass */ 556 return errorCount != 0; /* 0 == pass */
552} 557}
diff --git a/src/testzzuf/Makefile.am b/src/testzzuf/Makefile.am
index 329fe04d..be31bad2 100644
--- a/src/testzzuf/Makefile.am
+++ b/src/testzzuf/Makefile.am
@@ -11,6 +11,9 @@ AM_CPPFLAGS = -I$(top_srcdir)/src/include \
11 11
12EXTRA_DIST = README socat.c 12EXTRA_DIST = README socat.c
13 13
14THREAD_ONLY_TESTS = \
15 test_long_header
16
14check_PROGRAMS = \ 17check_PROGRAMS = \
15 test_get \ 18 test_get \
16 test_get_chunked \ 19 test_get_chunked \
@@ -23,8 +26,17 @@ check_PROGRAMS = \
23 test_post11 \ 26 test_post11 \
24 test_post_form11 \ 27 test_post_form11 \
25 test_put11 \ 28 test_put11 \
26 test_put_large11 \ 29 test_put_large11
27 test_long_header 30
31if USE_POSIX_THREADS
32check_PROGRAMS +=
33 $(THREAD_ONLY_TESTS)
34endif
35if USE_W32_THREADS
36check_PROGRAMS +=
37 $(THREAD_ONLY_TESTS)
38endif
39
28 40
29TESTS = $(check_PROGRAMS) 41TESTS = $(check_PROGRAMS)
30 42
diff --git a/src/testzzuf/test_get.c b/src/testzzuf/test_get.c
index 7e116d09..223b85e5 100644
--- a/src/testzzuf/test_get.c
+++ b/src/testzzuf/test_get.c
@@ -306,8 +306,11 @@ main (int argc, char *const *argv)
306 (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0; 306 (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
307 if (0 != curl_global_init (CURL_GLOBAL_WIN32)) 307 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
308 return 2; 308 return 2;
309 errorCount += testInternalGet (); 309 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_THREADS))
310 errorCount += testMultithreadedGet (); 310 {
311 errorCount += testInternalGet ();
312 errorCount += testMultithreadedGet ();
313 }
311 errorCount += testExternalGet (); 314 errorCount += testExternalGet ();
312 if (errorCount != 0) 315 if (errorCount != 0)
313 fprintf (stderr, "Error (code: %u)\n", errorCount); 316 fprintf (stderr, "Error (code: %u)\n", errorCount);
diff --git a/src/testzzuf/test_get_chunked.c b/src/testzzuf/test_get_chunked.c
index a74b5d9f..44828853 100644
--- a/src/testzzuf/test_get_chunked.c
+++ b/src/testzzuf/test_get_chunked.c
@@ -335,8 +335,11 @@ main (int argc, char *const *argv)
335 335
336 if (0 != curl_global_init (CURL_GLOBAL_WIN32)) 336 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
337 return 2; 337 return 2;
338 errorCount += testInternalGet (); 338 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_THREADS))
339 errorCount += testMultithreadedGet (); 339 {
340 errorCount += testInternalGet ();
341 errorCount += testMultithreadedGet ();
342 }
340 errorCount += testExternalGet (); 343 errorCount += testExternalGet ();
341 if (errorCount != 0) 344 if (errorCount != 0)
342 fprintf (stderr, "Error (code: %u)\n", errorCount); 345 fprintf (stderr, "Error (code: %u)\n", errorCount);
diff --git a/src/testzzuf/test_post.c b/src/testzzuf/test_post.c
index 9a4a8e9c..836f3395 100644
--- a/src/testzzuf/test_post.c
+++ b/src/testzzuf/test_post.c
@@ -389,8 +389,11 @@ main (int argc, char *const *argv)
389 (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0; 389 (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
390 if (0 != curl_global_init (CURL_GLOBAL_WIN32)) 390 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
391 return 2; 391 return 2;
392 errorCount += testInternalPost (); 392 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_THREADS))
393 errorCount += testMultithreadedPost (); 393 {
394 errorCount += testInternalPost ();
395 errorCount += testMultithreadedPost ();
396 }
394 errorCount += testExternalPost (); 397 errorCount += testExternalPost ();
395 if (errorCount != 0) 398 if (errorCount != 0)
396 fprintf (stderr, "Error (code: %u)\n", errorCount); 399 fprintf (stderr, "Error (code: %u)\n", errorCount);
diff --git a/src/testzzuf/test_post_form.c b/src/testzzuf/test_post_form.c
index d4e01c2b..571c9d99 100644
--- a/src/testzzuf/test_post_form.c
+++ b/src/testzzuf/test_post_form.c
@@ -405,8 +405,11 @@ main (int argc, char *const *argv)
405 (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0; 405 (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
406 if (0 != curl_global_init (CURL_GLOBAL_WIN32)) 406 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
407 return 2; 407 return 2;
408 errorCount += testInternalPost (); 408 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_THREADS))
409 errorCount += testMultithreadedPost (); 409 {
410 errorCount += testInternalPost ();
411 errorCount += testMultithreadedPost ();
412 }
410 errorCount += testExternalPost (); 413 errorCount += testExternalPost ();
411 if (errorCount != 0) 414 if (errorCount != 0)
412 fprintf (stderr, "Error (code: %u)\n", errorCount); 415 fprintf (stderr, "Error (code: %u)\n", errorCount);
diff --git a/src/testzzuf/test_put.c b/src/testzzuf/test_put.c
index cfe12dee..63518ba8 100644
--- a/src/testzzuf/test_put.c
+++ b/src/testzzuf/test_put.c
@@ -353,8 +353,11 @@ main (int argc, char *const *argv)
353 (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0; 353 (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
354 if (0 != curl_global_init (CURL_GLOBAL_WIN32)) 354 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
355 return 2; 355 return 2;
356 errorCount += testInternalPut (); 356 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_THREADS))
357 errorCount += testMultithreadedPut (); 357 {
358 errorCount += testInternalPut ();
359 errorCount += testMultithreadedPut ();
360 }
358 errorCount += testExternalPut (); 361 errorCount += testExternalPut ();
359 if (errorCount != 0) 362 if (errorCount != 0)
360 fprintf (stderr, "Error (code: %u)\n", errorCount); 363 fprintf (stderr, "Error (code: %u)\n", errorCount);
diff --git a/src/testzzuf/test_put_chunked.c b/src/testzzuf/test_put_chunked.c
index 72a9f316..642e968a 100644
--- a/src/testzzuf/test_put_chunked.c
+++ b/src/testzzuf/test_put_chunked.c
@@ -363,8 +363,11 @@ main (int argc, char *const *argv)
363 363
364 if (0 != curl_global_init (CURL_GLOBAL_WIN32)) 364 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
365 return 2; 365 return 2;
366 errorCount += testInternalPut (); 366 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_THREADS))
367 errorCount += testMultithreadedPut (); 367 {
368 errorCount += testInternalPut ();
369 errorCount += testMultithreadedPut ();
370 }
368 errorCount += testExternalPut (); 371 errorCount += testExternalPut ();
369 if (errorCount != 0) 372 if (errorCount != 0)
370 fprintf (stderr, "Error (code: %u)\n", errorCount); 373 fprintf (stderr, "Error (code: %u)\n", errorCount);
diff --git a/src/testzzuf/test_put_large.c b/src/testzzuf/test_put_large.c
index 540c37f9..40861b87 100644
--- a/src/testzzuf/test_put_large.c
+++ b/src/testzzuf/test_put_large.c
@@ -373,8 +373,11 @@ main (int argc, char *const *argv)
373 return 2; 373 return 2;
374 put_buffer = malloc (PUT_SIZE); 374 put_buffer = malloc (PUT_SIZE);
375 memset (put_buffer, 1, PUT_SIZE); 375 memset (put_buffer, 1, PUT_SIZE);
376 errorCount += testInternalPut (); 376 if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_THREADS))
377 errorCount += testMultithreadedPut (); 377 {
378 errorCount += testInternalPut ();
379 errorCount += testMultithreadedPut ();
380 }
378 errorCount += testExternalPut (); 381 errorCount += testExternalPut ();
379 free (put_buffer); 382 free (put_buffer);
380 if (errorCount != 0) 383 if (errorCount != 0)