aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/daemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd/daemon.c')
-rw-r--r--src/microhttpd/daemon.c180
1 files changed, 86 insertions, 94 deletions
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 5476f956..2c0e0a82 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -826,6 +826,62 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
826 826
827 827
828/** 828/**
829 * Call the handlers for a connection in the
830 * appropriate order based on the readiness as
831 * detected by the event loop.
832 *
833 * @param con connection to handle
834 * @param read_ready set if the socket is ready for reading
835 * @param write_ready set if the socket is ready for writing
836 * @param force_close set if a hard error was detected on the socket;
837 * if this information is not available, simply pass #MHD_NO
838 * @return #MHD_YES to continue normally,
839 * #MHD_NO if a serious error was encountered and the
840 * connection is to be closed.
841 */
842static int
843call_handlers (struct MHD_Connection *con,
844 int read_ready,
845 int write_ready,
846 int force_close)
847{
848 struct MHD_Daemon *daemon = con->daemon;
849 int had_response_before_idle;
850 int ret;
851
852#if HTTPS_SUPPORT
853 if (MHD_YES == con->tls_read_ready)
854 read_ready = MHD_YES;
855#endif
856 if (read_ready)
857 con->read_handler (con);
858 if (write_ready)
859 con->write_handler (con);
860 had_response_before_idle = (NULL != con->response);
861 if (force_close)
862 MHD_connection_close_ (con,
863 MHD_REQUEST_TERMINATED_WITH_ERROR);
864 ret = con->idle_handler (con);
865 /* If we're in TURBO mode, and got a response object,
866 try opportunistically to just call write immediately. */
867 if ( (! force_close) &&
868 (MHD_YES == ret) &&
869 (0 != (daemon->options & MHD_USE_EPOLL_TURBO)) &&
870 (NULL != con->response) &&
871 (MHD_NO == had_response_before_idle) )
872 {
873 /* first 'write' gets the header, then 'idle'
874 readies the body, then 2nd 'write' may send
875 the body. */
876 con->write_handler (con);
877 if (MHD_YES == (ret = con->idle_handler (con)))
878 con->write_handler (con);
879 }
880 return ret;
881}
882
883
884/**
829 * Main function of the thread that handles an individual 885 * Main function of the thread that handles an individual
830 * connection when #MHD_USE_THREAD_PER_CONNECTION is set. 886 * connection when #MHD_USE_THREAD_PER_CONNECTION is set.
831 * 887 *
@@ -962,17 +1018,12 @@ MHD_handle_connection (void *data)
962 (FD_ISSET (spipe, &rs)) ) 1018 (FD_ISSET (spipe, &rs)) )
963 MHD_pipe_drain_ (spipe); 1019 MHD_pipe_drain_ (spipe);
964#endif 1020#endif
965 /* call appropriate connection handler if necessary */ 1021 if (MHD_NO ==
966 if ( (FD_ISSET (con->socket_fd, &rs)) 1022 call_handlers (con,
967#if HTTPS_SUPPORT 1023 FD_ISSET (con->socket_fd, &rs),
968 || (MHD_YES == con->tls_read_ready) 1024 FD_ISSET (con->socket_fd, &ws),
969#endif 1025 MHD_NO))
970 ) 1026 goto exit;
971 con->read_handler (con);
972 if (FD_ISSET (con->socket_fd, &ws))
973 con->write_handler (con);
974 if (MHD_NO == con->idle_handler (con))
975 goto exit;
976 } 1027 }
977#ifdef HAVE_POLL 1028#ifdef HAVE_POLL
978 else 1029 else
@@ -1034,19 +1085,12 @@ MHD_handle_connection (void *data)
1034 (0 != (p[1].revents & (POLLERR | POLLHUP))) ) 1085 (0 != (p[1].revents & (POLLERR | POLLHUP))) )
1035 MHD_pipe_drain_ (spipe); 1086 MHD_pipe_drain_ (spipe);
1036#endif 1087#endif
1037 if ( (0 != (p[0].revents & POLLIN)) 1088 if (MHD_NO ==
1038#if HTTPS_SUPPORT 1089 call_handlers (con,
1039 || (MHD_YES == con->tls_read_ready) 1090 0 != (p[0].revents & POLLIN),
1040#endif 1091 0 != (p[0].revents & POLLOUT),
1041 ) 1092 0 != (p[0].revents & (POLLERR | POLLHUP))))
1042 con->read_handler (con); 1093 goto exit;
1043 if (0 != (p[0].revents & POLLOUT))
1044 con->write_handler (con);
1045 if (0 != (p[0].revents & (POLLERR | POLLHUP)))
1046 MHD_connection_close_ (con,
1047 MHD_REQUEST_TERMINATED_WITH_ERROR);
1048 if (MHD_NO == con->idle_handler (con))
1049 goto exit;
1050 } 1094 }
1051#endif 1095#endif
1052 } 1096 }
@@ -1823,7 +1867,7 @@ resume_suspended_connections (struct MHD_Daemon *daemon)
1823 MHD_PANIC ("Failed to acquire cleanup mutex\n"); 1867 MHD_PANIC ("Failed to acquire cleanup mutex\n");
1824 if (MHD_NO != daemon->resuming) 1868 if (MHD_NO != daemon->resuming)
1825 next = daemon->suspended_connections_head; 1869 next = daemon->suspended_connections_head;
1826 1870
1827 /* Clear the flag *only* if connections will be resumed otherwise 1871 /* Clear the flag *only* if connections will be resumed otherwise
1828 it may accidentally clear flag that was set at the same time in 1872 it may accidentally clear flag that was set at the same time in
1829 other thread (just after 'if (MHD_NO != daemon->resuming)' in 1873 other thread (just after 'if (MHD_NO != daemon->resuming)' in
@@ -2310,33 +2354,10 @@ MHD_run_from_select (struct MHD_Daemon *daemon,
2310 ds = pos->socket_fd; 2354 ds = pos->socket_fd;
2311 if (MHD_INVALID_SOCKET == ds) 2355 if (MHD_INVALID_SOCKET == ds)
2312 continue; 2356 continue;
2313 switch (pos->event_loop_info) 2357 call_handlers (pos,
2314 { 2358 FD_ISSET (ds, read_fd_set),
2315 case MHD_EVENT_LOOP_INFO_READ: 2359 FD_ISSET (ds, write_fd_set),
2316 if ( (FD_ISSET (ds, read_fd_set)) 2360 MHD_NO);
2317#if HTTPS_SUPPORT
2318 || (MHD_YES == pos->tls_read_ready)
2319#endif
2320 )
2321 pos->read_handler (pos);
2322 break;
2323 case MHD_EVENT_LOOP_INFO_WRITE:
2324 if ( (FD_ISSET (ds, read_fd_set)) &&
2325 (pos->read_buffer_size > pos->read_buffer_offset) )
2326 pos->read_handler (pos);
2327 if (FD_ISSET (ds, write_fd_set))
2328 pos->write_handler (pos);
2329 break;
2330 case MHD_EVENT_LOOP_INFO_BLOCK:
2331 if ( (FD_ISSET (ds, read_fd_set)) &&
2332 (pos->read_buffer_size > pos->read_buffer_offset) )
2333 pos->read_handler (pos);
2334 break;
2335 case MHD_EVENT_LOOP_INFO_CLEANUP:
2336 /* should never happen */
2337 break;
2338 }
2339 pos->idle_handler (pos);
2340 } 2361 }
2341 } 2362 }
2342 MHD_cleanup_connections (daemon); 2363 MHD_cleanup_connections (daemon);
@@ -2621,43 +2642,15 @@ MHD_poll_all (struct MHD_Daemon *daemon,
2621 while (NULL != (pos = next)) 2642 while (NULL != (pos = next))
2622 { 2643 {
2623 next = pos->next; 2644 next = pos->next;
2624 switch (pos->event_loop_info) 2645 /* first, sanity checks */
2625 { 2646 if (i >= num_connections)
2626 case MHD_EVENT_LOOP_INFO_READ: 2647 continue; /* connection list changed somehow, retry later ... */
2627 /* first, sanity checks */ 2648 if (p[poll_server+i].fd != pos->socket_fd)
2628 if (i >= num_connections) 2649 continue; /* fd mismatch, something else happened, retry later ... */
2629 break; /* connection list changed somehow, retry later ... */ 2650 call_handlers (pos,
2630 if (p[poll_server+i].fd != pos->socket_fd) 2651 0 != (p[poll_server+i].revents & POLLIN),
2631 break; /* fd mismatch, something else happened, retry later ... */ 2652 0 != (p[poll_server+i].revents & POLLOUT),
2632 /* normal handling */ 2653 MHD_NO);
2633 if (0 != (p[poll_server+i].revents & POLLIN))
2634 pos->read_handler (pos);
2635 pos->idle_handler (pos);
2636 i++;
2637 break;
2638 case MHD_EVENT_LOOP_INFO_WRITE:
2639 /* first, sanity checks */
2640 if (i >= num_connections)
2641 break; /* connection list changed somehow, retry later ... */
2642 if (p[poll_server+i].fd != pos->socket_fd)
2643 break; /* fd mismatch, something else happened, retry later ... */
2644 /* normal handling */
2645 if (0 != (p[poll_server+i].revents & POLLIN))
2646 pos->read_handler (pos);
2647 if (0 != (p[poll_server+i].revents & POLLOUT))
2648 pos->write_handler (pos);
2649 pos->idle_handler (pos);
2650 i++;
2651 break;
2652 case MHD_EVENT_LOOP_INFO_BLOCK:
2653 if (0 != (p[poll_server+i].revents & POLLIN))
2654 pos->read_handler (pos);
2655 pos->idle_handler (pos);
2656 break;
2657 case MHD_EVENT_LOOP_INFO_CLEANUP:
2658 pos->idle_handler (pos);
2659 break;
2660 }
2661 } 2654 }
2662 /* handle 'listen' FD */ 2655 /* handle 'listen' FD */
2663 if ( (-1 != poll_listen) && 2656 if ( (-1 != poll_listen) &&
@@ -2934,11 +2927,10 @@ MHD_epoll (struct MHD_Daemon *daemon,
2934 daemon->eready_tail, 2927 daemon->eready_tail,
2935 pos); 2928 pos);
2936 pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL; 2929 pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
2937 if (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) 2930 call_handlers (pos,
2938 pos->read_handler (pos); 2931 MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info,
2939 if (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) 2932 MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info,
2940 pos->write_handler (pos); 2933 MHD_NO);
2941 pos->idle_handler (pos);
2942 } 2934 }
2943 2935
2944 /* Finally, handle timed-out connections; we need to do this here 2936 /* Finally, handle timed-out connections; we need to do this here