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.c179
1 files changed, 102 insertions, 77 deletions
diff --git a/src/lib/daemon_destroy.c b/src/lib/daemon_destroy.c
index b1743088..1a8f7094 100644
--- a/src/lib/daemon_destroy.c
+++ b/src/lib/daemon_destroy.c
@@ -24,7 +24,63 @@
24 */ 24 */
25#include "internal.h" 25#include "internal.h"
26 26
27/* TODO: migrate logic below! */ 27
28/**
29 * Stop all worker threads from the worker pool.
30 *
31 * @param daemon master daemon controling the workers
32 */
33static void
34stop_workers (struct MHD_Daemon *daemon)
35{
36 MHD_socket fd;
37 unsigned int i;
38
39 mhd_assert (1 < daemon->worker_pool_size);
40 mhd_assert (1 < daemon->threading_model);
41 if (daemon->was_quiesced)
42 fd = MHD_INVALID_SOCKET; /* Do not use FD if daemon was quiesced */
43 else
44 fd = daemon->listen_socket;
45 /* Let workers shutdown in parallel. */
46 for (i = 0; i < daemon->worker_pool_size; i++)
47 {
48 daemon->worker_pool[i].shutdown = true;
49 if (MHD_ITC_IS_VALID_(daemon->worker_pool[i].itc))
50 {
51 if (! MHD_itc_activate_ (daemon->worker_pool[i].itc,
52 "e"))
53 MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel."));
54 }
55 else
56 {
57 /* Better hope shutdown() works... */
58 mhd_assert (MHD_INVALID_SOCKET != fd);
59 }
60 }
61#ifdef HAVE_LISTEN_SHUTDOWN
62 if (MHD_INVALID_SOCKET != fd)
63 {
64 (void) shutdown (fd,
65 SHUT_RDWR);
66 }
67#endif /* HAVE_LISTEN_SHUTDOWN */
68 for (i = 0; i < daemon->worker_pool_size; ++i)
69 {
70 MHD_daemon_destroy (&daemon->worker_pool[i]);
71 }
72 free (daemon->worker_pool);
73 daemon->worker_pool = NULL;
74 /* FIXME: does this still hold? */
75 mhd_assert (MHD_ITC_IS_INVALID_(daemon->itc));
76#ifdef EPOLL_SUPPORT
77 mhd_assert (-1 == daemon->epoll_fd);
78#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
79 mhd_assert (-1 == daemon->epoll_upgrade_fd);
80#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
81#endif /* EPOLL_SUPPORT */
82}
83
28 84
29/** 85/**
30 * Shutdown and destroy an HTTP daemon. 86 * Shutdown and destroy an HTTP daemon.
@@ -36,7 +92,6 @@ void
36MHD_daemon_destroy (struct MHD_Daemon *daemon) 92MHD_daemon_destroy (struct MHD_Daemon *daemon)
37{ 93{
38 MHD_socket fd; 94 MHD_socket fd;
39 unsigned int i;
40 95
41 if (NULL == daemon) 96 if (NULL == daemon)
42 return; 97 return;
@@ -50,92 +105,60 @@ MHD_daemon_destroy (struct MHD_Daemon *daemon)
50 105
51 if (NULL != daemon->worker_pool) 106 if (NULL != daemon->worker_pool)
52 { /* Master daemon with worker pool. */ 107 { /* Master daemon with worker pool. */
53 mhd_assert (1 < daemon->worker_pool_size); 108 stop_workers (daemon);
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 } 109 }
88 else 110 else
89 { /* Worker daemon or single daemon. */ 111 {
90 if (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) 112 mhd_assert (0 == daemon->worker_pool_size);
91 { /* Worker daemon or single daemon with internal thread(s). */ 113 /* Worker daemon or single-thread daemon. */
92 mhd_assert (0 == daemon->worker_pool_size); 114 if (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_model)
93 if (0 != (MHD_TEST_ALLOW_SUSPEND_RESUME & daemon->options)) 115 {
116 /* Worker daemon or single daemon with internal thread(s). */
117 if (! daemon->disallow_suspend_resume)
94 resume_suspended_connections (daemon); 118 resume_suspended_connections (daemon);
95 119
96 if (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) 120 /* Separate thread(s) is used for polling sockets. */
97 { 121 if (MHD_ITC_IS_VALID_(daemon->itc))
98 /* Separate thread(s) is used for polling sockets. */ 122 {
99 if (MHD_ITC_IS_VALID_(daemon->itc)) 123 if (! MHD_itc_activate_ (daemon->itc,
100 { 124 "e"))
101 if (! MHD_itc_activate_ (daemon->itc, "e")) 125 MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel"));
102 MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel")); 126 }
103 } 127 else
104 else 128 {
105 {
106#ifdef HAVE_LISTEN_SHUTDOWN 129#ifdef HAVE_LISTEN_SHUTDOWN
107 if (MHD_INVALID_SOCKET != fd) 130 if (MHD_INVALID_SOCKET != fd)
108 { 131 {
109 if (NULL == daemon->master) 132 if (NULL == daemon->master)
110 (void) shutdown (fd, 133 (void) shutdown (fd,
111 SHUT_RDWR); 134 SHUT_RDWR);
112 } 135 }
113 else 136 else
114#endif /* HAVE_LISTEN_SHUTDOWN */ 137#endif /* HAVE_LISTEN_SHUTDOWN */
115 mhd_assert (false); /* Should never happen */ 138 mhd_assert (false); /* Should never happen */
116 } 139 }
117 140
118 if (! MHD_join_thread_ (daemon->pid.handle)) 141 if (! MHD_join_thread_ (daemon->pid.handle))
119 { 142 {
120 MHD_PANIC (_("Failed to join a thread\n")); 143 MHD_PANIC (_("Failed to join a thread\n"));
121 } 144 }
122 /* close_all_connections() was called in daemon thread. */ 145 /* close_all_connections() was called in daemon thread. */
123 } 146 }
124 }
125 else 147 else
126 { 148 {
127 /* No internal threads are used for polling sockets. */ 149 /* No internal threads are used for polling sockets
150 (external event loop) */
128 close_all_connections (daemon); 151 close_all_connections (daemon);
129 } 152 }
130 if (MHD_ITC_IS_VALID_ (daemon->itc)) 153 if (MHD_ITC_IS_VALID_ (daemon->itc))
131 MHD_itc_destroy_chk_ (daemon->itc); 154 MHD_itc_destroy_chk_ (daemon->itc);
132 155
133#ifdef EPOLL_SUPPORT 156#ifdef EPOLL_SUPPORT
134 if ( (0 != (daemon->options & MHD_USE_EPOLL)) && 157 if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
135 (-1 != daemon->epoll_fd) ) 158 (-1 != daemon->epoll_fd) )
136 MHD_socket_close_chk_ (daemon->epoll_fd); 159 MHD_socket_close_chk_ (daemon->epoll_fd);
137#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) 160#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
138 if ( (0 != (daemon->options & MHD_USE_EPOLL)) && 161 if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
139 (-1 != daemon->epoll_upgrade_fd) ) 162 (-1 != daemon->epoll_upgrade_fd) )
140 MHD_socket_close_chk_ (daemon->epoll_upgrade_fd); 163 MHD_socket_close_chk_ (daemon->epoll_upgrade_fd);
141#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 164#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
@@ -154,16 +177,18 @@ MHD_daemon_destroy (struct MHD_Daemon *daemon)
154 177
155 /* TLS clean up */ 178 /* TLS clean up */
156#ifdef HTTPS_SUPPORT 179#ifdef HTTPS_SUPPORT
157 if (daemon->have_dhparams) 180 if (NULL != daemon->tls_api)
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 { 181 {
182#if FIXME_TLS_API
183 if (daemon->have_dhparams)
184 {
185 gnutls_dh_params_deinit (daemon->https_mem_dhparams);
186 daemon->have_dhparams = false;
187 }
164 gnutls_priority_deinit (daemon->priority_cache); 188 gnutls_priority_deinit (daemon->priority_cache);
165 if (daemon->x509_cred) 189 if (daemon->x509_cred)
166 gnutls_certificate_free_credentials (daemon->x509_cred); 190 gnutls_certificate_free_credentials (daemon->x509_cred);
191#endif
167 } 192 }
168#endif /* HTTPS_SUPPORT */ 193#endif /* HTTPS_SUPPORT */
169 194