diff options
Diffstat (limited to 'src/lib/daemon_close_all_connections.c')
-rw-r--r-- | src/lib/daemon_close_all_connections.c | 179 |
1 files changed, 92 insertions, 87 deletions
diff --git a/src/lib/daemon_close_all_connections.c b/src/lib/daemon_close_all_connections.c index d4b825da..1a777494 100644 --- a/src/lib/daemon_close_all_connections.c +++ b/src/lib/daemon_close_all_connections.c | |||
@@ -45,10 +45,10 @@ close_connection (struct MHD_Connection *pos) | |||
45 | struct MHD_Daemon *daemon = pos->daemon; | 45 | struct MHD_Daemon *daemon = pos->daemon; |
46 | 46 | ||
47 | if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) | 47 | if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) |
48 | { | 48 | { |
49 | MHD_connection_mark_closed_ (pos); | 49 | MHD_connection_mark_closed_ (pos); |
50 | return; /* must let thread to do the rest */ | 50 | return; /* must let thread to do the rest */ |
51 | } | 51 | } |
52 | MHD_connection_close_ (pos, | 52 | MHD_connection_close_ (pos, |
53 | MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN); | 53 | MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN); |
54 | 54 | ||
@@ -59,18 +59,18 @@ close_connection (struct MHD_Connection *pos) | |||
59 | if (pos->connection_timeout == | 59 | if (pos->connection_timeout == |
60 | pos->daemon->connection_default_timeout) | 60 | pos->daemon->connection_default_timeout) |
61 | XDLL_remove (daemon->normal_timeout_head, | 61 | XDLL_remove (daemon->normal_timeout_head, |
62 | daemon->normal_timeout_tail, | 62 | daemon->normal_timeout_tail, |
63 | pos); | 63 | pos); |
64 | else | 64 | else |
65 | XDLL_remove (daemon->manual_timeout_head, | 65 | XDLL_remove (daemon->manual_timeout_head, |
66 | daemon->manual_timeout_tail, | 66 | daemon->manual_timeout_tail, |
67 | pos); | 67 | pos); |
68 | DLL_remove (daemon->connections_head, | 68 | DLL_remove (daemon->connections_head, |
69 | daemon->connections_tail, | 69 | daemon->connections_tail, |
70 | pos); | 70 | pos); |
71 | DLL_insert (daemon->cleanup_head, | 71 | DLL_insert (daemon->cleanup_head, |
72 | daemon->cleanup_tail, | 72 | daemon->cleanup_tail, |
73 | pos); | 73 | pos); |
74 | 74 | ||
75 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 75 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
76 | } | 76 | } |
@@ -89,7 +89,8 @@ void | |||
89 | MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon) | 89 | MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon) |
90 | { | 90 | { |
91 | struct MHD_Connection *pos; | 91 | struct MHD_Connection *pos; |
92 | const bool used_thr_p_c = (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode); | 92 | const bool used_thr_p_c = (MHD_TM_THREAD_PER_CONNECTION == |
93 | daemon->threading_mode); | ||
93 | #ifdef UPGRADE_SUPPORT | 94 | #ifdef UPGRADE_SUPPORT |
94 | const bool upg_allowed = (! daemon->disallow_upgrade); | 95 | const bool upg_allowed = (! daemon->disallow_upgrade); |
95 | #endif /* UPGRADE_SUPPORT */ | 96 | #endif /* UPGRADE_SUPPORT */ |
@@ -103,16 +104,16 @@ MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon) | |||
103 | /* give upgraded HTTPS connections a chance to finish */ | 104 | /* give upgraded HTTPS connections a chance to finish */ |
104 | /* 'daemon->urh_head' is not used in thread-per-connection mode. */ | 105 | /* 'daemon->urh_head' is not used in thread-per-connection mode. */ |
105 | for (urh = daemon->urh_tail; NULL != urh; urh = urhn) | 106 | for (urh = daemon->urh_tail; NULL != urh; urh = urhn) |
106 | { | 107 | { |
107 | urhn = urh->prev; | 108 | urhn = urh->prev; |
108 | /* call generic forwarding function for passing data | 109 | /* call generic forwarding function for passing data |
109 | with chance to detect that application is done. */ | 110 | with chance to detect that application is done. */ |
110 | MHD_upgrade_response_handle_process_ (urh); | 111 | MHD_upgrade_response_handle_process_ (urh); |
111 | MHD_connection_finish_forward_ (urh->connection); | 112 | MHD_connection_finish_forward_ (urh->connection); |
112 | urh->clean_ready = true; | 113 | urh->clean_ready = true; |
113 | /* Resuming will move connection to cleanup list. */ | 114 | /* Resuming will move connection to cleanup list. */ |
114 | MHD_request_resume (&urh->connection->request); | 115 | MHD_request_resume (&urh->connection->request); |
115 | } | 116 | } |
116 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 117 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
117 | 118 | ||
118 | /* Give suspended connections a chance to resume to avoid | 119 | /* Give suspended connections a chance to resume to avoid |
@@ -120,89 +121,93 @@ MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon) | |||
120 | connections left in case of a tight race with a recently | 121 | connections left in case of a tight race with a recently |
121 | resumed connection. */ | 122 | resumed connection. */ |
122 | if (! daemon->disallow_suspend_resume) | 123 | if (! daemon->disallow_suspend_resume) |
123 | { | 124 | { |
124 | daemon->resuming = true; /* Force check for pending resume. */ | 125 | daemon->resuming = true; /* Force check for pending resume. */ |
125 | MHD_resume_suspended_connections_ (daemon); | 126 | MHD_resume_suspended_connections_ (daemon); |
126 | } | 127 | } |
127 | /* first, make sure all threads are aware of shutdown; need to | 128 | /* first, make sure all threads are aware of shutdown; need to |
128 | traverse DLLs in peace... */ | 129 | traverse DLLs in peace... */ |
129 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 130 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
130 | #ifdef UPGRADE_SUPPORT | 131 | #ifdef UPGRADE_SUPPORT |
131 | if (upg_allowed) | 132 | if (upg_allowed) |
132 | { | 133 | { |
133 | struct MHD_Connection * susp; | 134 | struct MHD_Connection *susp; |
134 | 135 | ||
135 | susp = daemon->suspended_connections_tail; | 136 | susp = daemon->suspended_connections_tail; |
136 | while (NULL != susp) | 137 | while (NULL != susp) |
137 | { | 138 | { |
138 | if (NULL == susp->request.urh) /* "Upgraded" connection? */ | 139 | if (NULL == susp->request.urh) /* "Upgraded" connection? */ |
139 | MHD_PANIC (_("MHD_stop_daemon() called while we have suspended connections.\n")); | 140 | MHD_PANIC (_ ( |
141 | "MHD_stop_daemon() called while we have suspended connections.\n")); | ||
140 | #ifdef HTTPS_SUPPORT | 142 | #ifdef HTTPS_SUPPORT |
141 | else if (used_tls && | 143 | else if (used_tls && |
142 | used_thr_p_c && | 144 | used_thr_p_c && |
143 | (! susp->request.urh->clean_ready) ) | 145 | (! susp->request.urh->clean_ready) ) |
144 | shutdown (susp->request.urh->app.socket, | 146 | shutdown (susp->request.urh->app.socket, |
145 | SHUT_RDWR); /* Wake thread by shutdown of app socket. */ | 147 | SHUT_RDWR); /* Wake thread by shutdown of app socket. */ |
146 | #endif /* HTTPS_SUPPORT */ | 148 | #endif /* HTTPS_SUPPORT */ |
147 | else | 149 | else |
148 | { | 150 | { |
149 | #ifdef HAVE_MESSAGES | 151 | #ifdef HAVE_MESSAGES |
150 | if (! susp->request.urh->was_closed) | 152 | if (! susp->request.urh->was_closed) |
151 | MHD_DLOG (daemon, | 153 | MHD_DLOG (daemon, |
152 | MHD_SC_SHUTDOWN_WITH_OPEN_UPGRADED_CONNECTION, | 154 | MHD_SC_SHUTDOWN_WITH_OPEN_UPGRADED_CONNECTION, |
153 | _("Initiated daemon shutdown while \"upgraded\" connection was not closed.\n")); | 155 | _ ( |
156 | "Initiated daemon shutdown while \"upgraded\" connection was not closed.\n")); | ||
154 | #endif | 157 | #endif |
155 | susp->request.urh->was_closed = true; | 158 | susp->request.urh->was_closed = true; |
156 | /* If thread-per-connection is used, connection's thread | 159 | /* If thread-per-connection is used, connection's thread |
157 | * may still processing "upgrade" (exiting). */ | 160 | * may still processing "upgrade" (exiting). */ |
158 | if (! used_thr_p_c) | 161 | if (! used_thr_p_c) |
159 | MHD_connection_finish_forward_ (susp); | 162 | MHD_connection_finish_forward_ (susp); |
160 | /* Do not use MHD_resume_connection() as mutex is | 163 | /* Do not use MHD_resume_connection() as mutex is |
161 | * already locked. */ | 164 | * already locked. */ |
162 | susp->resuming = true; | 165 | susp->resuming = true; |
163 | daemon->resuming = true; | 166 | daemon->resuming = true; |
164 | } | 167 | } |
165 | susp = susp->prev; | 168 | susp = susp->prev; |
166 | } | ||
167 | } | 169 | } |
170 | } | ||
168 | else /* This 'else' is combined with next 'if' */ | 171 | else /* This 'else' is combined with next 'if' */ |
169 | #endif /* UPGRADE_SUPPORT */ | 172 | #endif /* UPGRADE_SUPPORT */ |
170 | if (NULL != daemon->suspended_connections_head) | 173 | if (NULL != daemon->suspended_connections_head) |
171 | MHD_PANIC (_("MHD_stop_daemon() called while we have suspended connections.\n")); | 174 | MHD_PANIC (_ ( |
175 | "MHD_stop_daemon() called while we have suspended connections.\n")); | ||
172 | for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev) | 176 | for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev) |
173 | { | 177 | { |
174 | shutdown (pos->socket_fd, | 178 | shutdown (pos->socket_fd, |
175 | SHUT_RDWR); | 179 | SHUT_RDWR); |
176 | #if MHD_WINSOCK_SOCKETS | 180 | #if MHD_WINSOCK_SOCKETS |
177 | if ( (used_thr_p_c) && | 181 | if ( (used_thr_p_c) && |
178 | (MHD_ITC_IS_VALID_(daemon->itc)) && | 182 | (MHD_ITC_IS_VALID_ (daemon->itc)) && |
179 | (! MHD_itc_activate_ (daemon->itc, | 183 | (! MHD_itc_activate_ (daemon->itc, |
180 | "e")) ) | 184 | "e")) ) |
181 | MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel")); | 185 | MHD_PANIC (_ ( |
186 | "Failed to signal shutdown via inter-thread communication channel")); | ||
182 | #endif | 187 | #endif |
183 | } | 188 | } |
184 | 189 | ||
185 | /* now, collect per-connection threads */ | 190 | /* now, collect per-connection threads */ |
186 | if (used_thr_p_c) | 191 | if (used_thr_p_c) |
192 | { | ||
193 | pos = daemon->connections_tail; | ||
194 | while (NULL != pos) | ||
187 | { | 195 | { |
188 | pos = daemon->connections_tail; | 196 | if (! pos->thread_joined) |
189 | while (NULL != pos) | ||
190 | { | 197 | { |
191 | if (! pos->thread_joined) | 198 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
192 | { | 199 | if (! MHD_join_thread_ (pos->pid.handle)) |
193 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 200 | MHD_PANIC (_ ("Failed to join a thread\n")); |
194 | if (! MHD_join_thread_ (pos->pid.handle)) | 201 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
195 | MHD_PANIC (_("Failed to join a thread\n")); | 202 | pos->thread_joined = true; |
196 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 203 | /* The thread may have concurrently modified the DLL, |
197 | pos->thread_joined = true; | 204 | need to restart from the beginning */ |
198 | /* The thread may have concurrently modified the DLL, | 205 | pos = daemon->connections_tail; |
199 | need to restart from the beginning */ | 206 | continue; |
200 | pos = daemon->connections_tail; | ||
201 | continue; | ||
202 | } | ||
203 | pos = pos->prev; | ||
204 | } | 207 | } |
208 | pos = pos->prev; | ||
205 | } | 209 | } |
210 | } | ||
206 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 211 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
207 | 212 | ||
208 | #ifdef UPGRADE_SUPPORT | 213 | #ifdef UPGRADE_SUPPORT |
@@ -211,10 +216,10 @@ MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon) | |||
211 | /* "Upgraded" connections that were not closed explicitly by | 216 | /* "Upgraded" connections that were not closed explicitly by |
212 | * application should be moved to cleanup list too. */ | 217 | * application should be moved to cleanup list too. */ |
213 | if (upg_allowed) | 218 | if (upg_allowed) |
214 | { | 219 | { |
215 | daemon->resuming = true; /* Force check for pending resume. */ | 220 | daemon->resuming = true; /* Force check for pending resume. */ |
216 | MHD_resume_suspended_connections_ (daemon); | 221 | MHD_resume_suspended_connections_ (daemon); |
217 | } | 222 | } |
218 | #endif /* UPGRADE_SUPPORT */ | 223 | #endif /* UPGRADE_SUPPORT */ |
219 | 224 | ||
220 | /* now that we're alone, move everyone to cleanup */ | 225 | /* now that we're alone, move everyone to cleanup */ |
@@ -222,7 +227,7 @@ MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon) | |||
222 | { | 227 | { |
223 | if ( (used_thr_p_c) && | 228 | if ( (used_thr_p_c) && |
224 | (! pos->thread_joined) ) | 229 | (! pos->thread_joined) ) |
225 | MHD_PANIC (_("Failed to join a thread\n")); | 230 | MHD_PANIC (_ ("Failed to join a thread\n")); |
226 | close_connection (pos); | 231 | close_connection (pos); |
227 | } | 232 | } |
228 | MHD_connection_cleanup_ (daemon); | 233 | MHD_connection_cleanup_ (daemon); |