diff --git a/nsock/src/engine_epoll.c b/nsock/src/engine_epoll.c index c4f9183fe..edc4fdcd9 100644 --- a/nsock/src/engine_epoll.c +++ b/nsock/src/engine_epoll.c @@ -74,12 +74,12 @@ #define EPOLL_R_FLAGS (EPOLLIN | EPOLLPRI) #define EPOLL_W_FLAGS EPOLLOUT -#ifdef EPOLLRDHUP - #define EPOLL_X_FLAGS (EPOLLERR | EPOLLRDHUP| EPOLLHUP) -#else - /* EPOLLRDHUP was introduced later and might be unavailable on older systems. */ - #define EPOLL_X_FLAGS (EPOLLERR | EPOLLHUP) -#endif /* EPOLLRDHUP */ + +/* EPOLLRDHUP was introduced later and might be unavailable on older systems. */ +#ifndef EPOLLRDHUP + #define EPOLLRDHUP 0 +#endif +#define EPOLL_X_FLAGS (EPOLLERR | EPOLLRDHUP| EPOLLHUP) /* --- ENGINE INTERFACE PROTOTYPES --- */ @@ -178,8 +178,6 @@ int epoll_iod_register(struct npool *nsp, struct niod *iod, struct nevent *nse, epev.events |= EPOLL_R_FLAGS; if (ev & EV_WRITE) epev.events |= EPOLL_W_FLAGS; - if (ev & EV_EXCEPT) - epev.events |= EPOLL_X_FLAGS; sd = nsock_iod_get_sd(iod); if (epoll_ctl(einfo->epfd, EPOLL_CTL_ADD, sd, &epev) < 0) @@ -233,8 +231,6 @@ int epoll_iod_modify(struct npool *nsp, struct niod *iod, struct nevent *nse, in epev.events |= EPOLL_R_FLAGS; if (iod->watched_events & EV_WRITE) epev.events |= EPOLL_W_FLAGS; - if (iod->watched_events & EV_EXCEPT) - epev.events |= EPOLL_X_FLAGS; sd = nsock_iod_get_sd(iod); @@ -328,7 +324,7 @@ static inline int get_evmask(struct epoll_engine_info *einfo, int n) { if (einfo->events[n].events & EPOLL_W_FLAGS) evmask |= EV_WRITE; if (einfo->events[n].events & EPOLL_X_FLAGS) - evmask |= (EV_READ | EV_WRITE | EV_EXCEPT); + evmask |= EV_EXCEPT; return evmask; } diff --git a/nsock/src/engine_poll.c b/nsock/src/engine_poll.c index 9c54387c9..9492a7fbc 100644 --- a/nsock/src/engine_poll.c +++ b/nsock/src/engine_poll.c @@ -294,10 +294,6 @@ int poll_iod_modify(struct npool *nsp, struct niod *iod, struct nevent *nse, int pinfo->events[sd].events |= POLL_R_FLAGS; if (iod->watched_events & EV_WRITE) pinfo->events[sd].events |= POLL_W_FLAGS; -#ifndef WIN32 - if (iod->watched_events & EV_EXCEPT) - pinfo->events[sd].events |= POLL_X_FLAGS; -#endif return 1; } @@ -403,7 +399,7 @@ static inline int get_evmask(struct npool *nsp, struct niod *nsi) { if (pev->revents & POLL_W_FLAGS) evmask |= EV_WRITE; if (pev->events && (pev->revents & POLL_X_FLAGS)) - evmask |= (EV_READ | EV_WRITE | EV_EXCEPT); + evmask |= EV_EXCEPT; } return evmask; } diff --git a/nsock/src/engine_select.c b/nsock/src/engine_select.c index abc3719ec..c5dff15c8 100644 --- a/nsock/src/engine_select.c +++ b/nsock/src/engine_select.c @@ -208,6 +208,9 @@ int select_iod_modify(struct npool *nsp, struct niod *iod, struct nevent *nse, i iod->watched_events |= ev_set; iod->watched_events &= ~ev_clr; + ev_set |= EV_EXCEPT; + ev_clr &= ~EV_EXCEPT; + sd = nsock_iod_get_sd(iod); /* -- set events -- */ @@ -233,7 +236,7 @@ int select_iod_modify(struct npool *nsp, struct niod *iod, struct nevent *nse, i /* -- update max_sd -- */ if (ev_set != EV_NONE) - sinfo->max_sd = MAX(sinfo->max_sd,sd); + sinfo->max_sd = MAX(sinfo->max_sd, sd); else if (ev_clr != EV_NONE && iod->events_pending == 1 && (sinfo->max_sd == sd)) sinfo->max_sd--; diff --git a/nsock/src/nsock_core.c b/nsock/src/nsock_core.c index a2e727d7d..e4faf8a80 100644 --- a/nsock/src/nsock_core.c +++ b/nsock/src/nsock_core.c @@ -168,6 +168,18 @@ static int socket_count_dec_ssl_desire(struct nevent *nse) { } #endif +static int should_clear_ev_read(const struct niod *iod, int ev_set) { + return (ev_set & EV_READ) && +#if HAVE_PCAP + !iod->readpcapsd_count && +#endif + !iod->readsd_count; +} + +static int should_clear_ev_write(const struct niod *iod, int ev_set) { + return (ev_set & EV_WRITE) && !iod->writesd_count; +} + /* Update the events that the IO engine should watch for a given IOD. * * ev_inc is a set of events for which the event counters should be increased. @@ -188,18 +200,18 @@ static void update_events(struct niod * iod, struct npool *ms, struct nevent *ns setmask = ev_inc; clrmask = EV_NONE; - if ((ev_dec & EV_READ) && -#if HAVE_PCAP - !iod->readpcapsd_count && -#endif - !iod->readsd_count) + if (should_clear_ev_read(iod, ev_dec)) clrmask |= EV_READ; - if ((ev_dec & EV_WRITE) && !iod->writesd_count) + if (should_clear_ev_write(iod, ev_dec)) clrmask |= EV_WRITE; + /* EV_EXCEPT is systematically set and cannot be removed */ + if (ev_inc & EV_EXCEPT) + nsock_log_info("Invalid event set, no need to specify EV_EXCEPT"); + if (ev_dec & EV_EXCEPT) - clrmask |= EV_EXCEPT; + nsock_log_info("Invalid event set, refusing to clear EV_EXCEPT"); if (!IOD_PROPGET(iod, IOD_REGISTERED)) { assert(clrmask == EV_NONE); @@ -399,7 +411,6 @@ void handle_connect_result(struct npool *ms, struct nevent *nse, enum nse_status ev |= socket_count_read_dec(iod); ev |= socket_count_write_dec(iod); - ev |= EV_EXCEPT; update_events(iod, ms, nse, EV_NONE, ev); } @@ -924,7 +935,9 @@ enum nsock_loopstatus nsock_loop(nsock_pool nsp, int msec_timeout) { } void process_event(struct npool *nsp, gh_list_t *evlist, struct nevent *nse, int ev) { - int match_r = 0, match_w = 0; + int match_r = ev & EV_READ; + int match_w = ev & EV_WRITE; + int match_x = ev & EV_EXCEPT; #if HAVE_OPENSSL int desire_r = 0, desire_w = 0; #endif @@ -945,8 +958,6 @@ void process_event(struct npool *nsp, gh_list_t *evlist, struct nevent *nse, int break; case NSE_TYPE_READ: - match_r = ev & EV_READ; - match_w = ev & EV_WRITE; #if HAVE_OPENSSL desire_r = nse->sslinfo.ssl_desire == SSL_ERROR_WANT_READ; desire_w = nse->sslinfo.ssl_desire == SSL_ERROR_WANT_WRITE; @@ -954,16 +965,15 @@ void process_event(struct npool *nsp, gh_list_t *evlist, struct nevent *nse, int handle_read_result(nsp, nse, NSE_STATUS_SUCCESS); else #endif - if (!nse->iod->ssl && match_r) + if ((!nse->iod->ssl && match_r) || match_x) handle_read_result(nsp, nse, NSE_STATUS_SUCCESS); if (event_timedout(nse)) handle_read_result(nsp, nse, NSE_STATUS_TIMEOUT); + break; case NSE_TYPE_WRITE: - match_r = ev & EV_READ; - match_w = ev & EV_WRITE; #if HAVE_OPENSSL desire_r = nse->sslinfo.ssl_desire == SSL_ERROR_WANT_READ; desire_w = nse->sslinfo.ssl_desire == SSL_ERROR_WANT_WRITE; @@ -971,7 +981,7 @@ void process_event(struct npool *nsp, gh_list_t *evlist, struct nevent *nse, int handle_write_result(nsp, nse, NSE_STATUS_SUCCESS); else #endif - if (!nse->iod->ssl && match_w) + if ((!nse->iod->ssl && match_w) || match_x) handle_write_result(nsp, nse, NSE_STATUS_SUCCESS); if (event_timedout(nse)) @@ -1236,7 +1246,7 @@ void nsock_pool_add_event(struct npool *nsp, struct nevent *nse) { assert(nse->iod->sd >= 0); socket_count_read_inc(nse->iod); socket_count_write_inc(nse->iod); - update_events(nse->iod, nsp, nse, EV_READ|EV_WRITE|EV_EXCEPT, EV_NONE); + update_events(nse->iod, nsp, nse, EV_READ|EV_WRITE, EV_NONE); } iod_add_event(nse->iod, nse); break;