diff options
Diffstat (limited to 'src/microhttpd/daemon.c')
-rw-r--r-- | src/microhttpd/daemon.c | 180 |
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 | */ | ||
842 | static int | ||
843 | call_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 |