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 */
functions to close connection
@ MHD_REQUEST_TERMINATED_COMPLETED_OK
Definition: microhttpd.h:1838
#define XDLL_insert(head, tail, element)
Definition: internal.h:1786
@ MHD_EPOLL_STATE_SUSPENDED
Definition: internal.h:621
@ MHD_EPOLL_STATE_IN_EREADY_EDLL
Definition: internal.h:611
@ MHD_EPOLL_STATE_READ_READY
Definition: internal.h:600
@ MHD_EPOLL_STATE_WRITE_READY
Definition: internal.h:606
#define DLL_insert(head, tail, element)
Definition: internal.h:1743
#define EDLL_insert(head, tail, element)
Definition: internal.h:1829
#define MHD_PANIC(msg)
Definition: internal.h:69
#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
time_t MHD_monotonic_sec_counter(void)
#define NULL
Definition: reason_phrase.c:30
#define _(String)
Definition: mhd_options.h:42
internal shared structures
void MHD_request_resume(struct MHD_Request *request)
bool MHD_resume_suspended_connections_(struct MHD_Daemon *daemon)
bool suspended
Definition: internal.h:764
struct MHD_Request request
Definition: internal.h:717
time_t connection_timeout
Definition: internal.h:745
struct MHD_Connection * prev
Definition: internal.h:656
time_t last_activity
Definition: internal.h:739
struct MHD_Daemon * daemon
Definition: internal.h:675
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
enum MHD_EventLoopSyscall event_loop_syscall
Definition: internal.h:1436
struct MHD_Connection * manual_timeout_tail
Definition: internal.h:1150
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
struct MHD_Response * response
Definition: internal.h:383
void * client_context
Definition: internal.h:401
struct MHD_Connection * connection
Definition: internal.h:377
struct MHD_Daemon * daemon
Definition: internal.h:372
void * termination_cb_cls
Definition: internal.h:1617
MHD_RequestTerminationCallback termination_cb
Definition: internal.h:1612