diff options
Diffstat (limited to 'src/microhttpd/test_shutdown_select.c')
-rw-r--r-- | src/microhttpd/test_shutdown_select.c | 86 |
1 files changed, 81 insertions, 5 deletions
diff --git a/src/microhttpd/test_shutdown_select.c b/src/microhttpd/test_shutdown_select.c index 1ec0585c..8a374421 100644 --- a/src/microhttpd/test_shutdown_select.c +++ b/src/microhttpd/test_shutdown_select.c @@ -62,9 +62,16 @@ #ifdef HAVE_SYS_SELECT_H #include <sys/select.h> #endif /* HAVE_SYS_SELECT_H */ +#if defined(HAVE_POLL) && defined(HAVE_POLL_H) +#include <poll.h> +#endif /* HAVE_POLL && HAVE_POLL_H */ #define sock_errno (errno) #endif /* MHD_POSIX_SOCKETS */ +#ifdef HAVE_STDBOOL_H +#include <stdbool.h> +#endif /* HAVE_STDBOOL_H */ + #ifndef SOMAXCONN #define SOMAXCONN 511 #endif /* ! SOMAXCONN */ @@ -73,6 +80,33 @@ #define SHUT_RDWR SD_BOTH #endif +static _MHD_bool check_err; + +static _MHD_bool +has_in_name(const char *prog_name, const char *marker) +{ + size_t name_pos; + size_t pos; + + if (!prog_name || !marker) + return 0; + + pos = 0; + name_pos = 0; + while (prog_name[pos]) + { + if ('/' == prog_name[pos]) + name_pos = pos + 1; +#ifdef _WIN32 + else if ('\\' == prog_name[pos]) + name_pos = pos + 1; +#endif /* _WIN32 */ + pos++; + } + if (name_pos == pos) + return !0; + return strstr(prog_name + name_pos, marker) != NULL; +} static MHD_socket start_socket_listen(int domain) @@ -190,12 +224,31 @@ select_thread(void* data) timeout.tv_usec = 0; timeout.tv_sec = 7; - MHD_SYS_select_(listen_sock + 1, &rs, &ws, NULL, &timeout); + check_err = (0 > MHD_SYS_select_(listen_sock + 1, &rs, &ws, NULL, &timeout)); return (MHD_THRD_RTRN_TYPE_)0; } +#ifdef HAVE_POLL +MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ +poll_thread(void* data) +{ + /* use poll() like in daemon.c */ + struct pollfd p[1]; + MHD_socket listen_sock = *((MHD_socket*)data); + + p[0].fd = listen_sock; + p[0].events = POLLIN; + p[0].revents = 0; + + check_err = (0 > MHD_sys_poll_ (p, 1, 7000)); + + return (MHD_THRD_RTRN_TYPE_)0; +} +#endif /* HAVE_POLL */ + + static void local_sleep(unsigned seconds) { @@ -217,11 +270,27 @@ main (int argc, char *const *argv) int i; time_t start_t, end_t; int result = 0; - + MHD_THRD_RTRN_TYPE_ (MHD_THRD_CALL_SPEC_ *test_func)(void* data); #ifdef MHD_WINSOCK_SOCKETS WORD ver_req; WSADATA wsa_data; int err; +#endif /* MHD_WINSOCK_SOCKETS */ + _MHD_bool test_poll; + + test_poll = has_in_name(argv[0], "_poll"); + if (!test_poll) + test_func = &select_thread; + else + { +#ifndef HAVE_POLL + return 77; +#else /* ! HAVE_POLL */ + test_func = &poll_thread; +#endif /* ! HAVE_POLL */ + } + +#ifdef MHD_WINSOCK_SOCKETS ver_req = MAKEWORD(2, 2); err = WSAStartup(ver_req, &wsa_data); @@ -239,21 +308,22 @@ main (int argc, char *const *argv) for (i = 0; i < 5 && result == 0; i++) { MHD_thread_handle_ sel_thrd; - /* fprint f(stdout, "Creating, binding and listening socket...\n"); */ + /* fprintf(stdout, "Creating, binding and listening socket...\n"); */ MHD_socket listen_socket = start_socket_listen (AF_INET); if (MHD_INVALID_SOCKET == listen_socket) return 99; + check_err = !0; /* fprintf (stdout, "Starting select() thread...\n"); */ #if defined(MHD_USE_POSIX_THREADS) - if (0 != pthread_create (&sel_thrd, NULL, &select_thread, &listen_socket)) + if (0 != pthread_create (&sel_thrd, NULL, test_func, &listen_socket)) { MHD_socket_close_ (listen_socket); fprintf (stderr, "Can't start thread\n"); return 99; } #elif defined(MHD_USE_W32_THREADS) - sel_thrd = (HANDLE)_beginthreadex (NULL, 0, &select_thread, &listen_socket, 0, NULL); + sel_thrd = (HANDLE)_beginthreadex (NULL, 0, test_func, &listen_socket, 0, NULL); if (0 == (sel_thrd)) { MHD_socket_close_ (listen_socket); @@ -277,6 +347,12 @@ main (int argc, char *const *argv) fprintf (stderr, "Can't join select() thread\n"); return 99; } + if (check_err) + { + MHD_socket_close_(listen_socket); + fprintf (stderr, "Error in waiting thread\n"); + return 99; + } end_t = time (NULL); /* fprintf (stdout, "Thread finished.\n"); */ MHD_socket_close_(listen_socket); |