diff options
Diffstat (limited to 'src/microhttpd/daemon.c')
-rw-r--r-- | src/microhttpd/daemon.c | 323 |
1 files changed, 254 insertions, 69 deletions
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c index 2489728f..d8151bea 100644 --- a/src/microhttpd/daemon.c +++ b/src/microhttpd/daemon.c | |||
@@ -726,7 +726,7 @@ urh_to_fdset (struct MHD_UpgradeResponseHandle *urh, | |||
726 | fd_set *ws, | 726 | fd_set *ws, |
727 | fd_set *es, | 727 | fd_set *es, |
728 | MHD_socket *max_fd, | 728 | MHD_socket *max_fd, |
729 | unsigned int fd_setsize) | 729 | int fd_setsize) |
730 | { | 730 | { |
731 | const MHD_socket conn_sckt = urh->connection->socket_fd; | 731 | const MHD_socket conn_sckt = urh->connection->socket_fd; |
732 | const MHD_socket mhd_sckt = urh->mhd.socket; | 732 | const MHD_socket mhd_sckt = urh->mhd.socket; |
@@ -799,12 +799,14 @@ urh_to_fdset (struct MHD_UpgradeResponseHandle *urh, | |||
799 | * @param rs read result from select() | 799 | * @param rs read result from select() |
800 | * @param ws write result from select() | 800 | * @param ws write result from select() |
801 | * @param es except result from select() | 801 | * @param es except result from select() |
802 | * @param fd_setsize value of FD_SETSIZE used when fd_sets were created | ||
802 | */ | 803 | */ |
803 | static void | 804 | static void |
804 | urh_from_fdset (struct MHD_UpgradeResponseHandle *urh, | 805 | urh_from_fdset (struct MHD_UpgradeResponseHandle *urh, |
805 | const fd_set *rs, | 806 | const fd_set *rs, |
806 | const fd_set *ws, | 807 | const fd_set *ws, |
807 | const fd_set *es) | 808 | const fd_set *es, |
809 | int fd_setsize) | ||
808 | { | 810 | { |
809 | const MHD_socket conn_sckt = urh->connection->socket_fd; | 811 | const MHD_socket conn_sckt = urh->connection->socket_fd; |
810 | const MHD_socket mhd_sckt = urh->mhd.socket; | 812 | const MHD_socket mhd_sckt = urh->mhd.socket; |
@@ -815,25 +817,49 @@ urh_from_fdset (struct MHD_UpgradeResponseHandle *urh, | |||
815 | urh->mhd.celi &= (~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY) | 817 | urh->mhd.celi &= (~((enum MHD_EpollState) MHD_EPOLL_STATE_READ_READY) |
816 | & ~((enum MHD_EpollState) MHD_EPOLL_STATE_WRITE_READY)); | 818 | & ~((enum MHD_EpollState) MHD_EPOLL_STATE_WRITE_READY)); |
817 | 819 | ||
820 | mhd_assert (urh->connection->sk_nonblck); | ||
821 | |||
822 | #ifndef HAS_FD_SETSIZE_OVERRIDABLE | ||
823 | (void) fd_setsize; /* Mute compiler warning */ | ||
824 | mhd_assert (((int) FD_SETSIZE) <= fd_setsize); | ||
825 | fd_setsize = FD_SETSIZE; /* Help compiler to optimise */ | ||
826 | #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */ | ||
827 | |||
818 | if (MHD_INVALID_SOCKET != conn_sckt) | 828 | if (MHD_INVALID_SOCKET != conn_sckt) |
819 | { | 829 | { |
820 | if (FD_ISSET (conn_sckt, (fd_set *) _MHD_DROP_CONST (rs))) | 830 | if (MHD_SCKT_FD_FITS_FDSET_SETSIZE_ (conn_sckt, NULL, fd_setsize)) |
831 | { | ||
832 | if (FD_ISSET (conn_sckt, (fd_set *) _MHD_DROP_CONST (rs))) | ||
833 | urh->app.celi |= MHD_EPOLL_STATE_READ_READY; | ||
834 | if (FD_ISSET (conn_sckt, (fd_set *) _MHD_DROP_CONST (ws))) | ||
835 | urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY; | ||
836 | if ((NULL != es) && | ||
837 | FD_ISSET (conn_sckt, (fd_set *) _MHD_DROP_CONST (es))) | ||
838 | urh->app.celi |= MHD_EPOLL_STATE_ERROR; | ||
839 | } | ||
840 | else | ||
841 | { /* Cannot check readiness. Force ready state is safe as socket is non-blocking */ | ||
821 | urh->app.celi |= MHD_EPOLL_STATE_READ_READY; | 842 | urh->app.celi |= MHD_EPOLL_STATE_READ_READY; |
822 | if (FD_ISSET (conn_sckt, (fd_set *) _MHD_DROP_CONST (ws))) | ||
823 | urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY; | 843 | urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY; |
824 | if ((NULL != es) && | 844 | } |
825 | FD_ISSET (conn_sckt, (fd_set *) _MHD_DROP_CONST (es))) | ||
826 | urh->app.celi |= MHD_EPOLL_STATE_ERROR; | ||
827 | } | 845 | } |
828 | if ((MHD_INVALID_SOCKET != mhd_sckt)) | 846 | if ((MHD_INVALID_SOCKET != mhd_sckt)) |
829 | { | 847 | { |
830 | if (FD_ISSET (mhd_sckt, (fd_set *) _MHD_DROP_CONST (rs))) | 848 | if (MHD_SCKT_FD_FITS_FDSET_SETSIZE_ (mhd_sckt, NULL, fd_setsize)) |
849 | { | ||
850 | if (FD_ISSET (mhd_sckt, (fd_set *) _MHD_DROP_CONST (rs))) | ||
851 | urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; | ||
852 | if (FD_ISSET (mhd_sckt, (fd_set *) _MHD_DROP_CONST (ws))) | ||
853 | urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY; | ||
854 | if ((NULL != es) && | ||
855 | FD_ISSET (mhd_sckt, (fd_set *) _MHD_DROP_CONST (es))) | ||
856 | urh->mhd.celi |= MHD_EPOLL_STATE_ERROR; | ||
857 | } | ||
858 | else | ||
859 | { /* Cannot check readiness. Force ready state is safe as socket is non-blocking */ | ||
831 | urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; | 860 | urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; |
832 | if (FD_ISSET (mhd_sckt, (fd_set *) _MHD_DROP_CONST (ws))) | ||
833 | urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY; | 861 | urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY; |
834 | if ((NULL != es) && | 862 | } |
835 | FD_ISSET (mhd_sckt, (fd_set *) _MHD_DROP_CONST (es))) | ||
836 | urh->mhd.celi |= MHD_EPOLL_STATE_ERROR; | ||
837 | } | 863 | } |
838 | } | 864 | } |
839 | 865 | ||
@@ -958,7 +984,7 @@ internal_get_fdset2 (struct MHD_Daemon *daemon, | |||
958 | fd_set *write_fd_set, | 984 | fd_set *write_fd_set, |
959 | fd_set *except_fd_set, | 985 | fd_set *except_fd_set, |
960 | MHD_socket *max_fd, | 986 | MHD_socket *max_fd, |
961 | unsigned int fd_setsize) | 987 | int fd_setsize) |
962 | { | 988 | { |
963 | struct MHD_Connection *pos; | 989 | struct MHD_Connection *pos; |
964 | struct MHD_Connection *posn; | 990 | struct MHD_Connection *posn; |
@@ -1186,7 +1212,7 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon, | |||
1186 | return MHD_add_to_fd_set_ (daemon->epoll_fd, | 1212 | return MHD_add_to_fd_set_ (daemon->epoll_fd, |
1187 | read_fd_set, | 1213 | read_fd_set, |
1188 | max_fd, | 1214 | max_fd, |
1189 | fd_setsize) ? MHD_YES : MHD_NO; | 1215 | (int) fd_setsize) ? MHD_YES : MHD_NO; |
1190 | } | 1216 | } |
1191 | #endif | 1217 | #endif |
1192 | 1218 | ||
@@ -1195,7 +1221,7 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon, | |||
1195 | write_fd_set, | 1221 | write_fd_set, |
1196 | except_fd_set, | 1222 | except_fd_set, |
1197 | max_fd, | 1223 | max_fd, |
1198 | fd_setsize); | 1224 | (int) fd_setsize); |
1199 | } | 1225 | } |
1200 | 1226 | ||
1201 | 1227 | ||
@@ -1806,7 +1832,8 @@ thread_main_connection_upgrade (struct MHD_Connection *con) | |||
1806 | urh_from_fdset (urh, | 1832 | urh_from_fdset (urh, |
1807 | &rs, | 1833 | &rs, |
1808 | &ws, | 1834 | &ws, |
1809 | &es); | 1835 | &es, |
1836 | (int) FD_SETSIZE); | ||
1810 | process_urh (urh); | 1837 | process_urh (urh); |
1811 | } | 1838 | } |
1812 | } | 1839 | } |
@@ -4372,7 +4399,8 @@ get_timeout_millisec_int (struct MHD_Daemon *daemon, | |||
4372 | * @param daemon daemon to run select loop for | 4399 | * @param daemon daemon to run select loop for |
4373 | * @param read_fd_set read set | 4400 | * @param read_fd_set read set |
4374 | * @param write_fd_set write set | 4401 | * @param write_fd_set write set |
4375 | * @param except_fd_set except set (not used, can be NULL) | 4402 | * @param except_fd_set except set |
4403 | * @param fd_setsize value of FD_SETSIZE used when fd_sets were created | ||
4376 | * @return #MHD_NO on serious errors, #MHD_YES on success | 4404 | * @return #MHD_NO on serious errors, #MHD_YES on success |
4377 | * @ingroup event | 4405 | * @ingroup event |
4378 | */ | 4406 | */ |
@@ -4380,26 +4408,14 @@ static enum MHD_Result | |||
4380 | internal_run_from_select (struct MHD_Daemon *daemon, | 4408 | internal_run_from_select (struct MHD_Daemon *daemon, |
4381 | const fd_set *read_fd_set, | 4409 | const fd_set *read_fd_set, |
4382 | const fd_set *write_fd_set, | 4410 | const fd_set *write_fd_set, |
4383 | const fd_set *except_fd_set) | 4411 | const fd_set *except_fd_set, |
4412 | int fd_setsize) | ||
4384 | { | 4413 | { |
4385 | MHD_socket ds; | 4414 | MHD_socket ds; |
4386 | struct MHD_Connection *pos; | ||
4387 | struct MHD_Connection *prev; | ||
4388 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 4415 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
4389 | struct MHD_UpgradeResponseHandle *urh; | 4416 | struct MHD_UpgradeResponseHandle *urh; |
4390 | struct MHD_UpgradeResponseHandle *urhn; | 4417 | struct MHD_UpgradeResponseHandle *urhn; |
4391 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 4418 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
4392 | /* Reset. New value will be set when connections are processed. */ | ||
4393 | /* Note: no-op for thread-per-connection as it is always false in that mode. */ | ||
4394 | daemon->data_already_pending = false; | ||
4395 | |||
4396 | /* Clear ITC to avoid spinning select */ | ||
4397 | /* Do it before any other processing so new signals | ||
4398 | will trigger select again and will be processed */ | ||
4399 | if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && | ||
4400 | (FD_ISSET (MHD_itc_r_fd_ (daemon->itc), | ||
4401 | (fd_set *) _MHD_DROP_CONST (read_fd_set))) ) | ||
4402 | MHD_itc_clear_ (daemon->itc); | ||
4403 | 4419 | ||
4404 | mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ | 4420 | mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ |
4405 | (MHD_thread_handle_ID_is_valid_ID_ (daemon->tid))); | 4421 | (MHD_thread_handle_ID_is_valid_ID_ (daemon->tid))); |
@@ -4408,36 +4424,86 @@ internal_run_from_select (struct MHD_Daemon *daemon, | |||
4408 | mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ | 4424 | mhd_assert ((0 == (daemon->options & MHD_USE_SELECT_INTERNALLY)) || \ |
4409 | (MHD_thread_handle_ID_is_current_thread_ (daemon->tid))); | 4425 | (MHD_thread_handle_ID_is_current_thread_ (daemon->tid))); |
4410 | 4426 | ||
4427 | mhd_assert (0 < fd_setsize); | ||
4428 | #ifndef HAS_FD_SETSIZE_OVERRIDABLE | ||
4429 | (void) fd_setsize; /* Mute compiler warning */ | ||
4430 | mhd_assert (((int) FD_SETSIZE) <= fd_setsize); | ||
4431 | fd_setsize = FD_SETSIZE; /* Help compiler to optimise */ | ||
4432 | #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */ | ||
4433 | |||
4434 | /* Clear ITC to avoid spinning select */ | ||
4435 | /* Do it before any other processing so new signals | ||
4436 | will trigger select again and will be processed */ | ||
4437 | if (MHD_ITC_IS_VALID_ (daemon->itc)) | ||
4438 | { /* Have ITC */ | ||
4439 | bool need_to_clear_itc = true; /* ITC is always non-blocking, it is safe to clear even if ITC not activated */ | ||
4440 | if (MHD_SCKT_FD_FITS_FDSET_SETSIZE_ (MHD_itc_r_fd_ (daemon->itc), | ||
4441 | NULL, fd_setsize)) | ||
4442 | need_to_clear_itc = FD_ISSET (MHD_itc_r_fd_ (daemon->itc), \ | ||
4443 | (fd_set *) _MHD_DROP_CONST (read_fd_set)); /* Skip clearing, if not needed */ | ||
4444 | if (need_to_clear_itc) | ||
4445 | MHD_itc_clear_ (daemon->itc); | ||
4446 | } | ||
4447 | |||
4448 | /* Reset. New value will be set when connections are processed. */ | ||
4449 | /* Note: no-op for thread-per-connection as it is always false in that mode. */ | ||
4450 | daemon->data_already_pending = false; | ||
4451 | |||
4411 | /* Process externally added connection if any */ | 4452 | /* Process externally added connection if any */ |
4412 | if (daemon->have_new) | 4453 | if (daemon->have_new) |
4413 | new_connections_list_process_ (daemon); | 4454 | new_connections_list_process_ (daemon); |
4414 | 4455 | ||
4415 | /* select connection thread handling type */ | 4456 | /* select connection thread handling type */ |
4416 | if ( (MHD_INVALID_SOCKET != (ds = daemon->listen_fd)) && | 4457 | ds = daemon->listen_fd; |
4417 | (! daemon->was_quiesced) && | 4458 | if ( (MHD_INVALID_SOCKET != ds) && |
4418 | (FD_ISSET (ds, | 4459 | (! daemon->was_quiesced) ) |
4419 | (fd_set *) _MHD_DROP_CONST (read_fd_set))) ) | 4460 | { |
4420 | (void) MHD_accept_connection (daemon); | 4461 | bool need_to_accept; |
4462 | if (MHD_SCKT_FD_FITS_FDSET_SETSIZE_ (ds, NULL, fd_setsize)) | ||
4463 | need_to_accept = FD_ISSET (ds, | ||
4464 | (fd_set *) _MHD_DROP_CONST (read_fd_set)); | ||
4465 | else /* Cannot check whether new connection are pending */ | ||
4466 | need_to_accept = daemon->listen_nonblk; /* Try to accept if non-blocking */ | ||
4421 | 4467 | ||
4422 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | 4468 | if (need_to_accept) |
4469 | (void) MHD_accept_connection (daemon); | ||
4470 | } | ||
4471 | |||
4472 | if (! MHD_D_IS_USING_THREAD_PER_CONN_ (daemon)) | ||
4423 | { | 4473 | { |
4424 | /* do not have a thread per connection, process all connections now */ | 4474 | /* do not have a thread per connection, process all connections now */ |
4425 | prev = daemon->connections_tail; | 4475 | struct MHD_Connection *pos; |
4426 | while (NULL != (pos = prev)) | 4476 | for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev) |
4427 | { | 4477 | { |
4428 | prev = pos->prev; | 4478 | MHD_socket cs; |
4429 | ds = pos->socket_fd; | 4479 | bool r_ready; |
4430 | if (MHD_INVALID_SOCKET == ds) | 4480 | bool w_ready; |
4481 | bool has_err; | ||
4482 | |||
4483 | cs = pos->socket_fd; | ||
4484 | if (MHD_INVALID_SOCKET == cs) | ||
4431 | continue; | 4485 | continue; |
4486 | |||
4487 | if (MHD_SCKT_FD_FITS_FDSET_SETSIZE_ (cs, NULL, fd_setsize)) | ||
4488 | { | ||
4489 | r_ready = FD_ISSET (cs, | ||
4490 | (fd_set *) _MHD_DROP_CONST (read_fd_set)); | ||
4491 | w_ready = FD_ISSET (cs, | ||
4492 | (fd_set *) _MHD_DROP_CONST (write_fd_set)); | ||
4493 | has_err = (NULL != except_fd_set) && | ||
4494 | FD_ISSET (cs, | ||
4495 | (fd_set *) _MHD_DROP_CONST (except_fd_set)); | ||
4496 | } | ||
4497 | else | ||
4498 | { /* Cannot check the real readiness */ | ||
4499 | r_ready = pos->sk_nonblck; | ||
4500 | w_ready = r_ready; | ||
4501 | has_err = false; | ||
4502 | } | ||
4432 | call_handlers (pos, | 4503 | call_handlers (pos, |
4433 | FD_ISSET (ds, | 4504 | r_ready, |
4434 | (fd_set *) _MHD_DROP_CONST (read_fd_set)), | 4505 | w_ready, |
4435 | FD_ISSET (ds, | 4506 | has_err); |
4436 | (fd_set *) _MHD_DROP_CONST (write_fd_set)), | ||
4437 | (NULL != except_fd_set) ? | ||
4438 | (FD_ISSET (ds, | ||
4439 | (fd_set *) _MHD_DROP_CONST (except_fd_set))) : | ||
4440 | (false)); | ||
4441 | } | 4507 | } |
4442 | } | 4508 | } |
4443 | 4509 | ||
@@ -4450,7 +4516,8 @@ internal_run_from_select (struct MHD_Daemon *daemon, | |||
4450 | urh_from_fdset (urh, | 4516 | urh_from_fdset (urh, |
4451 | read_fd_set, | 4517 | read_fd_set, |
4452 | write_fd_set, | 4518 | write_fd_set, |
4453 | except_fd_set); | 4519 | except_fd_set, |
4520 | fd_setsize); | ||
4454 | /* call generic forwarding function for passing data */ | 4521 | /* call generic forwarding function for passing data */ |
4455 | process_urh (urh); | 4522 | process_urh (urh); |
4456 | /* Finished forwarding? */ | 4523 | /* Finished forwarding? */ |
@@ -4471,37 +4538,45 @@ internal_run_from_select (struct MHD_Daemon *daemon, | |||
4471 | } | 4538 | } |
4472 | 4539 | ||
4473 | 4540 | ||
4541 | #undef MHD_run_from_select | ||
4542 | |||
4474 | /** | 4543 | /** |
4475 | * Run webserver operations. This method should be called by clients | 4544 | * Run webserver operations. This method should be called by clients |
4476 | * in combination with #MHD_get_fdset and #MHD_get_timeout() if the | 4545 | * in combination with #MHD_get_fdset and #MHD_get_timeout() if the |
4477 | * client-controlled select method is used. | 4546 | * client-controlled select method is used. |
4547 | * This function specifies FD_SETSIZE used when provided fd_sets were | ||
4548 | * created. It is important on platforms where FD_SETSIZE can be | ||
4549 | * overridden. | ||
4478 | * | 4550 | * |
4479 | * You can use this function instead of #MHD_run if you called | 4551 | * You can use this function instead of #MHD_run if you called |
4480 | * `select()` on the result from #MHD_get_fdset. File descriptors in | 4552 | * 'select()' on the result from #MHD_get_fdset2(). File descriptors in |
4481 | * the sets that are not controlled by MHD will be ignored. Calling | 4553 | * the sets that are not controlled by MHD will be ignored. Calling |
4482 | * this function instead of #MHD_run is more efficient as MHD will | 4554 | * this function instead of #MHD_run() is more efficient as MHD will |
4483 | * not have to call `select()` again to determine which operations are | 4555 | * not have to call 'select()' again to determine which operations are |
4484 | * ready. | 4556 | * ready. |
4485 | * | 4557 | * |
4486 | * If #MHD_get_timeout() returned #MHD_YES, than this function must be | 4558 | * If #MHD_get_timeout() returned #MHD_YES, than this function must be |
4487 | * called right after `select()` returns regardless of detected activity | 4559 | * called right after 'select()' returns regardless of detected activity |
4488 | * on the daemon's FDs. | 4560 | * on the daemon's FDs. |
4489 | * | 4561 | * |
4490 | * This function cannot be used with daemon started with | 4562 | * This function cannot be used with daemon started with |
4491 | * #MHD_USE_INTERNAL_POLLING_THREAD flag. | 4563 | * #MHD_USE_INTERNAL_POLLING_THREAD flag. |
4492 | * | 4564 | * |
4493 | * @param daemon daemon to run select loop for | 4565 | * @param daemon the daemon to run select loop for |
4494 | * @param read_fd_set read set | 4566 | * @param read_fd_set the read set |
4495 | * @param write_fd_set write set | 4567 | * @param write_fd_set the write set |
4496 | * @param except_fd_set except set | 4568 | * @param except_fd_set the except set |
4569 | * @param fd_setsize the value of FD_SETSIZE | ||
4497 | * @return #MHD_NO on serious errors, #MHD_YES on success | 4570 | * @return #MHD_NO on serious errors, #MHD_YES on success |
4571 | * @sa #MHD_get_fdset2(), #MHD_OPTION_APP_FD_SETSIZE | ||
4498 | * @ingroup event | 4572 | * @ingroup event |
4499 | */ | 4573 | */ |
4500 | _MHD_EXTERN enum MHD_Result | 4574 | _MHD_EXTERN enum MHD_Result |
4501 | MHD_run_from_select (struct MHD_Daemon *daemon, | 4575 | MHD_run_from_select2 (struct MHD_Daemon *daemon, |
4502 | const fd_set *read_fd_set, | 4576 | const fd_set *read_fd_set, |
4503 | const fd_set *write_fd_set, | 4577 | const fd_set *write_fd_set, |
4504 | const fd_set *except_fd_set) | 4578 | const fd_set *except_fd_set, |
4579 | unsigned int fd_setsize) | ||
4505 | { | 4580 | { |
4506 | if (MHD_D_IS_USING_POLL_ (daemon) || | 4581 | if (MHD_D_IS_USING_POLL_ (daemon) || |
4507 | (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))) | 4582 | (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))) |
@@ -4516,6 +4591,49 @@ MHD_run_from_select (struct MHD_Daemon *daemon, | |||
4516 | "set to NULL. Such behavior is deprecated.\n")); | 4591 | "set to NULL. Such behavior is deprecated.\n")); |
4517 | } | 4592 | } |
4518 | #endif /* HAVE_MESSAGES */ | 4593 | #endif /* HAVE_MESSAGES */ |
4594 | |||
4595 | #ifdef HAS_FD_SETSIZE_OVERRIDABLE | ||
4596 | if (0 == fd_setsize) | ||
4597 | return MHD_NO; | ||
4598 | else if (((unsigned int) INT_MAX) < fd_setsize) | ||
4599 | fd_setsize = (unsigned int) INT_MAX; | ||
4600 | #ifdef HAVE_MESSAGES | ||
4601 | else if (daemon->fdset_size > ((int) fd_setsize)) | ||
4602 | { | ||
4603 | if (daemon->fdset_size_set_by_app) | ||
4604 | { | ||
4605 | MHD_DLOG (daemon, | ||
4606 | _ ("%s() called with fd_setsize (%u) " \ | ||
4607 | "less than value set by MHD_OPTION_APP_FD_SETSIZE (%d). " \ | ||
4608 | "Some socket FDs may be not processed. " \ | ||
4609 | "Use MHD_OPTION_APP_FD_SETSIZE with the correct value.\n"), | ||
4610 | "MHD_run_from_select2", fd_setsize, daemon->fdset_size); | ||
4611 | } | ||
4612 | else | ||
4613 | { | ||
4614 | MHD_DLOG (daemon, | ||
4615 | _ ("%s() called with fd_setsize (%u) " \ | ||
4616 | "less than FD_SETSIZE used by MHD (%d). " \ | ||
4617 | "Some socket FDs may be not processed. " \ | ||
4618 | "Consider using MHD_OPTION_APP_FD_SETSIZE option.\n"), | ||
4619 | "MHD_run_from_select2", fd_setsize, daemon->fdset_size); | ||
4620 | } | ||
4621 | } | ||
4622 | #endif /* HAVE_MESSAGES */ | ||
4623 | #else /* ! HAS_FD_SETSIZE_OVERRIDABLE */ | ||
4624 | if (((unsigned int) FD_SETSIZE) > fd_setsize) | ||
4625 | { | ||
4626 | #ifdef HAVE_MESSAGES | ||
4627 | MHD_DLOG (daemon, | ||
4628 | _ ("%s() called with fd_setsize (%u) " \ | ||
4629 | "less than fixed FD_SETSIZE value (%d) used on the " \ | ||
4630 | "platform.\n", "MHD_run_from_select2"), | ||
4631 | fd_setsize, (int) FD_SETSIZE); | ||
4632 | #endif /* HAVE_MESSAGES */ | ||
4633 | return MHD_NO; | ||
4634 | } | ||
4635 | #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */ | ||
4636 | |||
4519 | if (MHD_D_IS_USING_EPOLL_ (daemon)) | 4637 | if (MHD_D_IS_USING_EPOLL_ (daemon)) |
4520 | { | 4638 | { |
4521 | #ifdef EPOLL_SUPPORT | 4639 | #ifdef EPOLL_SUPPORT |
@@ -4536,7 +4654,55 @@ MHD_run_from_select (struct MHD_Daemon *daemon, | |||
4536 | return internal_run_from_select (daemon, | 4654 | return internal_run_from_select (daemon, |
4537 | read_fd_set, | 4655 | read_fd_set, |
4538 | write_fd_set, | 4656 | write_fd_set, |
4539 | except_fd_set); | 4657 | except_fd_set, |
4658 | (int) fd_setsize); | ||
4659 | } | ||
4660 | |||
4661 | |||
4662 | /** | ||
4663 | * Run webserver operations. This method should be called by clients | ||
4664 | * in combination with #MHD_get_fdset and #MHD_get_timeout() if the | ||
4665 | * client-controlled select method is used. | ||
4666 | * | ||
4667 | * You can use this function instead of #MHD_run if you called | ||
4668 | * `select()` on the result from #MHD_get_fdset. File descriptors in | ||
4669 | * the sets that are not controlled by MHD will be ignored. Calling | ||
4670 | * this function instead of #MHD_run is more efficient as MHD will | ||
4671 | * not have to call `select()` again to determine which operations are | ||
4672 | * ready. | ||
4673 | * | ||
4674 | * If #MHD_get_timeout() returned #MHD_YES, than this function must be | ||
4675 | * called right after `select()` returns regardless of detected activity | ||
4676 | * on the daemon's FDs. | ||
4677 | * | ||
4678 | * This function cannot be used with daemon started with | ||
4679 | * #MHD_USE_INTERNAL_POLLING_THREAD flag. | ||
4680 | * | ||
4681 | * @param daemon daemon to run select loop for | ||
4682 | * @param read_fd_set read set | ||
4683 | * @param write_fd_set write set | ||
4684 | * @param except_fd_set except set | ||
4685 | * @return #MHD_NO on serious errors, #MHD_YES on success | ||
4686 | * @ingroup event | ||
4687 | */ | ||
4688 | _MHD_EXTERN enum MHD_Result | ||
4689 | MHD_run_from_select (struct MHD_Daemon *daemon, | ||
4690 | const fd_set *read_fd_set, | ||
4691 | const fd_set *write_fd_set, | ||
4692 | const fd_set *except_fd_set) | ||
4693 | { | ||
4694 | return MHD_run_from_select2 (daemon, | ||
4695 | read_fd_set, | ||
4696 | write_fd_set, | ||
4697 | except_fd_set, | ||
4698 | #ifdef HAS_FD_SETSIZE_OVERRIDABLE | ||
4699 | daemon->fdset_size_set_by_app ? | ||
4700 | ((unsigned int) daemon->fdset_size) : | ||
4701 | ((unsigned int) _MHD_SYS_DEFAULT_FD_SETSIZE) | ||
4702 | #else /* ! HAS_FD_SETSIZE_OVERRIDABLE */ | ||
4703 | ((unsigned int) _MHD_SYS_DEFAULT_FD_SETSIZE) | ||
4704 | #endif /* ! HAS_FD_SETSIZE_OVERRIDABLE */ | ||
4705 | ); | ||
4540 | } | 4706 | } |
4541 | 4707 | ||
4542 | 4708 | ||
@@ -4587,7 +4753,7 @@ MHD_select (struct MHD_Daemon *daemon, | |||
4587 | &ws, | 4753 | &ws, |
4588 | &es, | 4754 | &es, |
4589 | &maxsock, | 4755 | &maxsock, |
4590 | FD_SETSIZE)) | 4756 | (int) FD_SETSIZE)) |
4591 | { | 4757 | { |
4592 | #ifdef HAVE_MESSAGES | 4758 | #ifdef HAVE_MESSAGES |
4593 | MHD_DLOG (daemon, | 4759 | MHD_DLOG (daemon, |
@@ -4604,7 +4770,7 @@ MHD_select (struct MHD_Daemon *daemon, | |||
4604 | (! MHD_add_to_fd_set_ (ls, | 4770 | (! MHD_add_to_fd_set_ (ls, |
4605 | &rs, | 4771 | &rs, |
4606 | &maxsock, | 4772 | &maxsock, |
4607 | FD_SETSIZE)) ) | 4773 | (int) FD_SETSIZE)) ) |
4608 | { | 4774 | { |
4609 | #ifdef HAVE_MESSAGES | 4775 | #ifdef HAVE_MESSAGES |
4610 | MHD_DLOG (daemon, | 4776 | MHD_DLOG (daemon, |
@@ -4617,7 +4783,7 @@ MHD_select (struct MHD_Daemon *daemon, | |||
4617 | (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), | 4783 | (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), |
4618 | &rs, | 4784 | &rs, |
4619 | &maxsock, | 4785 | &maxsock, |
4620 | FD_SETSIZE)) ) | 4786 | (int) FD_SETSIZE)) ) |
4621 | { | 4787 | { |
4622 | bool retry_succeed; | 4788 | bool retry_succeed; |
4623 | 4789 | ||
@@ -4634,7 +4800,7 @@ MHD_select (struct MHD_Daemon *daemon, | |||
4634 | if (MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), | 4800 | if (MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), |
4635 | &rs, | 4801 | &rs, |
4636 | &maxsock, | 4802 | &maxsock, |
4637 | FD_SETSIZE)) | 4803 | (int) FD_SETSIZE)) |
4638 | retry_succeed = true; | 4804 | retry_succeed = true; |
4639 | } | 4805 | } |
4640 | #endif /* MHD_WINSOCK_SOCKETS */ | 4806 | #endif /* MHD_WINSOCK_SOCKETS */ |
@@ -4731,7 +4897,8 @@ MHD_select (struct MHD_Daemon *daemon, | |||
4731 | if (MHD_NO != internal_run_from_select (daemon, | 4897 | if (MHD_NO != internal_run_from_select (daemon, |
4732 | &rs, | 4898 | &rs, |
4733 | &ws, | 4899 | &ws, |
4734 | &es)) | 4900 | &es, |
4901 | (int) FD_SETSIZE)) | ||
4735 | return (MHD_NO == err_state) ? MHD_YES : MHD_NO; | 4902 | return (MHD_NO == err_state) ? MHD_YES : MHD_NO; |
4736 | return MHD_NO; | 4903 | return MHD_NO; |
4737 | } | 4904 | } |
@@ -5675,6 +5842,24 @@ MHD_run_wait (struct MHD_Daemon *daemon, | |||
5675 | #endif | 5842 | #endif |
5676 | if (1) | 5843 | if (1) |
5677 | { | 5844 | { |
5845 | mhd_assert (MHD_D_IS_USING_SELECT_ (daemon)); | ||
5846 | #ifdef HAS_FD_SETSIZE_OVERRIDABLE | ||
5847 | #ifdef HAVE_MESSAGES | ||
5848 | if (daemon->fdset_size_set_by_app | ||
5849 | && (((int) FD_SETSIZE) < daemon->fdset_size)) | ||
5850 | { | ||
5851 | MHD_DLOG (daemon, | ||
5852 | _ ("MHD_run()/MHD_run_wait() called for daemon started with " \ | ||
5853 | "MHD_OPTION_APP_FD_SETSIZE option (%d). " \ | ||
5854 | "The library was compiled with smaller FD_SETSIZE (%d). " \ | ||
5855 | "Some socket FDs may be not processed. " \ | ||
5856 | "Use MHD_run_from_select2() instead of MHD_run() or " \ | ||
5857 | "do not use MHD_OPTION_APP_FD_SETSIZE option.\n"), | ||
5858 | daemon->fdset_size, (int) FD_SETSIZE); | ||
5859 | } | ||
5860 | #endif /* HAVE_MESSAGES */ | ||
5861 | #endif /* HAS_FD_SETSIZE_OVERRIDABLE */ | ||
5862 | |||
5678 | res = MHD_select (daemon, millisec); | 5863 | res = MHD_select (daemon, millisec); |
5679 | /* MHD_select does MHD_cleanup_connections already */ | 5864 | /* MHD_select does MHD_cleanup_connections already */ |
5680 | } | 5865 | } |