GNU libmicrohttpd  0.9.65
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 (_("Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
50  request->connection->resuming = true;
51  daemon->resuming = true;
53  if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
54  (! MHD_itc_activate_ (daemon->itc,
55  "r")) )
56  {
57 #ifdef HAVE_MESSAGES
58  MHD_DLOG (daemon,
59  MHD_SC_ITC_USE_FAILED,
60  _("Failed to signal resume via inter-thread communication channel."));
61 #endif
62  }
63 }
64 
65 
76 bool
78 /* FIXME: rename connections -> requests? */
79 {
80  struct MHD_Connection *pos;
81  struct MHD_Connection *prev = NULL;
82  bool ret;
83  const bool used_thr_p_c = (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode);
84 
86  ret = false;
88 
89  if (daemon->resuming)
90  {
92  /* During shutdown check for resuming is forced. */
93  mhd_assert((NULL != prev) || (daemon->shutdown));
94  }
95 
96  daemon->resuming = false;
97 
98  while (NULL != (pos = prev))
99  {
100 #ifdef UPGRADE_SUPPORT
101  struct MHD_UpgradeResponseHandle * const urh = pos->request.urh;
102 #else /* ! UPGRADE_SUPPORT */
103  static const void * const urh = NULL;
104 #endif /* ! UPGRADE_SUPPORT */
105  prev = pos->prev;
106  if ( (! pos->resuming)
107 #ifdef UPGRADE_SUPPORT
108  || ( (NULL != urh) &&
109  ( (! urh->was_closed) ||
110  (! urh->clean_ready) ) )
111 #endif /* UPGRADE_SUPPORT */
112  )
113  continue;
114  ret = true;
115  mhd_assert (pos->suspended);
118  pos);
119  pos->suspended = false;
120  if (NULL == urh)
121  {
122  DLL_insert (daemon->connections_head,
123  daemon->connections_tail,
124  pos);
125  if (! used_thr_p_c)
126  {
127  /* Reset timeout timer on resume. */
128  if (0 != pos->connection_timeout)
130 
133  daemon->normal_timeout_tail,
134  pos);
135  else
137  daemon->manual_timeout_tail,
138  pos);
139  }
140 #ifdef EPOLL_SUPPORT
141  if (MHD_ELS_EPOLL == daemon->event_loop_syscall)
142  {
143  if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
144  MHD_PANIC ("Resumed connection was already in EREADY set\n");
145  /* we always mark resumed connections as ready, as we
146  might have missed the edge poll event during suspension */
147  EDLL_insert (daemon->eready_head,
148  daemon->eready_tail,
149  pos);
150  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL | \
151  MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY;
152  pos->epoll_state &= ~MHD_EPOLL_STATE_SUSPENDED;
153  }
154 #endif
155  }
156 #ifdef UPGRADE_SUPPORT
157  else
158  {
159  struct MHD_Response *response = pos->request.response;
160 
161  /* Data forwarding was finished (for TLS connections) AND
162  * application was closed upgraded connection.
163  * Insert connection into cleanup list. */
164  if ( (NULL != response) &&
165  (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) &&
166  (NULL != response->termination_cb) )
167  response->termination_cb (response->termination_cb_cls,
169  &pos->request.client_context);
170  DLL_insert (daemon->cleanup_head,
171  daemon->cleanup_tail,
172  pos);
173 
174  }
175 #endif /* UPGRADE_SUPPORT */
176  pos->resuming = false;
177  }
179  if ( (used_thr_p_c) &&
180  (ret) )
181  { /* Wake up suspended connections. */
182  if (! MHD_itc_activate_(daemon->itc,
183  "w"))
184  {
185 #ifdef HAVE_MESSAGES
186  MHD_DLOG (daemon,
187  MHD_SC_ITC_USE_FAILED,
188  _("Failed to signal resume of connection via inter-thread communication channel."));
189 #endif
190  }
191  }
192  return ret;
193 }
194 
195 
196 /* end of request_resume.c */
struct MHD_Request request
Definition: internal.h:714
enum MHD_EventLoopSyscall event_loop_syscall
Definition: internal.h:1433
#define MHD_PANIC(msg)
Definition: internal.h:68
struct MHD_Connection * cleanup_head
Definition: internal.h:1174
#define MHD_mutex_unlock_chk_(pmutex)
Definition: mhd_locks.h:177
void * termination_cb_cls
Definition: internal.h:1614
#define EDLL_insert(head, tail, element)
Definition: internal.h:1829
MHD_RequestTerminationCallback termination_cb
Definition: internal.h:1609
struct MHD_Connection * manual_timeout_head
Definition: internal.h:1140
time_t MHD_monotonic_sec_counter(void)
internal shared structures
struct MHD_Daemon * daemon
Definition: internal.h:672
time_t connection_default_timeout
Definition: internal.h:1368
struct MHD_Daemon * daemon
Definition: internal.h:369
#define DLL_insert(head, tail, element)
Definition: internal.h:1742
struct MHD_Connection * connections_tail
Definition: internal.h:1157
struct MHD_Daemon * worker_pool
Definition: internal.h:1070
functions to close connection
struct MHD_Connection * connections_head
Definition: internal.h:1152
time_t connection_timeout
Definition: internal.h:742
struct MHD_Connection * manual_timeout_tail
Definition: internal.h:1147
#define NULL
Definition: reason_phrase.c:30
struct MHD_Connection * prev
Definition: internal.h:653
#define DLL_remove(head, tail, element)
Definition: internal.h:1762
struct MHD_Connection * normal_timeout_head
Definition: internal.h:1125
void MHD_request_resume(struct MHD_Request *request)
struct MHD_Connection * suspended_connections_tail
Definition: internal.h:1169
struct MHD_itc_ itc
Definition: internal.h:1407
#define mhd_assert(CHK)
Definition: mhd_assert.h:39
time_t last_activity
Definition: internal.h:736
struct MHD_Connection * cleanup_tail
Definition: internal.h:1179
struct MHD_Connection * normal_timeout_tail
Definition: internal.h:1132
struct MHD_Response * response
Definition: internal.h:380
#define MHD_mutex_lock_chk_(pmutex)
Definition: mhd_locks.h:151
bool resuming
Definition: internal.h:1507
#define XDLL_insert(head, tail, element)
Definition: internal.h:1786
#define _(String)
Definition: mhd_options.h:42
struct MHD_Connection * connection
Definition: internal.h:374
bool suspended
Definition: internal.h:761
bool disallow_suspend_resume
Definition: internal.h:1465
struct MHD_Connection * suspended_connections_head
Definition: internal.h:1163
bool MHD_resume_suspended_connections_(struct MHD_Daemon *daemon)
enum MHD_ThreadingMode threading_mode
Definition: internal.h:1414
void * client_context
Definition: internal.h:398
volatile bool shutdown
Definition: internal.h:1523
MHD_mutex_ cleanup_connection_mutex
Definition: internal.h:1262