diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2016-02-05 20:47:58 +0000 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2016-02-05 20:47:58 +0000 |
commit | 96010724e3862241ff01a1b62f88499d2adc7827 (patch) | |
tree | 70786848535aacc7ec8f40113c923634f09da486 | |
parent | bc162a8e859d360d77f57df8fdf5a8daf746e72d (diff) | |
download | libmicrohttpd-96010724e3862241ff01a1b62f88499d2adc7827.tar.gz libmicrohttpd-96010724e3862241ff01a1b62f88499d2adc7827.zip |
Added test for checking ability of shutdown() on socket to trigger poll()
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | src/microhttpd/Makefile.am | 13 | ||||
-rw-r--r-- | src/microhttpd/test_shutdown_select.c | 86 |
3 files changed, 98 insertions, 6 deletions
@@ -1,3 +1,8 @@ | |||
1 | Fri Feb 5 20:43:11 CET 2016 | ||
2 | Fixed testsuite compile warning on W32. | ||
3 | Added check test for triggering poll() on | ||
4 | listen socket. -EG | ||
5 | |||
1 | Thu Feb 4 11:38:11 CET 2016 | 6 | Thu Feb 4 11:38:11 CET 2016 |
2 | Added some buffer overrun protection. | 7 | Added some buffer overrun protection. |
3 | Fixed handling of misformed URI with spaces. -EG | 8 | Fixed handling of misformed URI with spaces. -EG |
diff --git a/src/microhttpd/Makefile.am b/src/microhttpd/Makefile.am index 58284d17..67ec3cd8 100644 --- a/src/microhttpd/Makefile.am +++ b/src/microhttpd/Makefile.am | |||
@@ -141,6 +141,7 @@ endif | |||
141 | 141 | ||
142 | check_PROGRAMS = \ | 142 | check_PROGRAMS = \ |
143 | test_shutdown_select \ | 143 | test_shutdown_select \ |
144 | test_shutdown_poll \ | ||
144 | test_daemon | 145 | test_daemon |
145 | 146 | ||
146 | if HAVE_POSTPROCESSOR | 147 | if HAVE_POSTPROCESSOR |
@@ -154,7 +155,8 @@ TESTS = $(check_PROGRAMS) | |||
154 | 155 | ||
155 | if !HAVE_LISTEN_SHUTDOWN | 156 | if !HAVE_LISTEN_SHUTDOWN |
156 | XFAIL_TESTS = \ | 157 | XFAIL_TESTS = \ |
157 | test_shutdown_select | 158 | test_shutdown_select \ |
159 | test_shutdown_poll | ||
158 | endif | 160 | endif |
159 | 161 | ||
160 | test_daemon_SOURCES = \ | 162 | test_daemon_SOURCES = \ |
@@ -193,3 +195,12 @@ test_shutdown_select_CFLAGS = \ | |||
193 | test_shutdown_select_LDADD = \ | 195 | test_shutdown_select_LDADD = \ |
194 | $(PTHREAD_LIBS) | 196 | $(PTHREAD_LIBS) |
195 | endif | 197 | endif |
198 | |||
199 | test_shutdown_poll_SOURCES = \ | ||
200 | test_shutdown_select.c | ||
201 | if USE_POSIX_THREADS | ||
202 | test_shutdown_poll_CFLAGS = \ | ||
203 | test_shutdown_select_CFLAGS | ||
204 | test_shutdown_poll_LDADD = \ | ||
205 | test_shutdown_select_LDADD | ||
206 | endif | ||
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 @@ | |||
62 | #ifdef HAVE_SYS_SELECT_H | 62 | #ifdef HAVE_SYS_SELECT_H |
63 | #include <sys/select.h> | 63 | #include <sys/select.h> |
64 | #endif /* HAVE_SYS_SELECT_H */ | 64 | #endif /* HAVE_SYS_SELECT_H */ |
65 | #if defined(HAVE_POLL) && defined(HAVE_POLL_H) | ||
66 | #include <poll.h> | ||
67 | #endif /* HAVE_POLL && HAVE_POLL_H */ | ||
65 | #define sock_errno (errno) | 68 | #define sock_errno (errno) |
66 | #endif /* MHD_POSIX_SOCKETS */ | 69 | #endif /* MHD_POSIX_SOCKETS */ |
67 | 70 | ||
71 | #ifdef HAVE_STDBOOL_H | ||
72 | #include <stdbool.h> | ||
73 | #endif /* HAVE_STDBOOL_H */ | ||
74 | |||
68 | #ifndef SOMAXCONN | 75 | #ifndef SOMAXCONN |
69 | #define SOMAXCONN 511 | 76 | #define SOMAXCONN 511 |
70 | #endif /* ! SOMAXCONN */ | 77 | #endif /* ! SOMAXCONN */ |
@@ -73,6 +80,33 @@ | |||
73 | #define SHUT_RDWR SD_BOTH | 80 | #define SHUT_RDWR SD_BOTH |
74 | #endif | 81 | #endif |
75 | 82 | ||
83 | static _MHD_bool check_err; | ||
84 | |||
85 | static _MHD_bool | ||
86 | has_in_name(const char *prog_name, const char *marker) | ||
87 | { | ||
88 | size_t name_pos; | ||
89 | size_t pos; | ||
90 | |||
91 | if (!prog_name || !marker) | ||
92 | return 0; | ||
93 | |||
94 | pos = 0; | ||
95 | name_pos = 0; | ||
96 | while (prog_name[pos]) | ||
97 | { | ||
98 | if ('/' == prog_name[pos]) | ||
99 | name_pos = pos + 1; | ||
100 | #ifdef _WIN32 | ||
101 | else if ('\\' == prog_name[pos]) | ||
102 | name_pos = pos + 1; | ||
103 | #endif /* _WIN32 */ | ||
104 | pos++; | ||
105 | } | ||
106 | if (name_pos == pos) | ||
107 | return !0; | ||
108 | return strstr(prog_name + name_pos, marker) != NULL; | ||
109 | } | ||
76 | 110 | ||
77 | static MHD_socket | 111 | static MHD_socket |
78 | start_socket_listen(int domain) | 112 | start_socket_listen(int domain) |
@@ -190,12 +224,31 @@ select_thread(void* data) | |||
190 | timeout.tv_usec = 0; | 224 | timeout.tv_usec = 0; |
191 | timeout.tv_sec = 7; | 225 | timeout.tv_sec = 7; |
192 | 226 | ||
193 | MHD_SYS_select_(listen_sock + 1, &rs, &ws, NULL, &timeout); | 227 | check_err = (0 > MHD_SYS_select_(listen_sock + 1, &rs, &ws, NULL, &timeout)); |
194 | 228 | ||
195 | return (MHD_THRD_RTRN_TYPE_)0; | 229 | return (MHD_THRD_RTRN_TYPE_)0; |
196 | } | 230 | } |
197 | 231 | ||
198 | 232 | ||
233 | #ifdef HAVE_POLL | ||
234 | MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ | ||
235 | poll_thread(void* data) | ||
236 | { | ||
237 | /* use poll() like in daemon.c */ | ||
238 | struct pollfd p[1]; | ||
239 | MHD_socket listen_sock = *((MHD_socket*)data); | ||
240 | |||
241 | p[0].fd = listen_sock; | ||
242 | p[0].events = POLLIN; | ||
243 | p[0].revents = 0; | ||
244 | |||
245 | check_err = (0 > MHD_sys_poll_ (p, 1, 7000)); | ||
246 | |||
247 | return (MHD_THRD_RTRN_TYPE_)0; | ||
248 | } | ||
249 | #endif /* HAVE_POLL */ | ||
250 | |||
251 | |||
199 | static void | 252 | static void |
200 | local_sleep(unsigned seconds) | 253 | local_sleep(unsigned seconds) |
201 | { | 254 | { |
@@ -217,11 +270,27 @@ main (int argc, char *const *argv) | |||
217 | int i; | 270 | int i; |
218 | time_t start_t, end_t; | 271 | time_t start_t, end_t; |
219 | int result = 0; | 272 | int result = 0; |
220 | 273 | MHD_THRD_RTRN_TYPE_ (MHD_THRD_CALL_SPEC_ *test_func)(void* data); | |
221 | #ifdef MHD_WINSOCK_SOCKETS | 274 | #ifdef MHD_WINSOCK_SOCKETS |
222 | WORD ver_req; | 275 | WORD ver_req; |
223 | WSADATA wsa_data; | 276 | WSADATA wsa_data; |
224 | int err; | 277 | int err; |
278 | #endif /* MHD_WINSOCK_SOCKETS */ | ||
279 | _MHD_bool test_poll; | ||
280 | |||
281 | test_poll = has_in_name(argv[0], "_poll"); | ||
282 | if (!test_poll) | ||
283 | test_func = &select_thread; | ||
284 | else | ||
285 | { | ||
286 | #ifndef HAVE_POLL | ||
287 | return 77; | ||
288 | #else /* ! HAVE_POLL */ | ||
289 | test_func = &poll_thread; | ||
290 | #endif /* ! HAVE_POLL */ | ||
291 | } | ||
292 | |||
293 | #ifdef MHD_WINSOCK_SOCKETS | ||
225 | ver_req = MAKEWORD(2, 2); | 294 | ver_req = MAKEWORD(2, 2); |
226 | 295 | ||
227 | err = WSAStartup(ver_req, &wsa_data); | 296 | err = WSAStartup(ver_req, &wsa_data); |
@@ -239,21 +308,22 @@ main (int argc, char *const *argv) | |||
239 | for (i = 0; i < 5 && result == 0; i++) | 308 | for (i = 0; i < 5 && result == 0; i++) |
240 | { | 309 | { |
241 | MHD_thread_handle_ sel_thrd; | 310 | MHD_thread_handle_ sel_thrd; |
242 | /* fprint f(stdout, "Creating, binding and listening socket...\n"); */ | 311 | /* fprintf(stdout, "Creating, binding and listening socket...\n"); */ |
243 | MHD_socket listen_socket = start_socket_listen (AF_INET); | 312 | MHD_socket listen_socket = start_socket_listen (AF_INET); |
244 | if (MHD_INVALID_SOCKET == listen_socket) | 313 | if (MHD_INVALID_SOCKET == listen_socket) |
245 | return 99; | 314 | return 99; |
246 | 315 | ||
316 | check_err = !0; | ||
247 | /* fprintf (stdout, "Starting select() thread...\n"); */ | 317 | /* fprintf (stdout, "Starting select() thread...\n"); */ |
248 | #if defined(MHD_USE_POSIX_THREADS) | 318 | #if defined(MHD_USE_POSIX_THREADS) |
249 | if (0 != pthread_create (&sel_thrd, NULL, &select_thread, &listen_socket)) | 319 | if (0 != pthread_create (&sel_thrd, NULL, test_func, &listen_socket)) |
250 | { | 320 | { |
251 | MHD_socket_close_ (listen_socket); | 321 | MHD_socket_close_ (listen_socket); |
252 | fprintf (stderr, "Can't start thread\n"); | 322 | fprintf (stderr, "Can't start thread\n"); |
253 | return 99; | 323 | return 99; |
254 | } | 324 | } |
255 | #elif defined(MHD_USE_W32_THREADS) | 325 | #elif defined(MHD_USE_W32_THREADS) |
256 | sel_thrd = (HANDLE)_beginthreadex (NULL, 0, &select_thread, &listen_socket, 0, NULL); | 326 | sel_thrd = (HANDLE)_beginthreadex (NULL, 0, test_func, &listen_socket, 0, NULL); |
257 | if (0 == (sel_thrd)) | 327 | if (0 == (sel_thrd)) |
258 | { | 328 | { |
259 | MHD_socket_close_ (listen_socket); | 329 | MHD_socket_close_ (listen_socket); |
@@ -277,6 +347,12 @@ main (int argc, char *const *argv) | |||
277 | fprintf (stderr, "Can't join select() thread\n"); | 347 | fprintf (stderr, "Can't join select() thread\n"); |
278 | return 99; | 348 | return 99; |
279 | } | 349 | } |
350 | if (check_err) | ||
351 | { | ||
352 | MHD_socket_close_(listen_socket); | ||
353 | fprintf (stderr, "Error in waiting thread\n"); | ||
354 | return 99; | ||
355 | } | ||
280 | end_t = time (NULL); | 356 | end_t = time (NULL); |
281 | /* fprintf (stdout, "Thread finished.\n"); */ | 357 | /* fprintf (stdout, "Thread finished.\n"); */ |
282 | MHD_socket_close_(listen_socket); | 358 | MHD_socket_close_(listen_socket); |