diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-06-22 08:38:48 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-06-22 08:38:48 +0000 |
commit | 46649e53fe4e61216160a93779017e96a787329c (patch) | |
tree | 3ea1d983a9555c7ecd14626d4f2afcd1101dac5e | |
parent | a84334b18d15984b881f8eace7149c5ee9581837 (diff) | |
download | libmicrohttpd-46649e53fe4e61216160a93779017e96a787329c.tar.gz libmicrohttpd-46649e53fe4e61216160a93779017e96a787329c.zip |
improve performance by using shutdown on client sockets instead of poll/select on listen socket
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | src/daemon/daemon.c | 49 |
2 files changed, 33 insertions, 23 deletions
@@ -1,3 +1,8 @@ | |||
1 | Wed Jun 22 10:37:35 CEST 2011 | ||
2 | Removing listen socket from poll/select sets in | ||
3 | MHD_USE_THREAD_PER_CONNECTION mode; using 'shutdown' | ||
4 | on connection sockets to signal termination instead. -CG | ||
5 | |||
1 | Wed Jun 22 10:25:13 CEST 2011 | 6 | Wed Jun 22 10:25:13 CEST 2011 |
2 | Eliminate unnecessary (and badly synchronized) calls to | 7 | Eliminate unnecessary (and badly synchronized) calls to |
3 | MHD_get_timeout in MHD_USE_THREAD_PER_CONNECTION mode. | 8 | MHD_get_timeout in MHD_USE_THREAD_PER_CONNECTION mode. |
@@ -7,7 +12,7 @@ Tue Jun 21 13:54:59 CEST 2011 | |||
7 | Fixing tiny memory leak in SSL code from 'gnutls_priority_init'. | 12 | Fixing tiny memory leak in SSL code from 'gnutls_priority_init'. |
8 | Fixing data race between code doing connection shutdown and | 13 | Fixing data race between code doing connection shutdown and |
9 | connection cleanup. | 14 | connection cleanup. |
10 | Changing code to reduce connection cleanup cost from O(n) to O(1). | 15 | Changing code to reduce connection cleanup cost from O(n) to O(1). |
11 | Cleaning up logging code around 'connection_close_error'. -CG | 16 | Cleaning up logging code around 'connection_close_error'. -CG |
12 | 17 | ||
13 | Sat Jun 11 13:05:12 CEST 2011 | 18 | Sat Jun 11 13:05:12 CEST 2011 |
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c index ee796fd8..4b9049d1 100644 --- a/src/daemon/daemon.c +++ b/src/daemon/daemon.c | |||
@@ -563,14 +563,13 @@ MHD_handle_connection (void *data) | |||
563 | fd_set ws; | 563 | fd_set ws; |
564 | fd_set es; | 564 | fd_set es; |
565 | int max; | 565 | int max; |
566 | int fd; | ||
567 | struct timeval tv; | 566 | struct timeval tv; |
568 | struct timeval *tvp; | 567 | struct timeval *tvp; |
569 | unsigned int timeout; | 568 | unsigned int timeout; |
570 | time_t now; | 569 | time_t now; |
571 | #ifdef HAVE_POLL_H | 570 | #ifdef HAVE_POLL_H |
572 | struct MHD_Pollfd mp; | 571 | struct MHD_Pollfd mp; |
573 | struct pollfd p[2]; | 572 | struct pollfd p[1]; |
574 | #endif | 573 | #endif |
575 | 574 | ||
576 | timeout = con->daemon->connection_timeout; | 575 | timeout = con->daemon->connection_timeout; |
@@ -605,15 +604,7 @@ MHD_handle_connection (void *data) | |||
605 | FD_ZERO (&rs); | 604 | FD_ZERO (&rs); |
606 | FD_ZERO (&ws); | 605 | FD_ZERO (&ws); |
607 | FD_ZERO (&es); | 606 | FD_ZERO (&es); |
608 | if (-1 != (fd = con->daemon->socket_fd)) | 607 | max = 0; |
609 | { | ||
610 | /* we add the listen socket to our read set so | ||
611 | that if the server is shutdown, we notice it */ | ||
612 | max = fd; | ||
613 | FD_SET (fd, &rs); | ||
614 | } | ||
615 | else | ||
616 | max = 0; | ||
617 | MHD_connection_get_fdset (con, &rs, &ws, &es, &max); | 608 | MHD_connection_get_fdset (con, &rs, &ws, &es, &max); |
618 | num_ready = SELECT (max + 1, &rs, &ws, &es, tvp); | 609 | num_ready = SELECT (max + 1, &rs, &ws, &es, tvp); |
619 | if (num_ready < 0) | 610 | if (num_ready < 0) |
@@ -648,20 +639,11 @@ MHD_handle_connection (void *data) | |||
648 | p[0].events |= POLLIN; | 639 | p[0].events |= POLLIN; |
649 | if (mp.events & MHD_POLL_ACTION_OUT) | 640 | if (mp.events & MHD_POLL_ACTION_OUT) |
650 | p[0].events |= POLLOUT; | 641 | p[0].events |= POLLOUT; |
651 | /* we add the listen socket to our read set so | ||
652 | that if the server is shutdown, we notice it */ | ||
653 | |||
654 | fd = con->daemon->socket_fd; | ||
655 | p[1].fd = fd; | ||
656 | p[1].events = 0; /* only care about POLLHUP */ | ||
657 | |||
658 | if (poll (p, | 642 | if (poll (p, |
659 | (fd != -1) ? 2 : 1, | 643 | 1, |
660 | (tvp == NULL) | 644 | (tvp == NULL) |
661 | ? -1 | 645 | ? -1 |
662 | : ((fd != -1) | 646 | : tv.tv_sec * 1000) < 0) |
663 | ? (tv.tv_sec * 1000) | ||
664 | : 0)) < 0) | ||
665 | { | 647 | { |
666 | if (errno == EINTR) | 648 | if (errno == EINTR) |
667 | continue; | 649 | continue; |
@@ -2407,7 +2389,27 @@ close_all_connections (struct MHD_Daemon *daemon) | |||
2407 | struct MHD_Connection *pos; | 2389 | struct MHD_Connection *pos; |
2408 | void *unused; | 2390 | void *unused; |
2409 | int rc; | 2391 | int rc; |
2392 | |||
2393 | /* first, make sure all threads are aware of shutdown; need to | ||
2394 | traverse DLLs in peace... */ | ||
2395 | if (0 != pthread_mutex_lock(&daemon->cleanup_connection_mutex)) | ||
2396 | { | ||
2397 | #if HAVE_MESSAGES | ||
2398 | MHD_DLOG (daemon, "Failed to acquire cleanup mutex\n"); | ||
2399 | #endif | ||
2400 | abort(); | ||
2401 | } | ||
2402 | for (pos = daemon->connections_head; pos != NULL; pos = pos->next) | ||
2403 | SHUTDOWN (pos->socket_fd, SHUT_RDWR); | ||
2404 | if (0 != pthread_mutex_unlock(&daemon->cleanup_connection_mutex)) | ||
2405 | { | ||
2406 | #if HAVE_MESSAGES | ||
2407 | MHD_DLOG (daemon, "Failed to release cleanup mutex\n"); | ||
2408 | #endif | ||
2409 | abort(); | ||
2410 | } | ||
2410 | 2411 | ||
2412 | /* now, collect threads */ | ||
2411 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | 2413 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
2412 | { | 2414 | { |
2413 | while (NULL != (pos = daemon->connections_head)) | 2415 | while (NULL != (pos = daemon->connections_head)) |
@@ -2423,6 +2425,8 @@ close_all_connections (struct MHD_Daemon *daemon) | |||
2423 | pos->thread_joined = MHD_YES; | 2425 | pos->thread_joined = MHD_YES; |
2424 | } | 2426 | } |
2425 | } | 2427 | } |
2428 | |||
2429 | /* now that we're alone, move everyone to cleanup */ | ||
2426 | while (NULL != (pos = daemon->connections_head)) | 2430 | while (NULL != (pos = daemon->connections_head)) |
2427 | { | 2431 | { |
2428 | pos->state = MHD_CONNECTION_CLOSED; | 2432 | pos->state = MHD_CONNECTION_CLOSED; |
@@ -2485,6 +2489,7 @@ MHD_stop_daemon (struct MHD_Daemon *daemon) | |||
2485 | } | 2489 | } |
2486 | free (daemon->worker_pool); | 2490 | free (daemon->worker_pool); |
2487 | 2491 | ||
2492 | /* clean up master threads */ | ||
2488 | if ((0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || | 2493 | if ((0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || |
2489 | ((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) | 2494 | ((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) |
2490 | && (0 == daemon->worker_pool_size))) | 2495 | && (0 == daemon->worker_pool_size))) |