aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-06-22 08:38:48 +0000
committerChristian Grothoff <christian@grothoff.org>2011-06-22 08:38:48 +0000
commit46649e53fe4e61216160a93779017e96a787329c (patch)
tree3ea1d983a9555c7ecd14626d4f2afcd1101dac5e
parenta84334b18d15984b881f8eace7149c5ee9581837 (diff)
downloadlibmicrohttpd-46649e53fe4e61216160a93779017e96a787329c.tar.gz
libmicrohttpd-46649e53fe4e61216160a93779017e96a787329c.zip
improve performance by using shutdown on client sockets instead of poll/select on listen socket
-rw-r--r--ChangeLog7
-rw-r--r--src/daemon/daemon.c49
2 files changed, 33 insertions, 23 deletions
diff --git a/ChangeLog b/ChangeLog
index 833d8f91..ac2d3f4c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
1Wed 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
1Wed Jun 22 10:25:13 CEST 2011 6Wed 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
13Sat Jun 11 13:05:12 CEST 2011 18Sat 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)))