aboutsummaryrefslogtreecommitdiff
path: root/src/lib/daemon_destroy.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/daemon_destroy.c')
-rw-r--r--src/lib/daemon_destroy.c178
1 files changed, 178 insertions, 0 deletions
diff --git a/src/lib/daemon_destroy.c b/src/lib/daemon_destroy.c
new file mode 100644
index 00000000..b1743088
--- /dev/null
+++ b/src/lib/daemon_destroy.c
@@ -0,0 +1,178 @@
1/*
2 This file is part of libmicrohttpd
3 Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18*/
19
20/**
21 * @file lib/daemon_destroy.c
22 * @brief main functions to destroy a daemon
23 * @author Christian Grothoff
24 */
25#include "internal.h"
26
27/* TODO: migrate logic below! */
28
29/**
30 * Shutdown and destroy an HTTP daemon.
31 *
32 * @param daemon daemon to stop
33 * @ingroup event
34 */
35void
36MHD_daemon_destroy (struct MHD_Daemon *daemon)
37{
38 MHD_socket fd;
39 unsigned int i;
40
41 if (NULL == daemon)
42 return;
43 daemon->shutdown = true;
44 if (daemon->was_quiesced)
45 fd = MHD_INVALID_SOCKET; /* Do not use FD if daemon was quiesced */
46 else
47 fd = daemon->listen_socket;
48
49 /* FIXME: convert from here to microhttpd2-style API! */
50
51 if (NULL != daemon->worker_pool)
52 { /* Master daemon with worker pool. */
53 mhd_assert (1 < daemon->worker_pool_size);
54 mhd_assert (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD));
55
56 /* Let workers shutdown in parallel. */
57 for (i = 0; i < daemon->worker_pool_size; ++i)
58 {
59 daemon->worker_pool[i].shutdown = true;
60 if (MHD_ITC_IS_VALID_(daemon->worker_pool[i].itc))
61 {
62 if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, "e"))
63 MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel."));
64 }
65 else
66 mhd_assert (MHD_INVALID_SOCKET != fd);
67 }
68#ifdef HAVE_LISTEN_SHUTDOWN
69 if (MHD_INVALID_SOCKET != fd)
70 {
71 (void) shutdown (fd,
72 SHUT_RDWR);
73 }
74#endif /* HAVE_LISTEN_SHUTDOWN */
75 for (i = 0; i < daemon->worker_pool_size; ++i)
76 {
77 MHD_stop_daemon (&daemon->worker_pool[i]);
78 }
79 free (daemon->worker_pool);
80 mhd_assert (MHD_ITC_IS_INVALID_(daemon->itc));
81#ifdef EPOLL_SUPPORT
82 mhd_assert (-1 == daemon->epoll_fd);
83#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
84 mhd_assert (-1 == daemon->epoll_upgrade_fd);
85#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
86#endif /* EPOLL_SUPPORT */
87 }
88 else
89 { /* Worker daemon or single daemon. */
90 if (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))
91 { /* Worker daemon or single daemon with internal thread(s). */
92 mhd_assert (0 == daemon->worker_pool_size);
93 if (0 != (MHD_TEST_ALLOW_SUSPEND_RESUME & daemon->options))
94 resume_suspended_connections (daemon);
95
96 if (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))
97 {
98 /* Separate thread(s) is used for polling sockets. */
99 if (MHD_ITC_IS_VALID_(daemon->itc))
100 {
101 if (! MHD_itc_activate_ (daemon->itc, "e"))
102 MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel"));
103 }
104 else
105 {
106#ifdef HAVE_LISTEN_SHUTDOWN
107 if (MHD_INVALID_SOCKET != fd)
108 {
109 if (NULL == daemon->master)
110 (void) shutdown (fd,
111 SHUT_RDWR);
112 }
113 else
114#endif /* HAVE_LISTEN_SHUTDOWN */
115 mhd_assert (false); /* Should never happen */
116 }
117
118 if (! MHD_join_thread_ (daemon->pid.handle))
119 {
120 MHD_PANIC (_("Failed to join a thread\n"));
121 }
122 /* close_all_connections() was called in daemon thread. */
123 }
124 }
125 else
126 {
127 /* No internal threads are used for polling sockets. */
128 close_all_connections (daemon);
129 }
130 if (MHD_ITC_IS_VALID_ (daemon->itc))
131 MHD_itc_destroy_chk_ (daemon->itc);
132
133#ifdef EPOLL_SUPPORT
134 if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
135 (-1 != daemon->epoll_fd) )
136 MHD_socket_close_chk_ (daemon->epoll_fd);
137#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
138 if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
139 (-1 != daemon->epoll_upgrade_fd) )
140 MHD_socket_close_chk_ (daemon->epoll_upgrade_fd);
141#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
142#endif /* EPOLL_SUPPORT */
143
144 MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
145 }
146
147 if (NULL != daemon->master)
148 return;
149 /* Cleanup that should be done only one time in master/single daemon.
150 * Do not perform this cleanup in worker daemons. */
151
152 if (MHD_INVALID_SOCKET != fd)
153 MHD_socket_close_chk_ (fd);
154
155 /* TLS clean up */
156#ifdef HTTPS_SUPPORT
157 if (daemon->have_dhparams)
158 {
159 gnutls_dh_params_deinit (daemon->https_mem_dhparams);
160 daemon->have_dhparams = false;
161 }
162 if (0 != (daemon->options & MHD_USE_TLS))
163 {
164 gnutls_priority_deinit (daemon->priority_cache);
165 if (daemon->x509_cred)
166 gnutls_certificate_free_credentials (daemon->x509_cred);
167 }
168#endif /* HTTPS_SUPPORT */
169
170#ifdef DAUTH_SUPPORT
171 free (daemon->nnc);
172 MHD_mutex_destroy_chk_ (&daemon->nnc_lock);
173#endif
174 MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
175 free (daemon);
176}
177
178/* end of daemon_destroy.c */