GNU libmicrohttpd  0.9.65
daemon_select.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_add.h"
28 #include "connection_cleanup.h"
30 #include "daemon_select.h"
31 #include "daemon_epoll.h"
32 #include "request_resume.h"
33 #include "upgrade_process.h"
34 
35 
41 #undef MHD_daemon_get_fdset
42 
67 enum MHD_StatusCode
69  fd_set *read_fd_set,
70  fd_set *write_fd_set,
71  fd_set *except_fd_set,
72  MHD_socket *max_fd)
73 {
74  return MHD_daemon_get_fdset2 (daemon,
75  read_fd_set,
76  write_fd_set,
77  except_fd_set,
78  max_fd,
80 }
81 
82 
83 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
84 
96 static bool
97 urh_to_fdset (struct MHD_UpgradeResponseHandle *urh,
98  fd_set *rs,
99  fd_set *ws,
100  fd_set *es,
101  MHD_socket *max_fd,
102  unsigned int fd_setsize)
103 {
104  const MHD_socket conn_sckt = urh->connection->socket_fd;
105  const MHD_socket mhd_sckt = urh->mhd.socket;
106  bool res = true;
107 
108  /* Do not add to 'es' only if socket is closed
109  * or not used anymore. */
110  if (MHD_INVALID_SOCKET != conn_sckt)
111  {
112  if ( (urh->in_buffer_used < urh->in_buffer_size) &&
113  (! MHD_add_to_fd_set_ (conn_sckt,
114  rs,
115  max_fd,
116  fd_setsize)) )
117  res = false;
118  if ( (0 != urh->out_buffer_used) &&
119  (! MHD_add_to_fd_set_ (conn_sckt,
120  ws,
121  max_fd,
122  fd_setsize)) )
123  res = false;
124  /* Do not monitor again for errors if error was detected before as
125  * error state is remembered. */
126  if ((0 == (urh->app.celi & MHD_EPOLL_STATE_ERROR)) &&
127  ((0 != urh->in_buffer_size) ||
128  (0 != urh->out_buffer_size) ||
129  (0 != urh->out_buffer_used)))
130  MHD_add_to_fd_set_ (conn_sckt,
131  es,
132  max_fd,
133  fd_setsize);
134  }
135  if (MHD_INVALID_SOCKET != mhd_sckt)
136  {
137  if ( (urh->out_buffer_used < urh->out_buffer_size) &&
138  (! MHD_add_to_fd_set_ (mhd_sckt,
139  rs,
140  max_fd,
141  fd_setsize)) )
142  res = false;
143  if ( (0 != urh->in_buffer_used) &&
144  (! MHD_add_to_fd_set_ (mhd_sckt,
145  ws,
146  max_fd,
147  fd_setsize)) )
148  res = false;
149  /* Do not monitor again for errors if error was detected before as
150  * error state is remembered. */
151  if ((0 == (urh->mhd.celi & MHD_EPOLL_STATE_ERROR)) &&
152  ((0 != urh->out_buffer_size) ||
153  (0 != urh->in_buffer_size) ||
154  (0 != urh->in_buffer_used)))
155  MHD_add_to_fd_set_ (mhd_sckt,
156  es,
157  max_fd,
158  fd_setsize);
159  }
160 
161  return res;
162 }
163 #endif
164 
165 
179 static enum MHD_StatusCode
181  fd_set *read_fd_set,
182  fd_set *write_fd_set,
183  fd_set *except_fd_set,
184  MHD_socket *max_fd,
185  unsigned int fd_setsize)
186 
187 {
188  struct MHD_Connection *pos;
189  struct MHD_Connection *posn;
190  enum MHD_StatusCode result = MHD_SC_OK;
191  MHD_socket ls;
192 
193  if (daemon->shutdown)
194  return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
195 
196  ls = daemon->listen_socket;
197  if ( (MHD_INVALID_SOCKET != ls) &&
198  (! daemon->was_quiesced) &&
199  (! MHD_add_to_fd_set_ (ls,
200  read_fd_set,
201  max_fd,
202  fd_setsize)) )
203  result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
204 
205  /* Add all sockets to 'except_fd_set' as well to watch for
206  * out-of-band data. However, ignore errors if INFO_READ
207  * or INFO_WRITE sockets will not fit 'except_fd_set'. */
208  /* Start from oldest connections. Make sense for W32 FDSETs. */
209  for (pos = daemon->connections_tail; NULL != pos; pos = posn)
210  {
211  posn = pos->prev;
212 
213  switch (pos->request.event_loop_info)
214  {
216  if (! MHD_add_to_fd_set_ (pos->socket_fd,
217  read_fd_set,
218  max_fd,
219  fd_setsize))
220  result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
221 #ifdef MHD_POSIX_SOCKETS
223  except_fd_set,
224  max_fd,
225  fd_setsize);
226 #endif /* MHD_POSIX_SOCKETS */
227  break;
229  if (! MHD_add_to_fd_set_ (pos->socket_fd,
230  write_fd_set,
231  max_fd,
232  fd_setsize))
233  result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
234 #ifdef MHD_POSIX_SOCKETS
236  except_fd_set,
237  max_fd,
238  fd_setsize);
239 #endif /* MHD_POSIX_SOCKETS */
240  break;
242  if ( (NULL == except_fd_set) ||
244  except_fd_set,
245  max_fd,
246  fd_setsize))
247  result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
248  break;
250  /* this should never happen */
251  break;
252  }
253  }
254 #ifdef MHD_WINSOCK_SOCKETS
255  /* W32 use limited array for fd_set so add INFO_READ/INFO_WRITE sockets
256  * only after INFO_BLOCK sockets to ensure that INFO_BLOCK sockets will
257  * not be pushed out. */
258  for (pos = daemon->connections_tail; NULL != pos; pos = posn)
259  {
260  posn = pos->prev;
262  except_fd_set,
263  max_fd,
264  fd_setsize);
265  }
266 #endif /* MHD_WINSOCK_SOCKETS */
267 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
268  {
269  struct MHD_UpgradeResponseHandle *urh;
270 
271  for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev)
272  {
273  if (! urh_to_fdset (urh,
274  read_fd_set,
275  write_fd_set,
276  except_fd_set,
277  max_fd,
278  fd_setsize))
279  result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
280  }
281  }
282 #endif
283  return result;
284 }
285 
286 
314 enum MHD_StatusCode
316  fd_set *read_fd_set,
317  fd_set *write_fd_set,
318  fd_set *except_fd_set,
319  MHD_socket *max_fd,
320  unsigned int fd_setsize)
321 {
322  if ( (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) ||
323  (MHD_ELS_POLL == daemon->event_loop_syscall) )
324  return MHD_SC_CONFIGURATION_MISMATCH_FOR_GET_FDSET;
325 
326 #ifdef EPOLL_SUPPORT
327  if (MHD_ELS_EPOLL == daemon->event_loop_syscall)
328  {
329  if (daemon->shutdown)
330  return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
331 
332  /* we're in epoll mode, use the epoll FD as a stand-in for
333  the entire event set */
334 
335  return MHD_add_to_fd_set_ (daemon->epoll_fd,
336  read_fd_set,
337  max_fd,
338  fd_setsize)
339  ? MHD_SC_OK
340  : MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
341  }
342 #endif
343 
344  return internal_get_fdset2 (daemon,
345  read_fd_set,
346  write_fd_set,
347  except_fd_set,
348  max_fd,
349  fd_setsize);
350 }
351 
352 
353 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
354 
363 static void
364 urh_from_fdset (struct MHD_UpgradeResponseHandle *urh,
365  const fd_set *rs,
366  const fd_set *ws,
367  const fd_set *es)
368 {
369  const MHD_socket conn_sckt = urh->connection->socket_fd;
370  const MHD_socket mhd_sckt = urh->mhd.socket;
371 
372  /* Reset read/write ready, preserve error state. */
375 
376  if (MHD_INVALID_SOCKET != conn_sckt)
377  {
378  if (FD_ISSET (conn_sckt, rs))
379  urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
380  if (FD_ISSET (conn_sckt, ws))
381  urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
382  if (FD_ISSET (conn_sckt, es))
383  urh->app.celi |= MHD_EPOLL_STATE_ERROR;
384  }
385  if ((MHD_INVALID_SOCKET != mhd_sckt))
386  {
387  if (FD_ISSET (mhd_sckt, rs))
388  urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
389  if (FD_ISSET (mhd_sckt, ws))
390  urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
391  if (FD_ISSET (mhd_sckt, es))
392  urh->mhd.celi |= MHD_EPOLL_STATE_ERROR;
393  }
394 }
395 #endif
396 
397 
408 static enum MHD_StatusCode
410  const fd_set *read_fd_set,
411  const fd_set *write_fd_set,
412  const fd_set *except_fd_set)
413 {
414  MHD_socket ds;
415  struct MHD_Connection *pos;
416  struct MHD_Connection *prev;
417 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
418  struct MHD_UpgradeResponseHandle *urh;
419  struct MHD_UpgradeResponseHandle *urhn;
420 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
421  /* Reset. New value will be set when connections are processed. */
422  /* Note: no-op for thread-per-connection as it is always false in that mode. */
423  daemon->data_already_pending = false;
424 
425  /* Clear ITC to avoid spinning select */
426  /* Do it before any other processing so new signals
427  will trigger select again and will be processed */
428  if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
429  (FD_ISSET (MHD_itc_r_fd_ (daemon->itc),
430  read_fd_set)) )
431  MHD_itc_clear_ (daemon->itc);
432 
433  /* select connection thread handling type */
434  if ( (MHD_INVALID_SOCKET != (ds = daemon->listen_socket)) &&
435  (! daemon->was_quiesced) &&
436  (FD_ISSET (ds,
437  read_fd_set)) )
438  (void) MHD_accept_connection_ (daemon);
439 
440  if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode)
441  {
442  /* do not have a thread per connection, process all connections now */
443  prev = daemon->connections_tail;
444  while (NULL != (pos = prev))
445  {
446  prev = pos->prev;
447  ds = pos->socket_fd;
448  if (MHD_INVALID_SOCKET == ds)
449  continue;
451  FD_ISSET (ds,
452  read_fd_set),
453  FD_ISSET (ds,
454  write_fd_set),
455  FD_ISSET (ds,
456  except_fd_set));
457  }
458  }
459 
460 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
461  /* handle upgraded HTTPS connections */
462  for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
463  {
464  urhn = urh->prev;
465  /* update urh state based on select() output */
466  urh_from_fdset (urh,
467  read_fd_set,
468  write_fd_set,
469  except_fd_set);
470  /* call generic forwarding function for passing data */
471  MHD_upgrade_response_handle_process_ (urh);
472  /* Finished forwarding? */
473  if ( (0 == urh->in_buffer_size) &&
474  (0 == urh->out_buffer_size) &&
475  (0 == urh->in_buffer_used) &&
476  (0 == urh->out_buffer_used) )
477  {
478  MHD_connection_finish_forward_ (urh->connection);
479  urh->clean_ready = true;
480  /* Resuming will move connection to cleanup list. */
481  MHD_request_resume (&urh->connection->request);
482  }
483  }
484 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
485  MHD_connection_cleanup_ (daemon);
486  return MHD_SC_OK;
487 }
488 
489 
490 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
491 
497 void
498 MHD_daemon_upgrade_connection_with_select_ (struct MHD_Connection *con)
499 {
500  struct MHD_UpgradeResponseHandle *urh = con->request.urh;
501 
502  while ( (0 != urh->in_buffer_size) ||
503  (0 != urh->out_buffer_size) ||
504  (0 != urh->in_buffer_used) ||
505  (0 != urh->out_buffer_used) )
506  {
507  /* use select */
508  fd_set rs;
509  fd_set ws;
510  fd_set es;
511  MHD_socket max_fd;
512  int num_ready;
513  bool result;
514 
515  FD_ZERO (&rs);
516  FD_ZERO (&ws);
517  FD_ZERO (&es);
518  max_fd = MHD_INVALID_SOCKET;
519  result = urh_to_fdset (urh,
520  &rs,
521  &ws,
522  &es,
523  &max_fd,
524  FD_SETSIZE);
525  if (! result)
526  {
527 #ifdef HAVE_MESSAGES
528  MHD_DLOG (con->daemon,
529  MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE,
530  _("Error preparing select\n"));
531 #endif
532  break;
533  }
534  /* FIXME: does this check really needed? */
535  if (MHD_INVALID_SOCKET != max_fd)
536  {
537  struct timeval* tvp;
538  struct timeval tv;
539  if ( (con->tls_read_ready) &&
540  (urh->in_buffer_used < urh->in_buffer_size))
541  { /* No need to wait if incoming data is already pending in TLS buffers. */
542  tv.tv_sec = 0;
543  tv.tv_usec = 0;
544  tvp = &tv;
545  }
546  else
547  tvp = NULL;
548  num_ready = MHD_SYS_select_ (max_fd + 1,
549  &rs,
550  &ws,
551  &es,
552  tvp);
553  }
554  else
555  num_ready = 0;
556  if (num_ready < 0)
557  {
558  const int err = MHD_socket_get_error_();
559 
560  if (MHD_SCKT_ERR_IS_EINTR_(err))
561  continue;
562 #ifdef HAVE_MESSAGES
563  MHD_DLOG (con->daemon,
564  MHD_SC_UNEXPECTED_SELECT_ERROR,
565  _("Error during select (%d): `%s'\n"),
566  err,
567  MHD_socket_strerr_ (err));
568 #endif
569  break;
570  }
571  urh_from_fdset (urh,
572  &rs,
573  &ws,
574  &es);
575  MHD_upgrade_response_handle_process_ (urh);
576  }
577 }
578 #endif
579 
580 
603 enum MHD_StatusCode
605  const fd_set *read_fd_set,
606 
607 
608  const fd_set *write_fd_set,
609  const fd_set *except_fd_set)
610 {
611  if ( (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) ||
612  (MHD_ELS_POLL == daemon->event_loop_syscall) )
613  return MHD_SC_CONFIGURATION_MISSMATCH_FOR_RUN_SELECT;
614  if (MHD_ELS_EPOLL == daemon->event_loop_syscall)
615  {
616 #ifdef EPOLL_SUPPORT
617  enum MHD_StatusCode sc;
618 
619  sc = MHD_daemon_epoll_ (daemon,
620  MHD_NO);
621  MHD_connection_cleanup_ (daemon);
622  return sc;
623 #else /* ! EPOLL_SUPPORT */
624  return MHD_NO;
625 #endif /* ! EPOLL_SUPPORT */
626  }
627 
628  /* Resuming external connections when using an extern mainloop */
629  if (! daemon->disallow_suspend_resume)
630  (void) MHD_resume_suspended_connections_ (daemon);
631 
632  return internal_run_from_select (daemon,
633  read_fd_set,
634  write_fd_set,
635  except_fd_set);
636 }
637 
638 
647 enum MHD_StatusCode
649  int may_block)
650 {
651  int num_ready;
652  fd_set rs;
653  fd_set ws;
654  fd_set es;
655  MHD_socket maxsock;
656  struct timeval timeout;
657  struct timeval *tv;
658  MHD_UNSIGNED_LONG_LONG ltimeout;
659  MHD_socket ls;
660  enum MHD_StatusCode sc;
661  enum MHD_StatusCode sc2;
662 
663  timeout.tv_sec = 0;
664  timeout.tv_usec = 0;
665  if (daemon->shutdown)
666  return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
667  FD_ZERO (&rs);
668  FD_ZERO (&ws);
669  FD_ZERO (&es);
670  maxsock = MHD_INVALID_SOCKET;
671  sc = MHD_SC_OK;
672  if ( (! daemon->disallow_suspend_resume) &&
674  (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) )
675  may_block = MHD_NO;
676 
677  if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode)
678  {
679 
680  /* single-threaded, go over everything */
681  if (MHD_SC_OK !=
682  (sc = internal_get_fdset2 (daemon,
683  &rs,
684  &ws,
685  &es,
686  &maxsock,
687  FD_SETSIZE)))
688  {
689 #ifdef HAVE_MESSAGES
690  MHD_DLOG (daemon,
691  sc,
692  _("Could not obtain daemon fdsets"));
693 #endif
694  }
695  }
696  else
697  {
698  /* accept only, have one thread per connection */
699  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) &&
700  (! daemon->was_quiesced) &&
701  (! MHD_add_to_fd_set_ (ls,
702  &rs,
703  &maxsock,
704  FD_SETSIZE)) )
705  {
706 #ifdef HAVE_MESSAGES
707  MHD_DLOG (daemon,
708  MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE,
709  _("Could not add listen socket to fdset"));
710 #endif
711  return MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
712  }
713  }
714  if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
715  (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
716  &rs,
717  &maxsock,
718  FD_SETSIZE)) )
719  {
720 #if defined(MHD_WINSOCK_SOCKETS)
721  /* fdset limit reached, new connections
722  cannot be handled. Remove listen socket FD
723  from fdset and retry to add ITC FD. */
724  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) &&
725  (! daemon->was_quiesced) )
726  {
727  FD_CLR (ls,
728  &rs);
729  if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_(daemon->itc),
730  &rs,
731  &maxsock,
732  FD_SETSIZE))
733  {
734 #endif /* MHD_WINSOCK_SOCKETS */
735  sc = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
736 #ifdef HAVE_MESSAGES
737  MHD_DLOG (daemon,
738  sc,
739  _("Could not add control inter-thread communication channel FD to fdset"));
740 #endif
741 #if defined(MHD_WINSOCK_SOCKETS)
742  }
743  }
744 #endif /* MHD_WINSOCK_SOCKETS */
745  }
746  /* Stop listening if we are at the configured connection limit */
747  /* If we're at the connection limit, no point in really
748  accepting new connections; however, make sure we do not miss
749  the shutdown OR the termination of an existing connection; so
750  only do this optimization if we have a signaling ITC in
751  place. */
752  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) &&
753  (MHD_ITC_IS_VALID_(daemon->itc)) &&
754  ( (daemon->connections == daemon->global_connection_limit) ||
755  (daemon->at_limit) ) )
756  {
757  FD_CLR (ls,
758  &rs);
759  }
760  tv = NULL;
761  if (MHD_SC_OK != sc)
762  may_block = MHD_NO;
763  if (MHD_NO == may_block)
764  {
765  timeout.tv_usec = 0;
766  timeout.tv_sec = 0;
767  tv = &timeout;
768  }
769  else if ( (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) &&
770  (MHD_SC_OK ==
771  MHD_daemon_get_timeout (daemon,
772  &ltimeout)) )
773  {
774  /* ltimeout is in ms */
775  timeout.tv_usec = (ltimeout % 1000) * 1000;
776  if (ltimeout / 1000 > TIMEVAL_TV_SEC_MAX)
777  timeout.tv_sec = TIMEVAL_TV_SEC_MAX;
778  else
779  timeout.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE)(ltimeout / 1000);
780  tv = &timeout;
781  }
782  num_ready = MHD_SYS_select_ (maxsock + 1,
783  &rs,
784  &ws,
785  &es,
786  tv);
787  if (daemon->shutdown)
788  return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
789  if (num_ready < 0)
790  {
791  const int err = MHD_socket_get_error_ ();
792 
793  if (MHD_SCKT_ERR_IS_EINTR_(err))
794  return sc;
795 #ifdef HAVE_MESSAGES
796  MHD_DLOG (daemon,
797  MHD_SC_UNEXPECTED_SELECT_ERROR,
798  _("select failed: %s\n"),
799  MHD_socket_strerr_ (err));
800 #endif
801  return MHD_SC_UNEXPECTED_SELECT_ERROR;
802  }
803  if (MHD_SC_OK !=
804  (sc2 = internal_run_from_select (daemon,
805  &rs,
806  &ws,
807  &es)))
808  return sc2;
809  return sc;
810 }
811 
812 /* end of daemon_select.c */
struct MHD_Request request
Definition: internal.h:714
enum MHD_EventLoopSyscall event_loop_syscall
Definition: internal.h:1433
bool data_already_pending
Definition: internal.h:1497
#define MHD_SYS_select_(n, r, w, e, t)
Definition: mhd_sockets.h:323
non-public functions provided by daemon_select.c
unsigned int global_connection_limit
Definition: internal.h:1348
#define MHD_socket_get_error_()
Definition: mhd_sockets.h:507
#define MHD_socket_strerr_(err)
Definition: mhd_sockets.h:525
enum MHD_StatusCode MHD_daemon_select_(struct MHD_Daemon *daemon, int may_block)
enum MHD_StatusCode MHD_daemon_get_fdset2(struct MHD_Daemon *daemon, fd_set *read_fd_set, fd_set *write_fd_set, fd_set *except_fd_set, MHD_socket *max_fd, unsigned int fd_setsize)
int MHD_add_to_fd_set_(MHD_socket fd, fd_set *set, MHD_socket *max_fd, unsigned int fd_setsize)
Definition: mhd_sockets.c:374
non-public functions provided by daemon_epoll.c
int MHD_socket
Definition: microhttpd.h:187
internal shared structures
MHD_socket listen_socket
Definition: internal.h:1374
#define MHD_UNSIGNED_LONG_LONG
Definition: microhttpd.h:283
struct MHD_Daemon * daemon
Definition: internal.h:672
bool was_quiesced
Definition: internal.h:1502
struct MHD_Connection * connections_tail
Definition: internal.h:1157
enum MHD_StatusCode MHD_daemon_get_timeout(struct MHD_Daemon *daemon, MHD_UNSIGNED_LONG_LONG *timeout)
#define MHD_INVALID_SOCKET
Definition: microhttpd.h:188
MHD_socket socket_fd
Definition: internal.h:749
enum MHD_StatusCode MHD_daemon_run_from_select(struct MHD_Daemon *daemon, const fd_set *read_fd_set, const fd_set *write_fd_set, const fd_set *except_fd_set)
complete upgrade socket forwarding operation in TLS mode
time_t _MHD_TIMEVAL_TV_SEC_TYPE
Definition: platform.h:122
enum MHD_RequestEventLoopInfo event_loop_info
Definition: internal.h:556
function to call event handlers based on event mask
enum MHD_StatusCode MHD_accept_connection_(struct MHD_Daemon *daemon)
functions to cleanup completed connection
#define NULL
Definition: reason_phrase.c:30
unsigned int connections
Definition: internal.h:1358
struct MHD_Connection * prev
Definition: internal.h:653
#define TIMEVAL_TV_SEC_MAX
Definition: mhd_limits.h:140
#define _MHD_SYS_DEFAULT_FD_SETSIZE
Definition: mhd_sockets.h:126
int MHD_connection_call_handlers_(struct MHD_Connection *con, bool read_ready, bool write_ready, bool force_close)
void MHD_request_resume(struct MHD_Request *request)
void MHD_connection_finish_forward_(struct MHD_Connection *connection) MHD_NONNULL(1)
bool tls_read_ready
Definition: internal.h:766
struct MHD_itc_ itc
Definition: internal.h:1407
static enum MHD_StatusCode internal_run_from_select(struct MHD_Daemon *daemon, const fd_set *read_fd_set, const fd_set *write_fd_set, const fd_set *except_fd_set)
static enum MHD_StatusCode internal_get_fdset2(struct MHD_Daemon *daemon, fd_set *read_fd_set, fd_set *write_fd_set, fd_set *except_fd_set, MHD_socket *max_fd, unsigned int fd_setsize)
void MHD_connection_cleanup_(struct MHD_Daemon *daemon)
bool at_limit
Definition: internal.h:1480
#define _(String)
Definition: mhd_options.h:42
bool disallow_suspend_resume
Definition: internal.h:1465
enum MHD_StatusCode MHD_daemon_get_fdset(struct MHD_Daemon *daemon, fd_set *read_fd_set, fd_set *write_fd_set, fd_set *except_fd_set, MHD_socket *max_fd)
Definition: daemon_select.c:68
bool MHD_resume_suspended_connections_(struct MHD_Daemon *daemon)
#define MHD_NO
Definition: microhttpd.h:145
enum MHD_ThreadingMode threading_mode
Definition: internal.h:1414
volatile bool shutdown
Definition: internal.h:1523
#define MHD_SCKT_ERR_IS_EINTR_(err)
Definition: mhd_sockets.h:613
function to process upgrade activity (over TLS)
functions to add connection to our active set
implementation of MHD_request_resume()