aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2023-11-23 13:43:34 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2023-11-24 16:08:31 +0300
commit1070d24aa6a3a569e77618ddbddddca90e0b6d0e (patch)
tree403c52b857ab2f6b119653861f98cb77575ffa76
parent7d7d9bc6b18e7aafeb4b01b13554bac4674221f4 (diff)
downloadlibmicrohttpd-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.c123
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;
782static pthread_t pt_client; 782static 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 */
787static volatile bool done; 787static volatile bool client_done;
788
789/**
790 * Flag set to true once the app is finished.
791 */
792static volatile bool app_done;
788 793
789 794
790static const char * 795static 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,
1285static void 1291static void
1286run_mhd_select_loop (struct MHD_Daemon *daemon) 1292run_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}