diff options
Diffstat (limited to 'src/lib/connection_call_handlers.c')
-rw-r--r-- | src/lib/connection_call_handlers.c | 128 |
1 files changed, 126 insertions, 2 deletions
diff --git a/src/lib/connection_call_handlers.c b/src/lib/connection_call_handlers.c index 9e6276eb..bb6123eb 100644 --- a/src/lib/connection_call_handlers.c +++ b/src/lib/connection_call_handlers.c | |||
@@ -23,6 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | #include "internal.h" | 24 | #include "internal.h" |
25 | #include "connection_call_handlers.h" | 25 | #include "connection_call_handlers.h" |
26 | #include "connection_update_event_loop_info.h" | ||
26 | #include "connection_update_last_activity.h" | 27 | #include "connection_update_last_activity.h" |
27 | #include "connection_close.h" | 28 | #include "connection_close.h" |
28 | 29 | ||
@@ -2767,6 +2768,127 @@ process_request_body (struct MHD_Request *request) | |||
2767 | 2768 | ||
2768 | 2769 | ||
2769 | /** | 2770 | /** |
2771 | * Clean up the state of the given connection and move it into the | ||
2772 | * clean up queue for final disposal. | ||
2773 | * @remark To be called only from thread that process connection's | ||
2774 | * recv(), send() and response. | ||
2775 | * | ||
2776 | * @param connection handle for the connection to clean up | ||
2777 | */ | ||
2778 | static void | ||
2779 | cleanup_connection (struct MHD_Connection *connection) | ||
2780 | { | ||
2781 | struct MHD_Daemon *daemon = connection->daemon; | ||
2782 | |||
2783 | if (connection->request.in_cleanup) | ||
2784 | return; /* Prevent double cleanup. */ | ||
2785 | connection->request.in_cleanup = true; | ||
2786 | if (NULL != connection->request.response) | ||
2787 | { | ||
2788 | MHD_response_queue_for_destroy (connection->request.response); | ||
2789 | connection->request.response = NULL; | ||
2790 | } | ||
2791 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | ||
2792 | if (connection->suspended) | ||
2793 | { | ||
2794 | DLL_remove (daemon->suspended_connections_head, | ||
2795 | daemon->suspended_connections_tail, | ||
2796 | connection); | ||
2797 | connection->suspended = false; | ||
2798 | } | ||
2799 | else | ||
2800 | { | ||
2801 | if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_model) | ||
2802 | { | ||
2803 | if (connection->connection_timeout == | ||
2804 | daemon->connection_default_timeout) | ||
2805 | XDLL_remove (daemon->normal_timeout_head, | ||
2806 | daemon->normal_timeout_tail, | ||
2807 | connection); | ||
2808 | else | ||
2809 | XDLL_remove (daemon->manual_timeout_head, | ||
2810 | daemon->manual_timeout_tail, | ||
2811 | connection); | ||
2812 | } | ||
2813 | DLL_remove (daemon->connections_head, | ||
2814 | daemon->connections_tail, | ||
2815 | connection); | ||
2816 | } | ||
2817 | DLL_insert (daemon->cleanup_head, | ||
2818 | daemon->cleanup_tail, | ||
2819 | connection); | ||
2820 | connection->resuming = false; | ||
2821 | connection->request.in_idle = false; | ||
2822 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | ||
2823 | if (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_model) | ||
2824 | { | ||
2825 | /* if we were at the connection limit before and are in | ||
2826 | thread-per-connection mode, signal the main thread | ||
2827 | to resume accepting connections */ | ||
2828 | if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && | ||
2829 | (! MHD_itc_activate_ (daemon->itc, | ||
2830 | "c")) ) | ||
2831 | { | ||
2832 | #ifdef HAVE_MESSAGES | ||
2833 | MHD_DLOG (daemon, | ||
2834 | MHD_SC_ITC_USE_FAILED, | ||
2835 | _("Failed to signal end of connection via inter-thread communication channel")); | ||
2836 | #endif | ||
2837 | } | ||
2838 | } | ||
2839 | } | ||
2840 | |||
2841 | |||
2842 | #ifdef EPOLL_SUPPORT | ||
2843 | /** | ||
2844 | * Perform epoll() processing, possibly moving the connection back into | ||
2845 | * the epoll() set if needed. | ||
2846 | * | ||
2847 | * @param connection connection to process | ||
2848 | * @return true if we should continue to process the | ||
2849 | * connection (not dead yet), false if it died | ||
2850 | */ | ||
2851 | static bool | ||
2852 | connection_epoll_update_ (struct MHD_Connection *connection) | ||
2853 | { | ||
2854 | struct MHD_Daemon *daemon = connection->daemon; | ||
2855 | |||
2856 | if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) && | ||
2857 | (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) && | ||
2858 | (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) && | ||
2859 | ( ( (MHD_EVENT_LOOP_INFO_WRITE == connection->request.event_loop_info) && | ||
2860 | (0 == (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY))) || | ||
2861 | ( (MHD_EVENT_LOOP_INFO_READ == connection->request.event_loop_info) && | ||
2862 | (0 == (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) ) ) ) | ||
2863 | { | ||
2864 | /* add to epoll set */ | ||
2865 | struct epoll_event event; | ||
2866 | |||
2867 | event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET; | ||
2868 | event.data.ptr = connection; | ||
2869 | if (0 != epoll_ctl (daemon->epoll_fd, | ||
2870 | EPOLL_CTL_ADD, | ||
2871 | connection->socket_fd, | ||
2872 | &event)) | ||
2873 | { | ||
2874 | #ifdef HAVE_MESSAGES | ||
2875 | MHD_DLOG (daemon, | ||
2876 | MHD_SC_EPOLL_CTL_ADD_FAILED, | ||
2877 | _("Call to epoll_ctl failed: %s\n"), | ||
2878 | MHD_socket_last_strerr_ ()); | ||
2879 | #endif | ||
2880 | connection->request.state = MHD_REQUEST_CLOSED; | ||
2881 | cleanup_connection (connection); | ||
2882 | return false; | ||
2883 | } | ||
2884 | connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET; | ||
2885 | } | ||
2886 | return true; | ||
2887 | } | ||
2888 | #endif | ||
2889 | |||
2890 | |||
2891 | /** | ||
2770 | * This function was created to handle per-request processing that | 2892 | * This function was created to handle per-request processing that |
2771 | * has to happen even if the socket cannot be read or written to. | 2893 | * has to happen even if the socket cannot be read or written to. |
2772 | * @remark To be called only from thread that process request's | 2894 | * @remark To be called only from thread that process request's |
@@ -3064,6 +3186,7 @@ MHD_request_handle_idle_ (struct MHD_Request *request) | |||
3064 | { | 3186 | { |
3065 | socket_start_normal_buffering (connection); | 3187 | socket_start_normal_buffering (connection); |
3066 | request->state = MHD_REQUEST_UPGRADE; | 3188 | request->state = MHD_REQUEST_UPGRADE; |
3189 | #if FIXME_LEGACY_STYLE | ||
3067 | /* This request is "upgraded". Pass socket to application. */ | 3190 | /* This request is "upgraded". Pass socket to application. */ |
3068 | if (! MHD_response_execute_upgrade_ (request->response, | 3191 | if (! MHD_response_execute_upgrade_ (request->response, |
3069 | request)) | 3192 | request)) |
@@ -3074,6 +3197,7 @@ MHD_request_handle_idle_ (struct MHD_Request *request) | |||
3074 | NULL); | 3197 | NULL); |
3075 | continue; | 3198 | continue; |
3076 | } | 3199 | } |
3200 | #endif | ||
3077 | /* Response is not required anymore for this request. */ | 3201 | /* Response is not required anymore for this request. */ |
3078 | if (NULL != request->response) | 3202 | if (NULL != request->response) |
3079 | { | 3203 | { |
@@ -3262,13 +3386,13 @@ MHD_request_handle_idle_ (struct MHD_Request *request) | |||
3262 | return true; | 3386 | return true; |
3263 | } | 3387 | } |
3264 | } | 3388 | } |
3265 | MHD_connection_update_event_loop_info (connection); | 3389 | MHD_connection_update_event_loop_info_ (connection); |
3266 | ret = true; | 3390 | ret = true; |
3267 | #ifdef EPOLL_SUPPORT | 3391 | #ifdef EPOLL_SUPPORT |
3268 | if ( (! connection->suspended) && | 3392 | if ( (! connection->suspended) && |
3269 | (MHD_ELS_EPOLL == daemon->event_loop_syscall) ) | 3393 | (MHD_ELS_EPOLL == daemon->event_loop_syscall) ) |
3270 | { | 3394 | { |
3271 | ret = MHD_connection_epoll_update_ (connection); | 3395 | ret = connection_epoll_update_ (connection); |
3272 | } | 3396 | } |
3273 | #endif /* EPOLL_SUPPORT */ | 3397 | #endif /* EPOLL_SUPPORT */ |
3274 | request->in_idle = false; | 3398 | request->in_idle = false; |