GNU libmicrohttpd  0.9.72
request_resume.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_close.h"
27 
42 void
44 {
45  struct MHD_Daemon *daemon = request->daemon;
46 
47  if (daemon->disallow_suspend_resume)
48  MHD_PANIC (_ (
49  "Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
51  request->connection->resuming = true;
52  daemon->resuming = true;
54  if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
55  (! MHD_itc_activate_ (daemon->itc,
56  "r")) )
57  {
58 #ifdef HAVE_MESSAGES
59  MHD_DLOG (daemon,
60  MHD_SC_ITC_USE_FAILED,
61  _ (
62  "Failed to signal resume via inter-thread communication channel.\n"));
63 #endif
64  }
65 }
66 
67 
78 bool
80 /* FIXME: rename connections -> requests? */
81 {
82  struct MHD_Connection *pos;
83  struct MHD_Connection *prev = NULL;
84  bool ret;
85  const bool used_thr_p_c = (MHD_TM_THREAD_PER_CONNECTION ==
87 
89  ret = false;
91 
92  if (daemon->resuming)
93  {
95  /* During shutdown check for resuming is forced. */
96  mhd_assert ((NULL != prev) || (daemon->shutdown));
97  }
98 
99  daemon->resuming = false;
100 
101  while (NULL != (pos = prev))
102  {
103 #ifdef UPGRADE_SUPPORT
104  struct MHD_UpgradeResponseHandle *const urh = pos->request.urh;
105 #else /* ! UPGRADE_SUPPORT */
106  static const void *const urh = NULL;
107 #endif /* ! UPGRADE_SUPPORT */
108  prev = pos->prev;
109  if ( (! pos->resuming)
110 #ifdef UPGRADE_SUPPORT
111  || ( (NULL != urh) &&
112  ( (! urh->was_closed) ||
113  (! urh->clean_ready) ) )
114 #endif /* UPGRADE_SUPPORT */
115  )
116  continue;
117  ret = true;
118  mhd_assert (pos->suspended);
121  pos);
122  pos->suspended = false;
123  if (NULL == urh)
124  {
125  DLL_insert (daemon->connections_head,
126  daemon->connections_tail,
127  pos);
128  if (! used_thr_p_c)
129  {
130  /* Reset timeout timer on resume. */
131  if (0 != pos->connection_timeout)
133 
136  daemon->normal_timeout_tail,
137  pos);
138  else
140  daemon->manual_timeout_tail,
141  pos);
142  }
143 #ifdef EPOLL_SUPPORT
144  if (MHD_ELS_EPOLL == daemon->event_loop_syscall)
145  {
146  if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
147  MHD_PANIC ("Resumed connection was already in EREADY set.\n");
148  /* we always mark resumed connections as ready, as we
149  might have missed the edge poll event during suspension */
150  EDLL_insert (daemon->eready_head,
151  daemon->eready_tail,
152  pos);
153  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL \
156  pos->epoll_state &= ~MHD_EPOLL_STATE_SUSPENDED;
157  }
158 #endif
159  }
160 #ifdef UPGRADE_SUPPORT
161  else
162  {
163  struct MHD_Response *response = pos->request.response;
164 
165  /* Data forwarding was finished (for TLS connections) AND
166  * application was closed upgraded connection.
167  * Insert connection into cleanup list. */
168  if ( (NULL != response) &&
169  (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) &&
170  (NULL != response->termination_cb) )
171  response->termination_cb (response->termination_cb_cls,
173  &pos->request.client_context);
174  DLL_insert (daemon->cleanup_head,
175  daemon->cleanup_tail,
176  pos);
177 
178  }
179 #endif /* UPGRADE_SUPPORT */
180  pos->resuming = false;
181  }
183  if ( (used_thr_p_c) &&
184  (ret) )
185  { /* Wake up suspended connections. */
186  if (! MHD_itc_activate_ (daemon->itc,
187  "w"))
188  {
189 #ifdef HAVE_MESSAGES
190  MHD_DLOG (daemon,
191  MHD_SC_ITC_USE_FAILED,
192  _ (
193  "Failed to signal resume of connection via inter-thread communication channel.\n"));
194 #endif
195  }
196  }
197  return ret;
198 }
199 
200 
201 /* end of request_resume.c */
MHD_Daemon::worker_pool
struct MHD_Daemon * worker_pool
Definition: internal.h:1073
_
#define _(String)
Definition: mhd_options.h:42
MHD_Connection::resuming
bool resuming
Definition: internal.h:774
MHD_Connection::prev
struct MHD_Connection * prev
Definition: internal.h:656
EDLL_insert
#define EDLL_insert(head, tail, element)
Definition: internal.h:1829
MHD_mutex_unlock_chk_
#define MHD_mutex_unlock_chk_(pmutex)
Definition: mhd_locks.h:180
MHD_Request
Definition: internal.h:367
MHD_EPOLL_STATE_WRITE_READY
@ MHD_EPOLL_STATE_WRITE_READY
Definition: internal.h:606
MHD_Daemon::itc
struct MHD_itc_ itc
Definition: internal.h:1410
MHD_Daemon::cleanup_tail
struct MHD_Connection * cleanup_tail
Definition: internal.h:1182
MHD_resume_suspended_connections_
bool MHD_resume_suspended_connections_(struct MHD_Daemon *daemon)
Definition: request_resume.c:79
MHD_Daemon::manual_timeout_tail
struct MHD_Connection * manual_timeout_tail
Definition: internal.h:1150
MHD_Request::client_context
void * client_context
Definition: internal.h:401
MHD_monotonic_sec_counter
time_t MHD_monotonic_sec_counter(void)
Definition: mhd_mono_clock.c:337
MHD_Daemon::normal_timeout_tail
struct MHD_Connection * normal_timeout_tail
Definition: internal.h:1135
MHD_Daemon::normal_timeout_head
struct MHD_Connection * normal_timeout_head
Definition: internal.h:1128
MHD_REQUEST_TERMINATED_COMPLETED_OK
@ MHD_REQUEST_TERMINATED_COMPLETED_OK
Definition: microhttpd.h:1838
MHD_Connection::last_activity
time_t last_activity
Definition: internal.h:739
connection_close.h
functions to close connection
MHD_Daemon::suspended_connections_tail
struct MHD_Connection * suspended_connections_tail
Definition: internal.h:1172
internal.h
internal shared structures
MHD_Daemon::suspended_connections_head
struct MHD_Connection * suspended_connections_head
Definition: internal.h:1166
MHD_Daemon::resuming
bool resuming
Definition: internal.h:1510
NULL
#define NULL
Definition: reason_phrase.c:30
MHD_Daemon::event_loop_syscall
enum MHD_EventLoopSyscall event_loop_syscall
Definition: internal.h:1436
MHD_Connection::suspended
bool suspended
Definition: internal.h:764
MHD_Daemon::disallow_suspend_resume
bool disallow_suspend_resume
Definition: internal.h:1468
MHD_Connection::request
struct MHD_Request request
Definition: internal.h:717
MHD_Daemon::shutdown
volatile bool shutdown
Definition: internal.h:1526
MHD_Request::daemon
struct MHD_Daemon * daemon
Definition: internal.h:372
DLL_insert
#define DLL_insert(head, tail, element)
Definition: internal.h:1743
DLL_remove
#define DLL_remove(head, tail, element)
Definition: internal.h:1763
MHD_Daemon::threading_mode
enum MHD_ThreadingMode threading_mode
Definition: internal.h:1417
MHD_Daemon::cleanup_connection_mutex
MHD_mutex_ cleanup_connection_mutex
Definition: internal.h:1265
MHD_Request::connection
struct MHD_Connection * connection
Definition: internal.h:377
MHD_Daemon::manual_timeout_head
struct MHD_Connection * manual_timeout_head
Definition: internal.h:1143
MHD_Daemon
Definition: internal.h:1001
MHD_Response::termination_cb
MHD_RequestTerminationCallback termination_cb
Definition: internal.h:1612
MHD_Daemon::cleanup_head
struct MHD_Connection * cleanup_head
Definition: internal.h:1177
mhd_assert
#define mhd_assert(CHK)
Definition: mhd_assert.h:39
MHD_Response::termination_cb_cls
void * termination_cb_cls
Definition: internal.h:1617
MHD_EPOLL_STATE_READ_READY
@ MHD_EPOLL_STATE_READ_READY
Definition: internal.h:600
MHD_mutex_lock_chk_
#define MHD_mutex_lock_chk_(pmutex)
Definition: mhd_locks.h:154
MHD_Connection::daemon
struct MHD_Daemon * daemon
Definition: internal.h:675
MHD_Daemon::connection_default_timeout
time_t connection_default_timeout
Definition: internal.h:1371
MHD_Daemon::connections_tail
struct MHD_Connection * connections_tail
Definition: internal.h:1160
XDLL_insert
#define XDLL_insert(head, tail, element)
Definition: internal.h:1786
MHD_Response
Definition: internal.h:1568
MHD_Connection
Definition: internal.h:634
MHD_request_resume
void MHD_request_resume(struct MHD_Request *request)
Definition: request_resume.c:43
MHD_Daemon::connections_head
struct MHD_Connection * connections_head
Definition: internal.h:1155
MHD_Request::response
struct MHD_Response * response
Definition: internal.h:383
MHD_PANIC
#define MHD_PANIC(msg)
Definition: internal.h:69
MHD_EPOLL_STATE_SUSPENDED
@ MHD_EPOLL_STATE_SUSPENDED
Definition: internal.h:621
MHD_EPOLL_STATE_IN_EREADY_EDLL
@ MHD_EPOLL_STATE_IN_EREADY_EDLL
Definition: internal.h:611
MHD_Connection::connection_timeout
time_t connection_timeout
Definition: internal.h:745