aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2017-02-08 22:33:29 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2017-02-08 22:44:21 +0300
commit47fdebac4b2a16ef84ef96e11ebdc2b1d1310fd8 (patch)
tree625fa43ca12f587a7af44aab1c6ac8e30ffc6949
parenteba022ce02aef76fd7d4babed1ce248d50427112 (diff)
downloadlibmicrohttpd-47fdebac4b2a16ef84ef96e11ebdc2b1d1310fd8.tar.gz
libmicrohttpd-47fdebac4b2a16ef84ef96e11ebdc2b1d1310fd8.zip
Rewrote epoll handling: handle all connections instead of drying last active
-rw-r--r--src/microhttpd/connection.c47
-rw-r--r--src/microhttpd/daemon.c39
-rw-r--r--src/microhttpd/internal.h3
3 files changed, 37 insertions, 52 deletions
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index abcf3fa0..ef596dad 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -3227,52 +3227,9 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
3227 MHD_connection_update_event_loop_info (connection); 3227 MHD_connection_update_event_loop_info (connection);
3228#ifdef EPOLL_SUPPORT 3228#ifdef EPOLL_SUPPORT
3229 if (0 != (daemon->options & MHD_USE_EPOLL)) 3229 if (0 != (daemon->options & MHD_USE_EPOLL))
3230 { 3230 return MHD_connection_epoll_update_ (connection);
3231 switch (connection->event_loop_info) 3231#endif /* EPOLL_SUPPORT */
3232 {
3233 case MHD_EVENT_LOOP_INFO_READ:
3234 if ( (0 != (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) &&
3235 (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) &&
3236 (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) )
3237 {
3238 EDLL_insert (daemon->eready_head,
3239 daemon->eready_tail,
3240 connection);
3241 connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
3242 }
3243 break;
3244 case MHD_EVENT_LOOP_INFO_WRITE:
3245 if ( (0 != (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) &&
3246 (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED)) &&
3247 (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) )
3248 {
3249 EDLL_insert (daemon->eready_head,
3250 daemon->eready_tail,
3251 connection);
3252 connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
3253 }
3254 break;
3255 case MHD_EVENT_LOOP_INFO_BLOCK:
3256 /* we should look at this connection again in the next iteration
3257 of the event loop, as we're waiting on the application */
3258 if ( (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) &&
3259 (0 == (connection->epoll_state & MHD_EPOLL_STATE_SUSPENDED))) )
3260 {
3261 EDLL_insert (daemon->eready_head,
3262 daemon->eready_tail,
3263 connection);
3264 connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
3265 }
3266 break;
3267 case MHD_EVENT_LOOP_INFO_CLEANUP:
3268 /* This connection is finished, nothing left to do */
3269 break;
3270 }
3271 }
3272 return MHD_connection_epoll_update_ (connection);
3273#else
3274 return MHD_YES; 3232 return MHD_YES;
3275#endif
3276} 3233}
3277 3234
3278 3235
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 82438bfa..6f010ec7 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -2900,6 +2900,15 @@ MHD_get_timeout (struct MHD_Daemon *daemon,
2900 return MHD_YES; 2900 return MHD_YES;
2901 } 2901 }
2902#endif /* HTTPS_SUPPORT */ 2902#endif /* HTTPS_SUPPORT */
2903#ifdef EPOLL_SUPPORT
2904 if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
2905 (NULL != daemon->eready_head) )
2906 {
2907 /* Some connection(s) already have some data pending. */
2908 *timeout = 0;
2909 return MHD_YES;
2910 }
2911#endif /* EPOLL_SUPPORT */
2903 2912
2904 have_timeout = MHD_NO; 2913 have_timeout = MHD_NO;
2905 earliest_deadline = 0; /* avoid compiler warnings */ 2914 earliest_deadline = 0; /* avoid compiler warnings */
@@ -3685,6 +3694,7 @@ MHD_epoll (struct MHD_Daemon *daemon,
3685#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ 3694#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
3686 struct MHD_Connection *pos; 3695 struct MHD_Connection *pos;
3687 struct MHD_Connection *next; 3696 struct MHD_Connection *next;
3697 struct MHD_Connection *prev;
3688 struct epoll_event events[MAX_EVENTS]; 3698 struct epoll_event events[MAX_EVENTS];
3689 struct epoll_event event; 3699 struct epoll_event event;
3690 int timeout_ms; 3700 int timeout_ms;
@@ -3887,16 +3897,31 @@ MHD_epoll (struct MHD_Daemon *daemon,
3887 (void) resume_suspended_connections (daemon); 3897 (void) resume_suspended_connections (daemon);
3888 3898
3889 /* process events for connections */ 3899 /* process events for connections */
3890 while (NULL != (pos = daemon->eready_tail)) 3900 prev = daemon->eready_tail;
3901 while (NULL != (pos = prev))
3891 { 3902 {
3892 EDLL_remove (daemon->eready_head, 3903 prev = pos->prevE;
3893 daemon->eready_tail, 3904 /* FIXME: use (0 != pos->epoll_state & MHD_EPOLL_STATE_READ_READY) ? MHD_YES : MHD_NO
3894 pos); 3905 * and (0 != pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY) ? MHD_YES : MHD_NO */
3895 pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
3896 call_handlers (pos, 3906 call_handlers (pos,
3897 MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info, 3907 (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) ? MHD_YES : MHD_NO,
3898 MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info, 3908 (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) ? MHD_YES : MHD_NO,
3899 MHD_NO); 3909 MHD_NO);
3910 if (MHD_EPOLL_STATE_IN_EREADY_EDLL ==
3911 (pos->epoll_state & (MHD_EPOLL_STATE_SUSPENDED | MHD_EPOLL_STATE_IN_EREADY_EDLL)))
3912 {
3913 if ( (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info &&
3914 0 == (pos->epoll_state & MHD_EPOLL_STATE_READ_READY) ) ||
3915 (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info &&
3916 0 == (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY) ) ||
3917 MHD_EVENT_LOOP_INFO_CLEANUP == pos->event_loop_info)
3918 {
3919 EDLL_remove (daemon->eready_head,
3920 daemon->eready_tail,
3921 pos);
3922 pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
3923 }
3924 }
3900 } 3925 }
3901 3926
3902 /* Finally, handle timed-out connections; we need to do this here 3927 /* Finally, handle timed-out connections; we need to do this here
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index c9d21aa4..abe0f291 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -884,16 +884,19 @@ struct MHD_Connection
884 884
885 /** 885 /**
886 * Handler used for processing read connection operations 886 * Handler used for processing read connection operations
887 * @sa #MHD_connection_handle_read, #MHD_tls_connection_handle_read
887 */ 888 */
888 int (*read_handler) (struct MHD_Connection *connection); 889 int (*read_handler) (struct MHD_Connection *connection);
889 890
890 /** 891 /**
891 * Handler used for processing write connection operations 892 * Handler used for processing write connection operations
893 * @sa #MHD_connection_handle_write, #MHD_tls_connection_handle_write
892 */ 894 */
893 int (*write_handler) (struct MHD_Connection *connection); 895 int (*write_handler) (struct MHD_Connection *connection);
894 896
895 /** 897 /**
896 * Handler used for processing idle connection operations 898 * Handler used for processing idle connection operations
899 * @sa #MHD_connection_handle_idle, #MHD_tls_connection_handle_idle
897 */ 900 */
898 int (*idle_handler) (struct MHD_Connection *connection); 901 int (*idle_handler) (struct MHD_Connection *connection);
899 902