aboutsummaryrefslogtreecommitdiff
path: root/src/lib/daemon_close_all_connections.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/daemon_close_all_connections.c')
-rw-r--r--src/lib/daemon_close_all_connections.c179
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
89MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon) 89MHD_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);