diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2023-11-23 13:43:34 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2023-11-24 16:08:31 +0300 |
commit | 1070d24aa6a3a569e77618ddbddddca90e0b6d0e (patch) | |
tree | 403c52b857ab2f6b119653861f98cb77575ffa76 | |
parent | 7d7d9bc6b18e7aafeb4b01b13554bac4674221f4 (diff) | |
download | libmicrohttpd-1070d24aa6a3a569e77618ddbddddca90e0b6d0e.tar.gz libmicrohttpd-1070d24aa6a3a569e77618ddbddddca90e0b6d0e.zip |
test_upgrade: fixed timeout value for external select
Now test properly uses MHD-provided timeout value. This should detect
problems if wrong timeout is reported for external polling modes.
-rw-r--r-- | src/microhttpd/test_upgrade.c | 123 |
1 files changed, 91 insertions, 32 deletions
diff --git a/src/microhttpd/test_upgrade.c b/src/microhttpd/test_upgrade.c index f21c145a..d48c2977 100644 --- a/src/microhttpd/test_upgrade.c +++ b/src/microhttpd/test_upgrade.c | |||
@@ -782,9 +782,14 @@ static struct wr_socket *volatile usock; | |||
782 | static pthread_t pt_client; | 782 | static pthread_t pt_client; |
783 | 783 | ||
784 | /** | 784 | /** |
785 | * Flag set to 1 once the test is finished. | 785 | * Flag set to true once the client is finished. |
786 | */ | 786 | */ |
787 | static volatile bool done; | 787 | static volatile bool client_done; |
788 | |||
789 | /** | ||
790 | * Flag set to true once the app is finished. | ||
791 | */ | ||
792 | static volatile bool app_done; | ||
788 | 793 | ||
789 | 794 | ||
790 | static const char * | 795 | static const char * |
@@ -1098,6 +1103,7 @@ run_usock (void *cls) | |||
1098 | MHD_UPGRADE_ACTION_CLOSE); | 1103 | MHD_UPGRADE_ACTION_CLOSE); |
1099 | free (usock); | 1104 | free (usock); |
1100 | usock = NULL; | 1105 | usock = NULL; |
1106 | app_done = true; | ||
1101 | return NULL; | 1107 | return NULL; |
1102 | } | 1108 | } |
1103 | 1109 | ||
@@ -1123,7 +1129,7 @@ run_usock_client (void *cls) | |||
1123 | recv_all_stext (sock, | 1129 | recv_all_stext (sock, |
1124 | "Finished"); | 1130 | "Finished"); |
1125 | wr_close (sock); | 1131 | wr_close (sock); |
1126 | done = true; | 1132 | client_done = true; |
1127 | return NULL; | 1133 | return NULL; |
1128 | } | 1134 | } |
1129 | 1135 | ||
@@ -1285,20 +1291,45 @@ ahc_upgrade (void *cls, | |||
1285 | static void | 1291 | static void |
1286 | run_mhd_select_loop (struct MHD_Daemon *daemon) | 1292 | run_mhd_select_loop (struct MHD_Daemon *daemon) |
1287 | { | 1293 | { |
1288 | fd_set rs; | 1294 | const time_t start_time = time (NULL); |
1289 | fd_set ws; | 1295 | bool connection_was_accepted; |
1290 | fd_set es; | 1296 | bool connection_has_finished; |
1291 | MHD_socket max_fd; | ||
1292 | uint64_t to64; | ||
1293 | struct timeval tv; | ||
1294 | 1297 | ||
1295 | while (! done) | 1298 | connection_was_accepted = false; |
1299 | connection_has_finished = false; | ||
1300 | while (1) | ||
1296 | { | 1301 | { |
1302 | fd_set rs; | ||
1303 | fd_set ws; | ||
1304 | fd_set es; | ||
1305 | MHD_socket max_fd; | ||
1306 | struct timeval tv; | ||
1307 | uint64_t to64; | ||
1308 | bool has_mhd_timeout; | ||
1309 | const union MHD_DaemonInfo *pdinfo; | ||
1310 | |||
1297 | FD_ZERO (&rs); | 1311 | FD_ZERO (&rs); |
1298 | FD_ZERO (&ws); | 1312 | FD_ZERO (&ws); |
1299 | FD_ZERO (&es); | 1313 | FD_ZERO (&es); |
1300 | max_fd = MHD_INVALID_SOCKET; | 1314 | max_fd = MHD_INVALID_SOCKET; |
1301 | to64 = 1000; | 1315 | |
1316 | if (time (NULL) - start_time > ((time_t) test_timeout)) | ||
1317 | mhdErrorExitDesc ("Test timeout"); | ||
1318 | |||
1319 | pdinfo = MHD_get_daemon_info (daemon, MHD_DAEMON_INFO_CURRENT_CONNECTIONS); | ||
1320 | |||
1321 | if (NULL == pdinfo) | ||
1322 | mhdErrorExitDesc ("MHD_get_daemon_info() failed"); | ||
1323 | |||
1324 | if (0 != pdinfo->num_connections) | ||
1325 | connection_was_accepted = true; | ||
1326 | else | ||
1327 | { | ||
1328 | if (connection_was_accepted) | ||
1329 | connection_has_finished = true; | ||
1330 | } | ||
1331 | if (connection_has_finished) | ||
1332 | return; | ||
1302 | 1333 | ||
1303 | if (MHD_YES != | 1334 | if (MHD_YES != |
1304 | MHD_get_fdset (daemon, | 1335 | MHD_get_fdset (daemon, |
@@ -1307,31 +1338,52 @@ run_mhd_select_loop (struct MHD_Daemon *daemon) | |||
1307 | &es, | 1338 | &es, |
1308 | &max_fd)) | 1339 | &max_fd)) |
1309 | mhdErrorExitDesc ("MHD_get_fdset() failed"); | 1340 | mhdErrorExitDesc ("MHD_get_fdset() failed"); |
1310 | (void) MHD_get_timeout64 (daemon, | 1341 | has_mhd_timeout = (MHD_NO != MHD_get_timeout64 (daemon, |
1311 | &to64); | 1342 | &to64)); |
1312 | if (1000 < to64) | 1343 | if (has_mhd_timeout) |
1313 | to64 = 1000; | 1344 | { |
1314 | #if ! defined(_WIN32) || defined(__CYGWIN__) | 1345 | #if ! defined(_WIN32) || defined(__CYGWIN__) |
1315 | tv.tv_sec = (time_t) (to64 / 1000); | 1346 | tv.tv_sec = (time_t) (to64 / 1000); |
1316 | #else /* Native W32 */ | 1347 | #else /* Native W32 */ |
1317 | tv.tv_sec = (long) (to64 / 1000); | 1348 | tv.tv_sec = (long) (to64 / 1000); |
1318 | #endif /* Native W32 */ | 1349 | #endif /* Native W32 */ |
1319 | tv.tv_usec = (long) (1000 * (to64 % 1000)); | 1350 | tv.tv_usec = (long) (1000 * (to64 % 1000)); |
1320 | if (0 > MHD_SYS_select_ (max_fd + 1, | 1351 | } |
1321 | &rs, | 1352 | else |
1322 | &ws, | ||
1323 | &es, | ||
1324 | &tv)) | ||
1325 | { | 1353 | { |
1326 | #ifdef MHD_POSIX_SOCKETS | 1354 | #if ! defined(_WIN32) || defined(__CYGWIN__) |
1327 | if (EINTR != errno) | 1355 | tv.tv_sec = (time_t) test_timeout; |
1328 | externalErrorExitDesc ("Unexpected select() error"); | 1356 | #else /* Native W32 */ |
1329 | #else | 1357 | tv.tv_sec = (long) test_timeout; |
1330 | if ((WSAEINVAL != WSAGetLastError ()) || | 1358 | #endif /* Native W32 */ |
1331 | (0 != rs.fd_count) || (0 != ws.fd_count) || (0 != es.fd_count) ) | 1359 | tv.tv_usec = 0; |
1332 | externalErrorExitDesc ("Unexpected select() error"); | 1360 | } |
1361 | |||
1362 | #ifdef MHD_WINSOCK_SOCKETS | ||
1363 | if ((0 == rs.fd_count) && (0 == ws.fd_count) && (0 != es.fd_count)) | ||
1333 | Sleep ((DWORD) (tv.tv_sec * 1000 + tv.tv_usec / 1000)); | 1364 | Sleep ((DWORD) (tv.tv_sec * 1000 + tv.tv_usec / 1000)); |
1365 | else /* Combined with the next 'if' */ | ||
1334 | #endif | 1366 | #endif |
1367 | if (1) | ||
1368 | { | ||
1369 | int sel_res; | ||
1370 | sel_res = MHD_SYS_select_ (max_fd + 1, | ||
1371 | &rs, | ||
1372 | &ws, | ||
1373 | &es, | ||
1374 | &tv); | ||
1375 | if (0 == sel_res) | ||
1376 | { | ||
1377 | if (! has_mhd_timeout) | ||
1378 | mhdErrorExitDesc ("Timeout waiting for data on sockets"); | ||
1379 | } | ||
1380 | else if (0 > sel_res) | ||
1381 | { | ||
1382 | #ifdef MHD_POSIX_SOCKETS | ||
1383 | if (EINTR != errno) | ||
1384 | #endif /* MHD_POSIX_SOCKETS */ | ||
1385 | mhdErrorExitDesc ("Unexpected select() error"); | ||
1386 | } | ||
1335 | } | 1387 | } |
1336 | MHD_run_from_select (daemon, | 1388 | MHD_run_from_select (daemon, |
1337 | &rs, | 1389 | &rs, |
@@ -1380,7 +1432,7 @@ run_mhd_epoll_loop (struct MHD_Daemon *daemon) | |||
1380 | if (NULL == di) | 1432 | if (NULL == di) |
1381 | mhdErrorExitDesc ("MHD_get_daemon_info() failed"); | 1433 | mhdErrorExitDesc ("MHD_get_daemon_info() failed"); |
1382 | ep = di->listen_fd; | 1434 | ep = di->listen_fd; |
1383 | while (! done) | 1435 | while (! client_done) |
1384 | { | 1436 | { |
1385 | FD_ZERO (&rs); | 1437 | FD_ZERO (&rs); |
1386 | to64 = 1000; | 1438 | to64 = 1000; |
@@ -1465,7 +1517,8 @@ test_upgrade (unsigned int flags, | |||
1465 | pid_t pid = -1; | 1517 | pid_t pid = -1; |
1466 | #endif /* HTTPS_SUPPORT && HAVE_FORK && HAVE_WAITPID */ | 1518 | #endif /* HTTPS_SUPPORT && HAVE_FORK && HAVE_WAITPID */ |
1467 | 1519 | ||
1468 | done = false; | 1520 | client_done = false; |
1521 | app_done = false; | ||
1469 | 1522 | ||
1470 | if (! test_tls) | 1523 | if (! test_tls) |
1471 | d = MHD_start_daemon (flags | MHD_USE_ERROR_LOG | MHD_ALLOW_UPGRADE | 1524 | d = MHD_start_daemon (flags | MHD_USE_ERROR_LOG | MHD_ALLOW_UPGRADE |
@@ -1564,6 +1617,12 @@ test_upgrade (unsigned int flags, | |||
1564 | externalErrorExitDesc ("waitpid() failed"); | 1617 | externalErrorExitDesc ("waitpid() failed"); |
1565 | } | 1618 | } |
1566 | #endif /* HTTPS_SUPPORT && HAVE_FORK && HAVE_WAITPID */ | 1619 | #endif /* HTTPS_SUPPORT && HAVE_FORK && HAVE_WAITPID */ |
1620 | if (! client_done) | ||
1621 | externalErrorExitDesc ("The client thread has not signalled " \ | ||
1622 | "successful finish"); | ||
1623 | if (! app_done) | ||
1624 | externalErrorExitDesc ("The application thread has not signalled " \ | ||
1625 | "successful finish"); | ||
1567 | MHD_stop_daemon (d); | 1626 | MHD_stop_daemon (d); |
1568 | return 0; | 1627 | return 0; |
1569 | } | 1628 | } |