GNU libmicrohttpd 0.9.77
Loading...
Searching...
No Matches
daemon_close_all_connections.c
Go to the documentation of this file.
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
25#include "internal.h"
26#include "connection_cleanup.h"
27#include "connection_close.h"
30#include "request_resume.h"
31#include "upgrade_process.h"
32
33
42static void
44{
45 struct MHD_Daemon *daemon = pos->daemon;
46
47 if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode)
48 {
50 return; /* must let thread to do the rest */
51 }
54
56
57 mhd_assert (! pos->suspended);
58 mhd_assert (! pos->resuming);
59 if (pos->connection_timeout ==
62 daemon->normal_timeout_tail,
63 pos);
64 else
66 daemon->manual_timeout_tail,
67 pos);
69 daemon->connections_tail,
70 pos);
71 DLL_insert (daemon->cleanup_head,
72 daemon->cleanup_tail,
73 pos);
74
76}
77
78
88void
90{
91 struct MHD_Connection *pos;
92 const bool used_thr_p_c = (MHD_TM_THREAD_PER_CONNECTION ==
94#ifdef UPGRADE_SUPPORT
95 const bool upg_allowed = (! daemon->disallow_upgrade);
96#endif /* UPGRADE_SUPPORT */
97#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
98 struct MHD_UpgradeResponseHandle *urh;
99 struct MHD_UpgradeResponseHandle *urhn;
100 const bool used_tls = (NULL != daemon->tls_api);
101
102 mhd_assert (NULL == daemon->worker_pool);
103 mhd_assert (daemon->shutdown);
104 /* give upgraded HTTPS connections a chance to finish */
105 /* 'daemon->urh_head' is not used in thread-per-connection mode. */
106 for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
107 {
108 urhn = urh->prev;
109 /* call generic forwarding function for passing data
110 with chance to detect that application is done. */
111 MHD_upgrade_response_handle_process_ (urh);
112 MHD_connection_finish_forward_ (urh->connection);
113 urh->clean_ready = true;
114 /* Resuming will move connection to cleanup list. */
115 MHD_request_resume (&urh->connection->request);
116 }
117#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
118
119 /* Give suspended connections a chance to resume to avoid
120 running into the check for there not being any suspended
121 connections left in case of a tight race with a recently
122 resumed connection. */
123 if (! daemon->disallow_suspend_resume)
124 {
125 daemon->resuming = true; /* Force check for pending resume. */
127 }
128 /* first, make sure all threads are aware of shutdown; need to
129 traverse DLLs in peace... */
131#ifdef UPGRADE_SUPPORT
132 if (upg_allowed)
133 {
134 struct MHD_Connection *susp;
135
137 while (NULL != susp)
138 {
139 if (NULL == susp->request.urh) /* "Upgraded" connection? */
140 MHD_PANIC (_ (
141 "MHD_stop_daemon() called while we have suspended connections.\n"));
142#ifdef HTTPS_SUPPORT
143 else if (used_tls &&
144 used_thr_p_c &&
145 (! susp->request.urh->clean_ready) )
146 shutdown (susp->request.urh->app.socket,
147 SHUT_RDWR); /* Wake thread by shutdown of app socket. */
148#endif /* HTTPS_SUPPORT */
149 else
150 {
151#ifdef HAVE_MESSAGES
152 if (! susp->request.urh->was_closed)
153 MHD_DLOG (daemon,
154 MHD_SC_SHUTDOWN_WITH_OPEN_UPGRADED_CONNECTION,
155 _ (
156 "Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
157#endif
158 susp->request.urh->was_closed = true;
159 /* If thread-per-connection is used, connection's thread
160 * may still processing "upgrade" (exiting). */
161 if (! used_thr_p_c)
163 /* Do not use MHD_resume_connection() as mutex is
164 * already locked. */
165 susp->resuming = true;
166 daemon->resuming = true;
167 }
168 susp = susp->prev;
169 }
170 }
171 else /* This 'else' is combined with next 'if' */
172#endif /* UPGRADE_SUPPORT */
174 MHD_PANIC (_ (
175 "MHD_stop_daemon() called while we have suspended connections.\n"));
176 for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev)
177 {
178 shutdown (pos->socket_fd,
179 SHUT_RDWR);
180#if MHD_WINSOCK_SOCKETS
181 if ( (used_thr_p_c) &&
182 (MHD_ITC_IS_VALID_ (daemon->itc)) &&
183 (! MHD_itc_activate_ (daemon->itc,
184 "e")) )
185 MHD_PANIC (_ (
186 "Failed to signal shutdown via inter-thread communication channel.\n"));
187#endif
188 }
189
190 /* now, collect per-connection threads */
191 if (used_thr_p_c)
192 {
194 while (NULL != pos)
195 {
196 if (! pos->thread_joined)
197 {
199 if (! MHD_join_thread_ (pos->pid.handle))
200 MHD_PANIC (_ ("Failed to join a thread.\n"));
202 pos->thread_joined = true;
203 /* The thread may have concurrently modified the DLL,
204 need to restart from the beginning */
206 continue;
207 }
208 pos = pos->prev;
209 }
210 }
212
213#ifdef UPGRADE_SUPPORT
214 /* Finished threads with "upgraded" connections need to be moved
215 * to cleanup list by resume_suspended_connections(). */
216 /* "Upgraded" connections that were not closed explicitly by
217 * application should be moved to cleanup list too. */
218 if (upg_allowed)
219 {
220 daemon->resuming = true; /* Force check for pending resume. */
222 }
223#endif /* UPGRADE_SUPPORT */
224
225 /* now that we're alone, move everyone to cleanup */
226 while (NULL != (pos = daemon->connections_tail))
227 {
228 if ( (used_thr_p_c) &&
229 (! pos->thread_joined) )
230 MHD_PANIC (_ ("Failed to join a thread.\n"));
231 close_connection (pos);
232 }
234}
235
236
237/* end of daemon_close_all_connections.c */
#define MHD_connection_finish_forward_(conn)
Definition connection.h:165
void MHD_connection_cleanup_(struct MHD_Daemon *daemon)
functions to cleanup completed connection
void MHD_connection_mark_closed_(struct MHD_Connection *connection)
void MHD_connection_close_(struct MHD_Connection *connection, enum MHD_RequestTerminationCode rtc)
functions to close connection
complete upgrade socket forwarding operation in TLS mode
static void close_connection(struct MHD_Connection *pos)
void MHD_daemon_close_all_connections_(struct MHD_Daemon *daemon)
function to close all connections open at a daemon
@ MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN
#define DLL_insert(head, tail, element)
Definition internal.h:1743
#define MHD_PANIC(msg)
Definition internal.h:69
#define XDLL_remove(head, tail, element)
Definition internal.h:1806
#define DLL_remove(head, tail, element)
Definition internal.h:1763
#define mhd_assert(CHK)
Definition mhd_assert.h:39
#define MHD_mutex_unlock_chk_(pmutex)
Definition mhd_locks.h:180
#define MHD_mutex_lock_chk_(pmutex)
Definition mhd_locks.h:154
#define NULL
#define _(String)
Definition mhd_options.h:42
MHD internal shared structures.
void MHD_request_resume(struct MHD_Request *request)
bool MHD_resume_suspended_connections_(struct MHD_Daemon *daemon)
implementation of MHD_request_resume()
MHD_socket socket_fd
Definition internal.h:752
struct MHD_Request request
Definition internal.h:717
time_t connection_timeout
Definition internal.h:745
struct MHD_Connection * prev
Definition internal.h:656
MHD_thread_handle_ID_ pid
Definition internal.h:723
struct MHD_Daemon * daemon
Definition internal.h:675
bool thread_joined
Definition internal.h:779
MHD_mutex_ cleanup_connection_mutex
Definition internal.h:1265
struct MHD_Connection * connections_head
Definition internal.h:1155
struct MHD_itc_ itc
Definition internal.h:1410
struct MHD_Connection * manual_timeout_tail
Definition internal.h:1150
bool disallow_upgrade
Definition internal.h:1474
volatile bool shutdown
Definition internal.h:1526
bool disallow_suspend_resume
Definition internal.h:1468
struct MHD_Connection * cleanup_tail
Definition internal.h:1182
bool resuming
Definition internal.h:1510
struct MHD_Daemon * worker_pool
Definition internal.h:1073
time_t connection_default_timeout
Definition internal.h:1371
struct MHD_Connection * manual_timeout_head
Definition internal.h:1143
struct MHD_Connection * suspended_connections_tail
Definition internal.h:1172
struct MHD_Connection * cleanup_head
Definition internal.h:1177
struct MHD_Connection * normal_timeout_head
Definition internal.h:1128
struct MHD_Connection * normal_timeout_tail
Definition internal.h:1135
enum MHD_ThreadingMode threading_mode
Definition internal.h:1417
struct MHD_Connection * suspended_connections_head
Definition internal.h:1166
struct MHD_Connection * connections_tail
Definition internal.h:1160
function to process upgrade activity (over TLS)