aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2016-10-26 21:43:15 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2016-10-27 22:45:07 +0300
commitfd0ceb70580e4fc7096720e123a25970b69631d9 (patch)
treec0282904364c4433700aae7b95969bb7313a2156
parent92c4de41465e1120129584bce6981034166f762a (diff)
downloadlibmicrohttpd-fd0ceb70580e4fc7096720e123a25970b69631d9.tar.gz
libmicrohttpd-fd0ceb70580e4fc7096720e123a25970b69631d9.zip
MHD_stop_daemon(): structurize closing logic
-rw-r--r--src/microhttpd/daemon.c181
1 files changed, 88 insertions, 93 deletions
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index e176fae4..210b929f 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -90,6 +90,17 @@
90 */ 90 */
91#define DEBUG_CONNECT MHD_NO 91#define DEBUG_CONNECT MHD_NO
92 92
93/* Forward declarations. */
94/**
95 * Close all connections for the daemon.
96 * Must only be called when MHD_Daemon::shutdown was set to MHD_YES.
97 * @remark To be called only from thread that process
98 * daemon's select()/poll()/etc.
99 *
100 * @param daemon daemon to close down
101 */
102static void
103close_all_connections (struct MHD_Daemon *daemon);
93 104
94/** 105/**
95 * Default implementation of the panic function, 106 * Default implementation of the panic function,
@@ -5510,105 +5521,101 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
5510#endif 5521#endif
5511 if (0 != (MHD_USE_SUSPEND_RESUME & daemon->options)) 5522 if (0 != (MHD_USE_SUSPEND_RESUME & daemon->options))
5512 resume_suspended_connections (daemon); 5523 resume_suspended_connections (daemon);
5524
5513 daemon->shutdown = MHD_YES; 5525 daemon->shutdown = MHD_YES;
5514 fd = daemon->socket_fd; 5526 fd = daemon->socket_fd;
5515 daemon->socket_fd = MHD_INVALID_SOCKET; 5527 daemon->socket_fd = MHD_INVALID_SOCKET;
5516 /* Prepare workers for shutdown */ 5528
5517 if (NULL != daemon->worker_pool) 5529 if ( (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) ||
5518 { 5530 (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) )
5519 /* #MHD_USE_NO_LISTEN_SOCKET disables thread pools, hence we need to check */
5520 for (i = 0; i < daemon->worker_pool_size; ++i)
5521 {
5522 daemon->worker_pool[i].shutdown = MHD_YES;
5523 daemon->worker_pool[i].socket_fd = MHD_INVALID_SOCKET;
5524#ifdef EPOLL_SUPPORT
5525 if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
5526 (-1 != daemon->worker_pool[i].epoll_fd) &&
5527 (MHD_INVALID_SOCKET == fd) )
5528 epoll_shutdown (&daemon->worker_pool[i]);
5529#endif
5530 }
5531 }
5532 if (MHD_ITC_IS_VALID_(daemon->itc))
5533 { 5531 {
5534 if (! MHD_itc_activate_ (daemon->itc, "e")) 5532 /* Separate thread(s) is used for select()/poll()/etc. */
5535 MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel")); 5533 if (NULL != daemon->worker_pool)
5536 } 5534 {
5535 /* Pool of workers is used. */
5536 /* Initiate shutdown process in wokers. */
5537 for (i = 0; i < daemon->worker_pool_size; ++i)
5538 {
5539 daemon->worker_pool[i].shutdown = MHD_YES;
5540 daemon->worker_pool[i].socket_fd = MHD_INVALID_SOCKET;
5541 if (MHD_ITC_IS_VALID_(daemon->worker_pool[i].itc))
5542 {
5543 if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, "e"))
5544 MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel."));
5545 }
5537#ifdef HAVE_LISTEN_SHUTDOWN 5546#ifdef HAVE_LISTEN_SHUTDOWN
5538 else 5547 else if (MHD_INVALID_SOCKET != fd)
5539 { 5548 {
5540 /* fd might be MHD_INVALID_SOCKET here due to 'MHD_quiesce_daemon' */ 5549 /* fd might be MHD_INVALID_SOCKET here due to 'MHD_quiesce_daemon' */
5541 if ( (MHD_INVALID_SOCKET != fd) && 5550 /* No problem if shutdown will be called several times for the same socket. */
5542 (0 == (daemon->options & MHD_USE_ITC)) ) 5551 (void) shutdown (fd, SHUT_RDWR);
5543 (void) shutdown (fd, 5552 }
5544 SHUT_RDWR);
5545 }
5546#endif
5547#ifdef EPOLL_SUPPORT
5548 if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
5549 (-1 != daemon->epoll_fd) &&
5550 (MHD_INVALID_SOCKET == fd) )
5551 epoll_shutdown (daemon);
5552#endif
5553
5554#if DEBUG_CLOSE
5555#ifdef HAVE_MESSAGES
5556 MHD_DLOG (daemon,
5557 _("MHD listen socket shutdown\n"));
5558#endif
5559#endif 5553#endif
5560 5554 }
5561 5555 /* Start harvesting. */
5562 /* Signal workers to stop and clean them up */ 5556 for (i = 0; i < daemon->worker_pool_size; ++i)
5563 if (NULL != daemon->worker_pool) 5557 {
5564 { 5558 if (! MHD_join_thread_ (daemon->worker_pool[i].pid))
5565 /* MHD_USE_NO_LISTEN_SOCKET disables thread pools, hence we need to check */ 5559 MHD_PANIC (_("Failed to join a thread\n"));
5566 for (i = 0; i < daemon->worker_pool_size; ++i)
5567 {
5568 if (MHD_ITC_IS_VALID_(daemon->worker_pool[i].itc))
5569 {
5570 if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, "e"))
5571 MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel."));
5572 }
5573 if (! MHD_join_thread_ (daemon->worker_pool[i].pid))
5574 MHD_PANIC (_("Failed to join a thread\n"));
5575 MHD_mutex_destroy_chk_ (&daemon->worker_pool[i].cleanup_connection_mutex);
5576#ifdef EPOLL_SUPPORT 5560#ifdef EPOLL_SUPPORT
5577 if (-1 != daemon->worker_pool[i].epoll_fd) 5561 if (-1 != daemon->worker_pool[i].epoll_fd)
5578 MHD_fd_close_chk_ (daemon->worker_pool[i].epoll_fd); 5562 MHD_fd_close_chk_ (daemon->worker_pool[i].epoll_fd);
5579#if HTTPS_SUPPORT 5563#if HTTPS_SUPPORT
5580 if (-1 != daemon->worker_pool[i].epoll_upgrade_fd) 5564 if (-1 != daemon->worker_pool[i].epoll_upgrade_fd)
5581 MHD_fd_close_chk_ (daemon->worker_pool[i].epoll_upgrade_fd); 5565 MHD_fd_close_chk_ (daemon->worker_pool[i].epoll_upgrade_fd);
5582#endif 5566#endif
5583#endif 5567#endif
5584 /* Individual ITCs are always used */
5585 if (1)
5586 {
5587 if (MHD_ITC_IS_VALID_ (daemon->worker_pool[i].itc) ) 5568 if (MHD_ITC_IS_VALID_ (daemon->worker_pool[i].itc) )
5588 { 5569 MHD_itc_destroy_chk_ (daemon->worker_pool[i].itc);
5589 MHD_itc_destroy_chk_ (daemon->worker_pool[i].itc); 5570 MHD_mutex_destroy_chk_ (&daemon->worker_pool[i].cleanup_connection_mutex);
5590 } 5571 }
5591 } 5572 free (daemon->worker_pool);
5592 } 5573 }
5593 free (daemon->worker_pool); 5574 else
5575 {
5576 /* Single internal thread is used for select()/poll()/etc. */
5577 if (MHD_ITC_IS_VALID_(daemon->itc))
5578 {
5579 if (! MHD_itc_activate_ (daemon->itc, "e"))
5580 MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel"));
5581 }
5582#ifdef HAVE_LISTEN_SHUTDOWN
5583 else
5584 {
5585 /* fd might be MHD_INVALID_SOCKET here due to 'MHD_quiesce_daemon' */
5586 if (MHD_INVALID_SOCKET != fd)
5587 (void) shutdown (fd, SHUT_RDWR);
5588 }
5589#endif
5590 if (! MHD_join_thread_ (daemon->pid))
5591 {
5592 MHD_PANIC (_("Failed to join a thread\n"));
5593 }
5594 }
5594 } 5595 }
5595 else 5596 else
5596 { 5597 {
5597 /* clean up master threads */ 5598 /* Internal threads are not used for select()/poll()/etc. */
5598 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || 5599 close_all_connections (daemon);
5599 ( (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) &&
5600 (0 == daemon->worker_pool_size) ) )
5601 {
5602 if (! MHD_join_thread_ (daemon->pid))
5603 {
5604 MHD_PANIC (_("Failed to join a thread\n"));
5605 }
5606 }
5607 } 5600 }
5608 close_all_connections (daemon); 5601
5609 if (MHD_INVALID_SOCKET != fd) 5602 if (MHD_INVALID_SOCKET != fd)
5610 MHD_socket_close_chk_ (fd); 5603 MHD_socket_close_chk_ (fd);
5611 5604
5605 if (MHD_ITC_IS_VALID_ (daemon->itc))
5606 MHD_itc_destroy_chk_ (daemon->itc);
5607
5608#ifdef EPOLL_SUPPORT
5609 if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
5610 (-1 != daemon->epoll_fd) )
5611 MHD_socket_close_chk_ (daemon->epoll_fd);
5612#if HTTPS_SUPPORT
5613 if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
5614 (-1 != daemon->epoll_upgrade_fd) )
5615 MHD_socket_close_chk_ (daemon->epoll_upgrade_fd);
5616#endif
5617#endif
5618
5612 /* TLS clean up */ 5619 /* TLS clean up */
5613#if HTTPS_SUPPORT 5620#if HTTPS_SUPPORT
5614 if (MHD_YES == daemon->have_dhparams) 5621 if (MHD_YES == daemon->have_dhparams)
@@ -5623,16 +5630,6 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
5623 gnutls_certificate_free_credentials (daemon->x509_cred); 5630 gnutls_certificate_free_credentials (daemon->x509_cred);
5624 } 5631 }
5625#endif 5632#endif
5626#ifdef EPOLL_SUPPORT
5627 if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
5628 (-1 != daemon->epoll_fd) )
5629 MHD_socket_close_chk_ (daemon->epoll_fd);
5630#if HTTPS_SUPPORT
5631 if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
5632 (-1 != daemon->epoll_upgrade_fd) )
5633 MHD_socket_close_chk_ (daemon->epoll_upgrade_fd);
5634#endif
5635#endif
5636 5633
5637#ifdef DAUTH_SUPPORT 5634#ifdef DAUTH_SUPPORT
5638 free (daemon->nnc); 5635 free (daemon->nnc);
@@ -5641,8 +5638,6 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
5641 MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); 5638 MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
5642 MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex); 5639 MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
5643 5640
5644 if (MHD_ITC_IS_VALID_(daemon->itc))
5645 MHD_itc_destroy_chk_ (daemon->itc);
5646 free (daemon); 5641 free (daemon);
5647} 5642}
5648 5643