diff options
Diffstat (limited to 'src/lib/daemon_destroy.c')
-rw-r--r-- | src/lib/daemon_destroy.c | 178 |
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 | */ | ||
35 | void | ||
36 | MHD_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 */ | ||