43 #define MAX_EVENTS 128
46 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
56 is_urh_ready (
struct MHD_UpgradeResponseHandle *
const urh)
60 if ( (0 == urh->in_buffer_size) &&
61 (0 == urh->out_buffer_size) &&
62 (0 == urh->in_buffer_used) &&
63 (0 == urh->out_buffer_used) )
71 (urh->in_buffer_used < urh->in_buffer_size) )
75 (urh->out_buffer_used < urh->out_buffer_size) )
79 (urh->out_buffer_used > 0) )
83 (urh->in_buffer_used > 0) )
101 static enum MHD_StatusCode
104 struct epoll_event events[MAX_EVENTS];
106 struct MHD_UpgradeResponseHandle *pos;
107 struct MHD_UpgradeResponseHandle *prev;
109 num_events = MAX_EVENTS;
110 while (MAX_EVENTS == num_events)
115 num_events = epoll_wait (daemon->epoll_upgrade_fd,
119 if (-1 == num_events)
126 MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR,
127 _ (
"Call to epoll_wait failed: %s\n"),
130 return MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR;
132 for (i = 0; i < (
unsigned int) num_events; i++)
134 struct UpgradeEpollHandle *
const ueh = events[i].data.ptr;
135 struct MHD_UpgradeResponseHandle *
const urh = ueh->urh;
136 bool new_err_state =
false;
138 if (urh->clean_ready)
142 if (0 != (events[i].events & EPOLLIN))
144 if (0 != (events[i].events & EPOLLOUT))
146 if (0 != (events[i].events & EPOLLHUP))
150 (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) )
156 new_err_state =
true;
159 if (! urh->in_eready_list)
165 daemon->eready_urh_tail,
167 urh->in_eready_list =
true;
172 prev = daemon->eready_urh_tail;
173 while (
NULL != (pos = prev))
176 MHD_upgrade_response_handle_process_ (pos);
177 if (! is_urh_ready (pos))
180 daemon->eready_urh_tail,
182 pos->in_eready_list =
false;
185 if ( (0 == pos->in_buffer_size) &&
186 (0 == pos->out_buffer_size) &&
187 (0 == pos->in_buffer_used) &&
188 (0 == pos->out_buffer_used) )
191 pos->clean_ready =
true;
219 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
220 static const char *
const upgrade_marker =
"upgrade_ptr";
224 struct epoll_event events[MAX_EVENTS];
225 struct epoll_event event;
231 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
232 bool run_upgraded =
false;
235 if (-1 == daemon->epoll_fd)
236 return MHD_SC_EPOLL_FD_INVALID;
238 return MHD_SC_DAEMON_ALREADY_SHUTDOWN;
242 (! daemon->listen_socket_in_epoll) &&
245 event.events = EPOLLIN;
246 event.data.ptr = daemon;
247 if (0 != epoll_ctl (daemon->epoll_fd,
254 MHD_SC_EPOLL_CTL_ADD_FAILED,
255 _ (
"Call to epoll_ctl failed: %s\n"),
258 return MHD_SC_EPOLL_CTL_ADD_FAILED;
260 daemon->listen_socket_in_epoll =
true;
263 (daemon->listen_socket_in_epoll) )
265 if (0 != epoll_ctl (daemon->epoll_fd,
269 MHD_PANIC (
"Failed to remove listen FD from epoll set.\n");
270 daemon->listen_socket_in_epoll =
false;
273 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
274 if ( (! daemon->upgrade_fd_in_epoll) &&
275 (-1 != daemon->epoll_upgrade_fd) )
277 event.events = EPOLLIN | EPOLLOUT;
278 event.data.ptr = (
void *) upgrade_marker;
279 if (0 != epoll_ctl (daemon->epoll_fd,
281 daemon->epoll_upgrade_fd,
286 MHD_SC_EPOLL_CTL_ADD_FAILED,
287 _ (
"Call to epoll_ctl failed: %s\n"),
290 return MHD_SC_EPOLL_CTL_ADD_FAILED;
292 daemon->upgrade_fd_in_epoll =
true;
295 if ( (daemon->listen_socket_in_epoll) &&
302 if (0 != epoll_ctl (daemon->epoll_fd,
306 MHD_PANIC (
_ (
"Failed to remove listen FD from epoll set.\n"));
307 daemon->listen_socket_in_epoll =
false;
321 timeout_ms = INT_MAX;
323 timeout_ms = (int) timeout_ll;
340 num_events = MAX_EVENTS;
341 while (MAX_EVENTS == num_events)
344 num_events = epoll_wait (daemon->epoll_fd,
348 if (-1 == num_events)
355 MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR,
356 _ (
"Call to epoll_wait failed: %s\n"),
359 return MHD_SC_UNEXPECTED_EPOLL_WAIT_ERROR;
361 for (i = 0; i<(
unsigned int) num_events; i++)
367 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
368 if (upgrade_marker == events[i].
data.ptr)
376 if (daemon->epoll_itc_marker == events[i].data.ptr)
380 MHD_itc_clear_ (daemon->
itc);
383 if (daemon == events[i].
data.ptr)
387 if (0 == (events[i].events & (EPOLLERR | EPOLLHUP)))
389 unsigned int series_length = 0;
394 while ( (MHD_SC_OK ==
396 (series_length < 10) &&
406 pos = events[i].data.ptr;
408 if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP)))
421 if (0 != (events[i].events & EPOLLIN))
435 if (0 != (events[i].events & EPOLLOUT))
451 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
453 run_epoll_for_upgrade (daemon);
457 prev = daemon->eready_tail;
458 while (
NULL != (pos = prev))
462 0 != (pos->epoll_state
464 0 != (pos->epoll_state
466 0 != (pos->epoll_state
494 while (
NULL != (pos = prev))
504 while (
NULL != (pos = prev))
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)
bool MHD_request_handle_idle_(struct MHD_Request *request)
function to call event handlers based on event mask
complete upgrade socket forwarding operation in TLS mode
void MHD_connection_finish_forward_(struct MHD_Connection *connection) MHD_NONNULL(1)
non-public functions provided by daemon_epoll.c
enum MHD_StatusCode MHD_daemon_get_timeout(struct MHD_Daemon *daemon, MHD_UNSIGNED_LONG_LONG *timeout)
@ MHD_EPOLL_STATE_SUSPENDED
@ MHD_EPOLL_STATE_IN_EREADY_EDLL
@ MHD_EPOLL_STATE_READ_READY
@ MHD_EPOLL_STATE_WRITE_READY
#define EDLL_insert(head, tail, element)
#define EDLL_remove(head, tail, element)
#define MHD_socket_strerr_(err)
#define MHD_socket_last_strerr_()
#define MHD_socket_get_error_()
#define MHD_SCKT_ERR_IS_EINTR_(err)
internal shared structures
@ MHD_EVENT_LOOP_INFO_READ
@ MHD_EVENT_LOOP_INFO_WRITE
@ MHD_EVENT_LOOP_INFO_CLEANUP
#define MHD_UNSIGNED_LONG_LONG
#define MHD_INVALID_SOCKET
void MHD_request_resume(struct MHD_Request *request)
bool MHD_resume_suspended_connections_(struct MHD_Daemon *daemon)
implementation of MHD_request_resume()
struct MHD_Connection * prevX
struct MHD_Request request
struct MHD_Connection * prev
struct MHD_Daemon * daemon
bool data_already_pending
struct MHD_Connection * manual_timeout_tail
bool disallow_suspend_resume
struct MHD_Connection * normal_timeout_tail
unsigned int global_connection_limit
size_t read_buffer_offset
enum MHD_RequestEventLoopInfo event_loop_info
enum MHD_REQUEST_STATE state
function to process upgrade activity (over TLS)