Rewrote epoll handling: handle all connections instead of drying last active

This commit is contained in:
Evgeny Grin (Karlson2k)
2017-02-08 22:44:21 +03:00
parent eba022ce02
commit 47fdebac4b
3 changed files with 37 additions and 52 deletions
+2 -45
View File
@@ -3227,52 +3227,9 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
MHD_connection_update_event_loop_info (connection);
#ifdef EPOLL_SUPPORT
if (0 != (daemon->options & MHD_USE_EPOLL))
{
switch (connection->event_loop_info)
{
case MHD_EVENT_LOOP_INFO_READ:
if ( (0 != (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) &&
(0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) &&
(0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) )
{
EDLL_insert (daemon->eready_head,
daemon->eready_tail,
connection);
connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
}
break;
case MHD_EVENT_LOOP_INFO_WRITE:
if ( (0 != (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) &&
(0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) &&
(0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) )
{
EDLL_insert (daemon->eready_head,
daemon->eready_tail,
connection);
connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
}
break;
case MHD_EVENT_LOOP_INFO_BLOCK:
/* we should look at this connection again in the next iteration
of the event loop, as we're waiting on the application */
if ( (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) &&
(0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED))) )
{
EDLL_insert (daemon->eready_head,
daemon->eready_tail,
connection);
connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
}
break;
case MHD_EVENT_LOOP_INFO_CLEANUP:
/* This connection is finished, nothing left to do */
break;
}
}
return MHD_connection_epoll_update_ (connection);
#else
return MHD_connection_epoll_update_ (connection);
#endif /* EPOLL_SUPPORT */
return MHD_YES;
#endif
}
+32 -7
View File
@@ -2900,6 +2900,15 @@ MHD_get_timeout (struct MHD_Daemon *daemon,
return MHD_YES;
}
#endif /* HTTPS_SUPPORT */
#ifdef EPOLL_SUPPORT
if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
(NULL != daemon->eready_head) )
{
/* Some connection(s) already have some data pending. */
*timeout = 0;
return MHD_YES;
}
#endif /* EPOLL_SUPPORT */
have_timeout = MHD_NO;
earliest_deadline = 0; /* avoid compiler warnings */
@@ -3685,6 +3694,7 @@ MHD_epoll (struct MHD_Daemon *daemon,
#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
struct MHD_Connection *pos;
struct MHD_Connection *next;
struct MHD_Connection *prev;
struct epoll_event events[MAX_EVENTS];
struct epoll_event event;
int timeout_ms;
@@ -3887,16 +3897,31 @@ MHD_epoll (struct MHD_Daemon *daemon,
(void) resume_suspended_connections (daemon);
/* process events for connections */
while (NULL != (pos = daemon->eready_tail))
prev = daemon->eready_tail;
while (NULL != (pos = prev))
{
EDLL_remove (daemon->eready_head,
daemon->eready_tail,
pos);
pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
prev = pos->prevE;
/* FIXME: use (0 != pos->epoll_state & MHD_EPOLL_STATE_READ_READY) ? MHD_YES : MHD_NO
* and (0 != pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY) ? MHD_YES : MHD_NO */
call_handlers (pos,
MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info,
MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info,
(MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) ? MHD_YES : MHD_NO,
(MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) ? MHD_YES : MHD_NO,
MHD_NO);
if (MHD_EPOLL_STATE_IN_EREADY_EDLL ==
(pos->epoll_state & (MHD_EPOLL_STATE_SUSPENDED | MHD_EPOLL_STATE_IN_EREADY_EDLL)))
{
if ( (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info &&
0 == (pos->epoll_state & MHD_EPOLL_STATE_READ_READY) ) ||
(MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info &&
0 == (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY) ) ||
MHD_EVENT_LOOP_INFO_CLEANUP == pos->event_loop_info)
{
EDLL_remove (daemon->eready_head,
daemon->eready_tail,
pos);
pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
}
}
}
/* Finally, handle timed-out connections; we need to do this here
+3
View File
@@ -884,16 +884,19 @@ struct MHD_Connection
/**
* Handler used for processing read connection operations
* @sa #MHD_connection_handle_read, #MHD_tls_connection_handle_read
*/
int (*read_handler) (struct MHD_Connection *connection);
/**
* Handler used for processing write connection operations
* @sa #MHD_connection_handle_write, #MHD_tls_connection_handle_write
*/
int (*write_handler) (struct MHD_Connection *connection);
/**
* Handler used for processing idle connection operations
* @sa #MHD_connection_handle_idle, #MHD_tls_connection_handle_idle
*/
int (*idle_handler) (struct MHD_Connection *connection);