diff options
Diffstat (limited to 'src/daemon/daemon.c')
-rw-r--r-- | src/daemon/daemon.c | 119 |
1 files changed, 99 insertions, 20 deletions
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c index e050d585..b85c8510 100644 --- a/src/daemon/daemon.c +++ b/src/daemon/daemon.c | |||
@@ -1333,18 +1333,19 @@ MHD_select (struct MHD_Daemon *daemon, | |||
1333 | } | 1333 | } |
1334 | 1334 | ||
1335 | 1335 | ||
1336 | #ifdef HAVE_POLL_H | ||
1336 | /** | 1337 | /** |
1337 | * Poll for new connection. | 1338 | * Process all of our connections and possibly the server |
1339 | * socket using 'poll'. | ||
1338 | * | 1340 | * |
1339 | * @param daemon daemon to run poll loop for | 1341 | * @param daemon daemon to run poll loop for |
1340 | * @param may_block YES if blocking, NO if non-blocking | 1342 | * @param may_block YES if blocking, NO if non-blocking |
1341 | * @return MHD_NO on serious errors, MHD_YES on success | 1343 | * @return MHD_NO on serious errors, MHD_YES on success |
1342 | */ | 1344 | */ |
1343 | static int | 1345 | static int |
1344 | MHD_poll (struct MHD_Daemon *daemon, | 1346 | MHD_poll_all (struct MHD_Daemon *daemon, |
1345 | int may_block) | 1347 | int may_block) |
1346 | { | 1348 | { |
1347 | #ifdef HAVE_POLL_H | ||
1348 | unsigned int num_connections; | 1349 | unsigned int num_connections; |
1349 | struct MHD_Connection *pos; | 1350 | struct MHD_Connection *pos; |
1350 | 1351 | ||
@@ -1361,11 +1362,20 @@ MHD_poll (struct MHD_Daemon *daemon, | |||
1361 | unsigned MHD_LONG_LONG ltimeout; | 1362 | unsigned MHD_LONG_LONG ltimeout; |
1362 | unsigned int i; | 1363 | unsigned int i; |
1363 | int timeout; | 1364 | int timeout; |
1365 | unsigned int poll_server; | ||
1364 | 1366 | ||
1365 | memset (p, 0, sizeof (p)); | 1367 | memset (p, 0, sizeof (p)); |
1366 | p[0].fd = daemon->socket_fd; | 1368 | if ( (daemon->max_connections == 0) && (daemon->socket_fd != -1) ) |
1367 | p[0].events = POLLIN; | 1369 | { |
1368 | p[0].revents = 0; | 1370 | poll_server = 1; |
1371 | p[0].fd = daemon->socket_fd; | ||
1372 | p[0].events = POLLIN; | ||
1373 | p[0].revents = 0; | ||
1374 | } | ||
1375 | else | ||
1376 | { | ||
1377 | poll_server = 0; | ||
1378 | } | ||
1369 | if (may_block == MHD_NO) | 1379 | if (may_block == MHD_NO) |
1370 | timeout = 0; | 1380 | timeout = 0; |
1371 | else if (MHD_YES != MHD_get_timeout (daemon, <imeout)) | 1381 | else if (MHD_YES != MHD_get_timeout (daemon, <imeout)) |
@@ -1379,22 +1389,23 @@ MHD_poll (struct MHD_Daemon *daemon, | |||
1379 | { | 1389 | { |
1380 | memset(&mp, 0, sizeof (struct MHD_Pollfd)); | 1390 | memset(&mp, 0, sizeof (struct MHD_Pollfd)); |
1381 | MHD_connection_get_pollfd (pos, &mp); | 1391 | MHD_connection_get_pollfd (pos, &mp); |
1382 | p[1+i].fd = mp.fd; | 1392 | p[poll_server+i].fd = mp.fd; |
1383 | if (mp.events & MHD_POLL_ACTION_IN) | 1393 | if (mp.events & MHD_POLL_ACTION_IN) |
1384 | p[1+i].events |= POLLIN; | 1394 | p[poll_server+i].events |= POLLIN; |
1385 | if (mp.events & MHD_POLL_ACTION_OUT) | 1395 | if (mp.events & MHD_POLL_ACTION_OUT) |
1386 | p[1+i].events |= POLLOUT; | 1396 | p[poll_server+i].events |= POLLOUT; |
1387 | i++; | 1397 | i++; |
1388 | pos = pos->next; | 1398 | pos = pos->next; |
1389 | } | 1399 | } |
1390 | if (poll (p, 1 + num_connections, timeout) < 0) { | 1400 | if (poll (p, poll_server + num_connections, timeout) < 0) |
1391 | if (errno == EINTR) | 1401 | { |
1392 | return MHD_YES; | 1402 | if (errno == EINTR) |
1403 | return MHD_YES; | ||
1393 | #if HAVE_MESSAGES | 1404 | #if HAVE_MESSAGES |
1394 | MHD_DLOG (daemon, "poll failed: %s\n", STRERROR (errno)); | 1405 | MHD_DLOG (daemon, "poll failed: %s\n", STRERROR (errno)); |
1395 | #endif | 1406 | #endif |
1396 | return MHD_NO; | 1407 | return MHD_NO; |
1397 | } | 1408 | } |
1398 | /* handle shutdown cases */ | 1409 | /* handle shutdown cases */ |
1399 | if (daemon->shutdown == MHD_YES) | 1410 | if (daemon->shutdown == MHD_YES) |
1400 | return MHD_NO; | 1411 | return MHD_NO; |
@@ -1408,23 +1419,91 @@ MHD_poll (struct MHD_Daemon *daemon, | |||
1408 | if (i >= num_connections) | 1419 | if (i >= num_connections) |
1409 | break; /* connection list changed somehow, retry later ... */ | 1420 | break; /* connection list changed somehow, retry later ... */ |
1410 | MHD_connection_get_pollfd (pos, &mp); | 1421 | MHD_connection_get_pollfd (pos, &mp); |
1411 | if (p[1+i].fd != mp.fd) | 1422 | if (p[poll_server+i].fd != mp.fd) |
1412 | break; /* fd mismatch, something else happened, retry later ... */ | 1423 | break; /* fd mismatch, something else happened, retry later ... */ |
1413 | 1424 | ||
1414 | /* normal handling */ | 1425 | /* normal handling */ |
1415 | if (0 != (p[1+i].revents & POLLIN)) | 1426 | if (0 != (p[poll_server+i].revents & POLLIN)) |
1416 | pos->read_handler (pos); | 1427 | pos->read_handler (pos); |
1417 | if (0 != (p[1+i].revents & POLLOUT)) | 1428 | if (0 != (p[poll_server+i].revents & POLLOUT)) |
1418 | pos->write_handler (pos); | 1429 | pos->write_handler (pos); |
1419 | if (pos->socket_fd != -1) | 1430 | if (pos->socket_fd != -1) |
1420 | pos->idle_handler (pos); | 1431 | pos->idle_handler (pos); |
1421 | i++; | 1432 | i++; |
1422 | pos = pos->next; | 1433 | pos = pos->next; |
1423 | } | 1434 | } |
1424 | if (0 != (p[0].revents & POLLIN)) | 1435 | if ( (1 == poll_server) && |
1436 | (0 != (p[0].revents & POLLIN)) ) | ||
1425 | MHD_accept_connection (daemon); | 1437 | MHD_accept_connection (daemon); |
1426 | } | 1438 | } |
1427 | return MHD_YES; | 1439 | return MHD_YES; |
1440 | } | ||
1441 | |||
1442 | |||
1443 | /** | ||
1444 | * Process only the listen socket using 'poll'. | ||
1445 | * | ||
1446 | * @param daemon daemon to run poll loop for | ||
1447 | * @param may_block YES if blocking, NO if non-blocking | ||
1448 | * @return MHD_NO on serious errors, MHD_YES on success | ||
1449 | */ | ||
1450 | static int | ||
1451 | MHD_poll_listen_socket (struct MHD_Daemon *daemon, | ||
1452 | int may_block) | ||
1453 | { | ||
1454 | struct pollfd p; | ||
1455 | unsigned MHD_LONG_LONG ltimeout; | ||
1456 | int timeout; | ||
1457 | |||
1458 | memset (&p, 0, sizeof (p)); | ||
1459 | p.fd = daemon->socket_fd; | ||
1460 | p.events = POLLIN; | ||
1461 | p.revents = 0; | ||
1462 | if (may_block == MHD_NO) | ||
1463 | timeout = 0; | ||
1464 | else if (MHD_YES != MHD_get_timeout (daemon, <imeout)) | ||
1465 | timeout = -1; | ||
1466 | else | ||
1467 | timeout = (ltimeout > INT_MAX) ? INT_MAX : (int) ltimeout; | ||
1468 | if (poll (&p, 1, timeout) < 0) | ||
1469 | { | ||
1470 | if (errno == EINTR) | ||
1471 | return MHD_YES; | ||
1472 | #if HAVE_MESSAGES | ||
1473 | MHD_DLOG (daemon, "poll failed: %s\n", STRERROR (errno)); | ||
1474 | #endif | ||
1475 | return MHD_NO; | ||
1476 | } | ||
1477 | /* handle shutdown cases */ | ||
1478 | if (daemon->shutdown == MHD_YES) | ||
1479 | return MHD_NO; | ||
1480 | if (daemon->socket_fd < 0) | ||
1481 | return MHD_YES; | ||
1482 | if (0 != (p.revents & POLLIN)) | ||
1483 | MHD_accept_connection (daemon); | ||
1484 | return MHD_YES; | ||
1485 | } | ||
1486 | #endif | ||
1487 | |||
1488 | |||
1489 | /** | ||
1490 | * Do 'poll'-based processing. | ||
1491 | * | ||
1492 | * @param daemon daemon to run poll loop for | ||
1493 | * @param may_block YES if blocking, NO if non-blocking | ||
1494 | * @return MHD_NO on serious errors, MHD_YES on success | ||
1495 | */ | ||
1496 | static int | ||
1497 | MHD_poll (struct MHD_Daemon *daemon, | ||
1498 | int may_block) | ||
1499 | { | ||
1500 | #ifdef HAVE_POLL_H | ||
1501 | if (daemon->shutdown == MHD_YES) | ||
1502 | return MHD_NO; | ||
1503 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | ||
1504 | return MHD_poll_all (daemon, may_block); | ||
1505 | else | ||
1506 | return MHD_poll_listen_socket (daemon, may_block); | ||
1428 | #else | 1507 | #else |
1429 | return MHD_NO; | 1508 | return MHD_NO; |
1430 | #endif | 1509 | #endif |