GNU libmicrohttpd 0.9.77
Loading...
Searching...
No Matches
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
67enum 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)
96static bool
97urh_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
164
165#endif
166
167
181static enum MHD_StatusCode
183 fd_set *read_fd_set,
184 fd_set *write_fd_set,
185 fd_set *except_fd_set,
186 MHD_socket *max_fd,
187 unsigned int fd_setsize)
188
189{
190 struct MHD_Connection *pos;
191 struct MHD_Connection *posn;
192 enum MHD_StatusCode result = MHD_SC_OK;
193 MHD_socket ls;
194
195 if (daemon->shutdown)
196 return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
197
198 ls = daemon->listen_socket;
199 if ( (MHD_INVALID_SOCKET != ls) &&
200 (! daemon->was_quiesced) &&
201 (! MHD_add_to_fd_set_ (ls,
202 read_fd_set,
203 max_fd,
204 fd_setsize)) )
205 result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
206
207 /* Add all sockets to 'except_fd_set' as well to watch for
208 * out-of-band data. However, ignore errors if INFO_READ
209 * or INFO_WRITE sockets will not fit 'except_fd_set'. */
210 /* Start from oldest connections. Make sense for W32 FDSETs. */
211 for (pos = daemon->connections_tail; NULL != pos; pos = posn)
212 {
213 posn = pos->prev;
214
215 switch (pos->request.event_loop_info)
216 {
218 if (! MHD_add_to_fd_set_ (pos->socket_fd,
219 read_fd_set,
220 max_fd,
221 fd_setsize))
222 result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
223#ifdef MHD_POSIX_SOCKETS
225 except_fd_set,
226 max_fd,
227 fd_setsize);
228#endif /* MHD_POSIX_SOCKETS */
229 break;
231 if (! MHD_add_to_fd_set_ (pos->socket_fd,
232 write_fd_set,
233 max_fd,
234 fd_setsize))
235 result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
236#ifdef MHD_POSIX_SOCKETS
238 except_fd_set,
239 max_fd,
240 fd_setsize);
241#endif /* MHD_POSIX_SOCKETS */
242 break;
244 if ( (NULL == except_fd_set) ||
246 except_fd_set,
247 max_fd,
248 fd_setsize))
249 result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
250 break;
252 /* this should never happen */
253 break;
254 }
255 }
256#ifdef MHD_WINSOCK_SOCKETS
257 /* W32 use limited array for fd_set so add INFO_READ/INFO_WRITE sockets
258 * only after INFO_BLOCK sockets to ensure that INFO_BLOCK sockets will
259 * not be pushed out. */
260 for (pos = daemon->connections_tail; NULL != pos; pos = posn)
261 {
262 posn = pos->prev;
264 except_fd_set,
265 max_fd,
266 fd_setsize);
267 }
268#endif /* MHD_WINSOCK_SOCKETS */
269#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
270 {
271 struct MHD_UpgradeResponseHandle *urh;
272
273 for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev)
274 {
275 if (! urh_to_fdset (urh,
276 read_fd_set,
277 write_fd_set,
278 except_fd_set,
279 max_fd,
280 fd_setsize))
281 result = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
282 }
283 }
284#endif
285 return result;
286}
287
288
316enum MHD_StatusCode
318 fd_set *read_fd_set,
319 fd_set *write_fd_set,
320 fd_set *except_fd_set,
321 MHD_socket *max_fd,
322 unsigned int fd_setsize)
323{
324 if ( (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) ||
325 (MHD_ELS_POLL == daemon->event_loop_syscall) )
326 return MHD_SC_CONFIGURATION_MISMATCH_FOR_GET_FDSET;
327
328#ifdef EPOLL_SUPPORT
329 if (MHD_ELS_EPOLL == daemon->event_loop_syscall)
330 {
331 if (daemon->shutdown)
332 return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
333
334 /* we're in epoll mode, use the epoll FD as a stand-in for
335 the entire event set */
336
337 return MHD_add_to_fd_set_ (daemon->epoll_fd,
338 read_fd_set,
339 max_fd,
340 fd_setsize)
341 ? MHD_SC_OK
342 : MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
343 }
344#endif
345
346 return internal_get_fdset2 (daemon,
347 read_fd_set,
348 write_fd_set,
349 except_fd_set,
350 max_fd,
351 fd_setsize);
352}
353
354
355#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
365static void
366urh_from_fdset (struct MHD_UpgradeResponseHandle *urh,
367 const fd_set *rs,
368 const fd_set *ws,
369 const fd_set *es)
370{
371 const MHD_socket conn_sckt = urh->connection->socket_fd;
372 const MHD_socket mhd_sckt = urh->mhd.socket;
373
374 /* Reset read/write ready, preserve error state. */
375 urh->app.celi &= (~MHD_EPOLL_STATE_READ_READY & ~MHD_EPOLL_STATE_WRITE_READY);
376 urh->mhd.celi &= (~MHD_EPOLL_STATE_READ_READY & ~MHD_EPOLL_STATE_WRITE_READY);
377
378 if (MHD_INVALID_SOCKET != conn_sckt)
379 {
380 if (FD_ISSET (conn_sckt, rs))
381 urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
382 if (FD_ISSET (conn_sckt, ws))
383 urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
384 if (FD_ISSET (conn_sckt, es))
385 urh->app.celi |= MHD_EPOLL_STATE_ERROR;
386 }
387 if ((MHD_INVALID_SOCKET != mhd_sckt))
388 {
389 if (FD_ISSET (mhd_sckt, rs))
390 urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
391 if (FD_ISSET (mhd_sckt, ws))
392 urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
393 if (FD_ISSET (mhd_sckt, es))
394 urh->mhd.celi |= MHD_EPOLL_STATE_ERROR;
395 }
396}
397
398
399#endif
400
401
412static enum MHD_StatusCode
414 const fd_set *read_fd_set,
415 const fd_set *write_fd_set,
416 const fd_set *except_fd_set)
417{
418 MHD_socket ds;
419 struct MHD_Connection *pos;
420 struct MHD_Connection *prev;
421#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
422 struct MHD_UpgradeResponseHandle *urh;
423 struct MHD_UpgradeResponseHandle *urhn;
424#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
425 /* Reset. New value will be set when connections are processed. */
426 /* Note: no-op for thread-per-connection as it is always false in that mode. */
427 daemon->data_already_pending = false;
428
429 /* Clear ITC to avoid spinning select */
430 /* Do it before any other processing so new signals
431 will trigger select again and will be processed */
432 if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
433 (FD_ISSET (MHD_itc_r_fd_ (daemon->itc),
434 read_fd_set)) )
435 MHD_itc_clear_ (daemon->itc);
436
437 /* select connection thread handling type */
438 if ( (MHD_INVALID_SOCKET != (ds = daemon->listen_socket)) &&
439 (! daemon->was_quiesced) &&
440 (FD_ISSET (ds,
441 read_fd_set)) )
442 (void) MHD_accept_connection_ (daemon);
443
444 if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode)
445 {
446 /* do not have a thread per connection, process all connections now */
447 prev = daemon->connections_tail;
448 while (NULL != (pos = prev))
449 {
450 prev = pos->prev;
451 ds = pos->socket_fd;
452 if (MHD_INVALID_SOCKET == ds)
453 continue;
455 FD_ISSET (ds,
456 read_fd_set),
457 FD_ISSET (ds,
458 write_fd_set),
459 FD_ISSET (ds,
460 except_fd_set));
461 }
462 }
463
464#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
465 /* handle upgraded HTTPS connections */
466 for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
467 {
468 urhn = urh->prev;
469 /* update urh state based on select() output */
470 urh_from_fdset (urh,
471 read_fd_set,
472 write_fd_set,
473 except_fd_set);
474 /* call generic forwarding function for passing data */
475 MHD_upgrade_response_handle_process_ (urh);
476 /* Finished forwarding? */
477 if ( (0 == urh->in_buffer_size) &&
478 (0 == urh->out_buffer_size) &&
479 (0 == urh->in_buffer_used) &&
480 (0 == urh->out_buffer_used) )
481 {
482 MHD_connection_finish_forward_ (urh->connection);
483 urh->clean_ready = true;
484 /* Resuming will move connection to cleanup list. */
485 MHD_request_resume (&urh->connection->request);
486 }
487 }
488#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
490 return MHD_SC_OK;
491}
492
493
494#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
501void
502MHD_daemon_upgrade_connection_with_select_ (struct MHD_Connection *con)
503{
504 struct MHD_UpgradeResponseHandle *urh = con->request.urh;
505
506 while ( (0 != urh->in_buffer_size) ||
507 (0 != urh->out_buffer_size) ||
508 (0 != urh->in_buffer_used) ||
509 (0 != urh->out_buffer_used) )
510 {
511 /* use select */
512 fd_set rs;
513 fd_set ws;
514 fd_set es;
515 MHD_socket max_fd;
516 int num_ready;
517 bool result;
518
519 FD_ZERO (&rs);
520 FD_ZERO (&ws);
521 FD_ZERO (&es);
522 max_fd = MHD_INVALID_SOCKET;
523 result = urh_to_fdset (urh,
524 &rs,
525 &ws,
526 &es,
527 &max_fd,
528 FD_SETSIZE);
529 if (! result)
530 {
531#ifdef HAVE_MESSAGES
532 MHD_DLOG (con->daemon,
533 MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE,
534 _ ("Error preparing select.\n"));
535#endif
536 break;
537 }
538 /* FIXME: does this check really needed? */
539 if (MHD_INVALID_SOCKET != max_fd)
540 {
541 struct timeval *tvp;
542 struct timeval tv;
543 if ( (con->tls_read_ready) &&
544 (urh->in_buffer_used < urh->in_buffer_size))
545 { /* No need to wait if incoming data is already pending in TLS buffers. */
546 tv.tv_sec = 0;
547 tv.tv_usec = 0;
548 tvp = &tv;
549 }
550 else
551 tvp = NULL;
552 num_ready = MHD_SYS_select_ (max_fd + 1,
553 &rs,
554 &ws,
555 &es,
556 tvp);
557 }
558 else
559 num_ready = 0;
560 if (num_ready < 0)
561 {
562 const int err = MHD_socket_get_error_ ();
563
564 if (MHD_SCKT_ERR_IS_EINTR_ (err))
565 continue;
566#ifdef HAVE_MESSAGES
567 MHD_DLOG (con->daemon,
568 MHD_SC_UNEXPECTED_SELECT_ERROR,
569 _ ("Error during select (%d): `%s'\n"),
570 err,
571 MHD_socket_strerr_ (err));
572#endif
573 break;
574 }
575 urh_from_fdset (urh,
576 &rs,
577 &ws,
578 &es);
579 MHD_upgrade_response_handle_process_ (urh);
580 }
581}
582
583
584#endif
585
586
609enum MHD_StatusCode
611 const fd_set *read_fd_set,
612
613
614 const fd_set *write_fd_set,
615 const fd_set *except_fd_set)
616{
617 if ( (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) ||
618 (MHD_ELS_POLL == daemon->event_loop_syscall) )
619 return MHD_SC_CONFIGURATION_MISMATCH_FOR_RUN_SELECT;
620 if (MHD_ELS_EPOLL == daemon->event_loop_syscall)
621 {
622#ifdef EPOLL_SUPPORT
623 enum MHD_StatusCode sc;
624
625 sc = MHD_daemon_epoll_ (daemon,
626 MHD_NO);
628 return sc;
629#else /* ! EPOLL_SUPPORT */
630 return MHD_NO;
631#endif /* ! EPOLL_SUPPORT */
632 }
633
634 /* Resuming external connections when using an extern mainloop */
635 if (! daemon->disallow_suspend_resume)
636 (void) MHD_resume_suspended_connections_ (daemon);
637
638 return internal_run_from_select (daemon,
639 read_fd_set,
640 write_fd_set,
641 except_fd_set);
642}
643
644
653enum MHD_StatusCode
655 int may_block)
656{
657 int num_ready;
658 fd_set rs;
659 fd_set ws;
660 fd_set es;
661 MHD_socket maxsock;
662 struct timeval timeout;
663 struct timeval *tv;
664 MHD_UNSIGNED_LONG_LONG ltimeout;
665 MHD_socket ls;
666 enum MHD_StatusCode sc;
667 enum MHD_StatusCode sc2;
668
669 timeout.tv_sec = 0;
670 timeout.tv_usec = 0;
671 if (daemon->shutdown)
672 return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
673 FD_ZERO (&rs);
674 FD_ZERO (&ws);
675 FD_ZERO (&es);
676 maxsock = MHD_INVALID_SOCKET;
677 sc = MHD_SC_OK;
678 if ( (! daemon->disallow_suspend_resume) &&
680 (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) )
681 may_block = MHD_NO;
682
683 if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode)
684 {
685
686 /* single-threaded, go over everything */
687 if (MHD_SC_OK !=
688 (sc = internal_get_fdset2 (daemon,
689 &rs,
690 &ws,
691 &es,
692 &maxsock,
693 FD_SETSIZE)))
694 {
695#ifdef HAVE_MESSAGES
696 MHD_DLOG (daemon,
697 sc,
698 _ ("Could not obtain daemon fdsets.\n"));
699#endif
700 }
701 }
702 else
703 {
704 /* accept only, have one thread per connection */
705 if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) &&
706 (! daemon->was_quiesced) &&
707 (! MHD_add_to_fd_set_ (ls,
708 &rs,
709 &maxsock,
710 FD_SETSIZE)) )
711 {
712#ifdef HAVE_MESSAGES
713 MHD_DLOG (daemon,
714 MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE,
715 _ ("Could not add listen socket to fdset.\n"));
716#endif
717 return MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
718 }
719 }
720 if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
721 (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
722 &rs,
723 &maxsock,
724 FD_SETSIZE)) )
725 {
726#if defined(MHD_WINSOCK_SOCKETS)
727 /* fdset limit reached, new connections
728 cannot be handled. Remove listen socket FD
729 from fdset and retry to add ITC FD. */
730 if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) &&
731 (! daemon->was_quiesced) )
732 {
733 FD_CLR (ls,
734 &rs);
735 if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
736 &rs,
737 &maxsock,
738 FD_SETSIZE))
739 {
740#endif /* MHD_WINSOCK_SOCKETS */
741 sc = MHD_SC_SOCKET_OUTSIDE_OF_FDSET_RANGE;
742#ifdef HAVE_MESSAGES
743 MHD_DLOG (daemon,
744 sc,
745 _ (
746 "Could not add control inter-thread communication channel FD to fdset.\n"));
747#endif
748#if defined(MHD_WINSOCK_SOCKETS)
749 }
750}
751
752
753#endif /* MHD_WINSOCK_SOCKETS */
754 }
755 /* Stop listening if we are at the configured connection limit */
756 /* If we're at the connection limit, no point in really
757 accepting new connections; however, make sure we do not miss
758 the shutdown OR the termination of an existing connection; so
759 only do this optimization if we have a signaling ITC in
760 place. */
761 if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_socket)) &&
762 (MHD_ITC_IS_VALID_ (daemon->itc)) &&
763 ( (daemon->connections == daemon->global_connection_limit) ||
764 (daemon->at_limit) ) )
765 {
766 FD_CLR (ls,
767 &rs);
768 }
769 tv = NULL;
770 if (MHD_SC_OK != sc)
771 may_block = MHD_NO;
772 if (MHD_NO == may_block)
773 {
774 timeout.tv_usec = 0;
775 timeout.tv_sec = 0;
776 tv = &timeout;
777 }
778 else if ( (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode) &&
779 (MHD_SC_OK ==
781 &ltimeout)) )
782 {
783 /* ltimeout is in ms */
784 timeout.tv_usec = (ltimeout % 1000) * 1000;
785 if (ltimeout / 1000 > TIMEVAL_TV_SEC_MAX)
786 timeout.tv_sec = TIMEVAL_TV_SEC_MAX;
787 else
788 timeout.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) (ltimeout / 1000);
789 tv = &timeout;
790 }
791 num_ready = MHD_SYS_select_ (maxsock + 1,
792 &rs,
793 &ws,
794 &es,
795 tv);
796 if (daemon->shutdown)
797 return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
798 if (num_ready < 0)
799 {
800 const int err = MHD_socket_get_error_ ();
801
802 if (MHD_SCKT_ERR_IS_EINTR_ (err))
803 return sc;
804#ifdef HAVE_MESSAGES
805 MHD_DLOG (daemon,
806 MHD_SC_UNEXPECTED_SELECT_ERROR,
807 _ ("select failed: %s\n"),
808 MHD_socket_strerr_ (err));
809#endif
810 return MHD_SC_UNEXPECTED_SELECT_ERROR;
811 }
812 if (MHD_SC_OK !=
813 (sc2 = internal_run_from_select (daemon,
814 &rs,
815 &ws,
816 &es)))
817 return sc2;
818 return sc;
819}
820
821/* end of daemon_select.c */
#define MHD_connection_finish_forward_(conn)
Definition connection.h:165
enum MHD_StatusCode MHD_accept_connection_(struct MHD_Daemon *daemon)
functions to add connection to our active set
int MHD_connection_call_handlers_(struct MHD_Connection *con, bool read_ready, bool write_ready, bool force_close)
function to call event handlers based on event mask
void MHD_connection_cleanup_(struct MHD_Daemon *daemon)
functions to cleanup completed connection
complete upgrade socket forwarding operation in TLS mode
non-public functions provided by daemon_epoll.c
enum MHD_StatusCode MHD_daemon_select_(struct MHD_Daemon *daemon, int may_block)
non-public functions provided by daemon_select.c
enum MHD_StatusCode MHD_daemon_get_timeout(struct MHD_Daemon *daemon, MHD_UNSIGNED_LONG_LONG *timeout)
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)
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)
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)
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)
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)
@ MHD_EPOLL_STATE_READ_READY
Definition internal.h:600
@ MHD_EPOLL_STATE_WRITE_READY
Definition internal.h:606
@ MHD_EPOLL_STATE_ERROR
Definition internal.h:626
#define TIMEVAL_TV_SEC_MAX
Definition mhd_limits.h:140
int MHD_add_to_fd_set_(MHD_socket fd, fd_set *set, MHD_socket *max_fd, unsigned int fd_setsize)
#define _MHD_SYS_DEFAULT_FD_SETSIZE
#define MHD_socket_strerr_(err)
#define MHD_socket_get_error_()
#define MHD_SCKT_ERR_IS_EINTR_(err)
#define MHD_SYS_select_(n, r, w, e, t)
#define NULL
#define _(String)
Definition mhd_options.h:42
MHD internal shared structures.
@ MHD_EVENT_LOOP_INFO_READ
Definition internal.h:246
@ MHD_EVENT_LOOP_INFO_WRITE
Definition internal.h:251
@ MHD_EVENT_LOOP_INFO_CLEANUP
Definition internal.h:261
@ MHD_EVENT_LOOP_INFO_BLOCK
Definition internal.h:256
int MHD_socket
Definition microhttpd.h:207
@ MHD_NO
Definition microhttpd.h:162
#define MHD_UNSIGNED_LONG_LONG
Definition microhttpd.h:311
#define MHD_INVALID_SOCKET
Definition microhttpd.h:208
time_t _MHD_TIMEVAL_TV_SEC_TYPE
Definition platform.h:126
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
bool tls_read_ready
Definition internal.h:769
struct MHD_Request request
Definition internal.h:717
struct MHD_Connection * prev
Definition internal.h:656
struct MHD_Daemon * daemon
Definition internal.h:675
bool data_already_pending
Definition internal.h:1500
bool at_limit
Definition internal.h:1483
bool was_quiesced
Definition internal.h:1505
unsigned int connections
Definition internal.h:1361
struct MHD_itc_ itc
Definition internal.h:1410
enum MHD_EventLoopSyscall event_loop_syscall
Definition internal.h:1436
volatile bool shutdown
Definition internal.h:1526
bool disallow_suspend_resume
Definition internal.h:1468
MHD_socket listen_socket
Definition internal.h:1377
enum MHD_ThreadingMode threading_mode
Definition internal.h:1417
unsigned int global_connection_limit
Definition internal.h:1351
struct MHD_Connection * connections_tail
Definition internal.h:1160
enum MHD_RequestEventLoopInfo event_loop_info
Definition internal.h:559
function to process upgrade activity (over TLS)