diff --git a/include/proto/fd.h b/include/proto/fd.h index c87dc3dc3..4f75bd6a3 100644 --- a/include/proto/fd.h +++ b/include/proto/fd.h @@ -252,6 +252,17 @@ static inline void fd_may_recv(const int fd) updt_fd(fd); } +/* Disable readiness when polled. This is useful to interrupt reading when it + * is suspected that the end of data might have been reached (eg: short read). + * This can only be done using level-triggered pollers, so if any edge-triggered + * is ever implemented, a test will have to be added here. + */ +static inline void fd_done_recv(const int fd) +{ + if (fd_recv_polled(fd)) + fd_cant_recv(fd); +} + /* Report that FD cannot send anymore without polling (EAGAIN detected). */ static inline void fd_cant_send(const int fd) { diff --git a/src/listener.c b/src/listener.c index ba7d727fb..836ca70a4 100644 --- a/src/listener.c +++ b/src/listener.c @@ -356,7 +356,7 @@ void listener_accept(int fd) return; default: /* unexpected result, let's give up and let other tasks run */ - return; + goto stop; } } @@ -414,6 +414,8 @@ void listener_accept(int fd) } /* end of while (max_accept--) */ /* we've exhausted max_accept, so there is no need to poll again */ + stop: + fd_done_recv(fd); return; } diff --git a/src/raw_sock.c b/src/raw_sock.c index a67a8d979..fda7de19a 100644 --- a/src/raw_sock.c +++ b/src/raw_sock.c @@ -176,6 +176,7 @@ int raw_sock_to_pipe(struct connection *conn, struct pipe *pipe, unsigned int co * being asked to poll. */ conn->flags |= CO_FL_WAIT_ROOM; + fd_done_recv(conn->t.sock.fd); break; } } /* while */ @@ -299,6 +300,8 @@ static int raw_sock_to_buf(struct connection *conn, struct buffer *buf, int coun */ if (fdtab[conn->t.sock.fd].ev & FD_POLL_HUP) goto read0; + + fd_done_recv(conn->t.sock.fd); break; } count -= ret;