diff --git a/src/include/microhttpd2.h b/src/include/microhttpd2.h index 77df726c..4412179d 100644 --- a/src/include/microhttpd2.h +++ b/src/include/microhttpd2.h @@ -5332,7 +5332,7 @@ MHD_FN_PAR_NONNULL_ALL_; MHD_EXTERN_ const struct MHD_Action * MHD_action_from_response (struct MHD_Request *MHD_RESTRICT request, struct MHD_Response *MHD_RESTRICT response) -MHD_FN_PAR_NONNULL_(1); +MHD_FN_PAR_NONNULL_ (1); /** @@ -5900,7 +5900,7 @@ MHD_FN_RETURNS_NONNULL_ MHD_FN_PAR_NONNULL_ALL_; MHD_EXTERN_ const struct MHD_UploadAction * MHD_upload_action_from_response (struct MHD_Request *MHD_RESTRICT request, struct MHD_Response *MHD_RESTRICT response) -MHD_FN_PAR_NONNULL_(1); +MHD_FN_PAR_NONNULL_ (1); /** * Action telling MHD to continue processing the upload. diff --git a/src/tests/basic/libtest.h b/src/tests/basic/libtest.h index 2dcc65be..49bbf9e8 100644 --- a/src/tests/basic/libtest.h +++ b/src/tests/basic/libtest.h @@ -319,7 +319,9 @@ typedef void * simple #MHD_daemon_start() method until * a read() against @a finsig succeeds. * - * @param cls closure + * @param cls closure, pass a NULL-terminated (!) + * array of `struct MHD_DaemonOptionAndValue` with the + * the threading mode to use * @param finsig fd to read from to detect termination request * @param[in,out] d daemon to run */ diff --git a/src/tests/basic/libtest_convenience.c b/src/tests/basic/libtest_convenience.c index 50f5416e..77dcb557 100644 --- a/src/tests/basic/libtest_convenience.c +++ b/src/tests/basic/libtest_convenience.c @@ -37,11 +37,19 @@ const char * MHDT_server_setup_minimal (void *cls, struct MHD_Daemon *d) { + const struct MHD_DaemonOptionAndValue *options = cls; + + if (MHD_SC_OK != + MHD_daemon_set_options ( + d, + options, + MHD_OPTIONS_ARRAY_MAX_SIZE)) + return "Failed to configure threading mode!"; + return NULL; + if (MHD_SC_OK != MHD_DAEMON_SET_OPTIONS ( d, - MHD_D_OPTION_POLL_SYSCALL (MHD_SPS_POLL), - MHD_D_OPTION_WM_WORKER_THREADS (1), MHD_D_OPTION_BIND_PORT (MHD_AF_AUTO, 0))) return "Failed to bind to port 0!"; @@ -90,7 +98,6 @@ MHDT_server_run_minimal (void *cls, } -#if FUTURE void MHDT_server_run_blocking (void *cls, int finsig, @@ -120,7 +127,7 @@ MHDT_server_run_blocking (void *cls, strerror (errno)); break; } - +#if FIXME if (MHD_SC_OK != MHD_daemon_process_blocking (d, 1000)) @@ -129,6 +136,9 @@ MHDT_server_run_blocking (void *cls, "Failure running MHD_daemon_process_blocking()\n"); break; } +#else + abort (); +#endif } if ( (FD_ISSET (finsig, &r)) && @@ -140,6 +150,3 @@ MHDT_server_run_blocking (void *cls, "Failed to drain termination signal\n"); } } - - -#endif diff --git a/src/tests/basic/test_client_server.c b/src/tests/basic/test_client_server.c index c4a54fd3..269559c6 100644 --- a/src/tests/basic/test_client_server.c +++ b/src/tests/basic/test_client_server.c @@ -24,12 +24,124 @@ * @author Christian Grothoff */ #include +#include "mhd_config.h" #include "libtest.h" int main (int argc, char *argv[]) { + struct MHD_DaemonOptionAndValue thread1select[] = { + MHD_D_OPTION_POLL_SYSCALL (MHD_SPS_SELECT), + MHD_D_OPTION_WM_WORKER_THREADS (1), + MHD_D_OPTION_TERMINATE () + }; + struct MHD_DaemonOptionAndValue thread2select[] = { + MHD_D_OPTION_POLL_SYSCALL (MHD_SPS_SELECT), + MHD_D_OPTION_WM_WORKER_THREADS (2), + MHD_D_OPTION_TERMINATE () + }; + struct MHD_DaemonOptionAndValue thread1poll[] = { + MHD_D_OPTION_POLL_SYSCALL (MHD_SPS_POLL), + MHD_D_OPTION_WM_WORKER_THREADS (1), + MHD_D_OPTION_TERMINATE () + }; + struct MHD_DaemonOptionAndValue thread2poll[] = { + MHD_D_OPTION_POLL_SYSCALL (MHD_SPS_POLL), + MHD_D_OPTION_WM_WORKER_THREADS (1), + MHD_D_OPTION_TERMINATE () + }; + struct MHD_DaemonOptionAndValue thread1epoll[] = { + MHD_D_OPTION_POLL_SYSCALL (MHD_SPS_EPOLL), + MHD_D_OPTION_WM_WORKER_THREADS (1), + MHD_D_OPTION_TERMINATE () + }; + struct MHD_DaemonOptionAndValue thread2epoll[] = { + MHD_D_OPTION_POLL_SYSCALL (MHD_SPS_EPOLL), + MHD_D_OPTION_WM_WORKER_THREADS (1), + MHD_D_OPTION_TERMINATE () + }; + struct MHD_DaemonOptionAndValue thread1auto[] = { + MHD_D_OPTION_POLL_SYSCALL (MHD_SPS_AUTO), + MHD_D_OPTION_WM_WORKER_THREADS (1), + MHD_D_OPTION_TERMINATE () + }; + struct MHD_DaemonOptionAndValue external0auto[] = { + MHD_D_OPTION_POLL_SYSCALL (MHD_SPS_AUTO), + MHD_D_OPTION_WM_EXTERNAL_PERIODIC (), + MHD_D_OPTION_TERMINATE () + }; + struct ServerType + { + const char *label; + MHDT_ServerSetup server_setup; + void *server_setup_cls; + MHDT_ServerRunner server_runner; + void *server_runner_cls; + } configs[] = { + { + .label = "single threaded select", + .server_setup = &MHDT_server_setup_minimal, + .server_setup_cls = thread1select, + .server_runner = &MHDT_server_run_minimal, + }, + { + .label = "multi-threaded select", + .server_setup = &MHDT_server_setup_minimal, + .server_setup_cls = thread2select, + .server_runner = &MHDT_server_run_minimal, + }, +#if HAVE_POLL + { + .label = "single threaded poll", + .server_setup = &MHDT_server_setup_minimal, + .server_setup_cls = thread1poll, + .server_runner = &MHDT_server_run_minimal, + }, + { + .label = "multi-threaded poll", + .server_setup = &MHDT_server_setup_minimal, + .server_setup_cls = thread2poll, + .server_runner = &MHDT_server_run_minimal, + }, +#endif +#if HAVE_EPOLL_CREATE1 + { + .label = "single threaded epoll", + .server_setup = &MHDT_server_setup_minimal, + .server_setup_cls = thread1epoll, + .server_runner = &MHDT_server_run_minimal, + }, + { + .label = "multi-threaded epoll", + .server_setup = &MHDT_server_setup_minimal, + .server_setup_cls = thread2epoll, + .server_runner = &MHDT_server_run_minimal, + }, +#endif + { + .label = "auto-selected mode, single threaded", + .server_setup = &MHDT_server_setup_minimal, + .server_setup_cls = thread1auto, + .server_runner = &MHDT_server_run_minimal, + }, +#if 1 + /* FIXME: remove once MHD_daemon_process_blocking + has been implemented */ + { + .label = "END" + }, +#endif + { + .label = "auto-selected external event loop mode, no threads", + .server_setup = &MHDT_server_setup_minimal, + .server_setup_cls = external0auto, + .server_runner = &MHDT_server_run_blocking, + }, + { + .label = "END" + } + }; struct MHDT_Phase phases[] = { { .label = "simple get", @@ -74,15 +186,31 @@ main (int argc, char *argv[]) .label = NULL, }, }; + unsigned int i; + (void) argc; /* Unused. Silence compiler warning. */ (void) argv; /* Unused. Silence compiler warning. */ - // threading modi - // socket polling functions (select, poll, epoll, internal, external edge, external level) - // - return MHDT_test (&MHDT_server_setup_minimal, - NULL, - &MHDT_server_run_minimal, - NULL, - phases); + for (i = 0; NULL != configs[i].server_setup; i++) + { + int ret; + + fprintf (stderr, + "Running tests with server setup `%s'\n", + configs[i].label); + ret = MHDT_test (configs[i].server_setup, + configs[i].server_setup_cls, + configs[i].server_runner, + configs[i].server_runner_cls, + phases); + if (0 != ret) + { + fprintf (stderr, + "Test failed with server of type `%s' (%u)\n", + configs[i].label, + i); + return ret; + } + } + return 0; }