diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2016-10-26 21:43:15 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2016-10-27 22:45:07 +0300 |
commit | fd0ceb70580e4fc7096720e123a25970b69631d9 (patch) | |
tree | c0282904364c4433700aae7b95969bb7313a2156 | |
parent | 92c4de41465e1120129584bce6981034166f762a (diff) | |
download | libmicrohttpd-fd0ceb70580e4fc7096720e123a25970b69631d9.tar.gz libmicrohttpd-fd0ceb70580e4fc7096720e123a25970b69631d9.zip |
MHD_stop_daemon(): structurize closing logic
-rw-r--r-- | src/microhttpd/daemon.c | 181 |
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 | */ | ||
102 | static void | ||
103 | close_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 | ||