diff --git a/include/types/buffers.h b/include/types/buffers.h index 3b0c3a12a..faad019b2 100644 --- a/include/types/buffers.h +++ b/include/types/buffers.h @@ -84,6 +84,7 @@ #define BF_ANA_TIMEOUT 0x080000 /* the analyser timeout has expired */ #define BF_READ_ATTACHED 0x100000 /* the read side is attached for the first time */ #define BF_KERN_SPLICING 0x200000 /* kernel splicing desired for this buffer */ +#define BF_READ_DONTWAIT 0x400000 /* wake the task up after every read (eg: HTTP request) */ /* Use these masks to clear the flags before going back to lower layers */ #define BF_CLEAR_READ (~(BF_READ_NULL|BF_READ_PARTIAL|BF_READ_ERROR|BF_READ_ATTACHED)) diff --git a/src/client.c b/src/client.c index 765a54b37..05ee8d540 100644 --- a/src/client.c +++ b/src/client.c @@ -374,8 +374,10 @@ int event_accept(int fd) { s->req->flags |= BF_READ_ATTACHED; /* the producer is already connected */ - if (p->mode == PR_MODE_HTTP) /* reserve some space for header rewriting */ + if (p->mode == PR_MODE_HTTP) { /* reserve some space for header rewriting */ s->req->max_len -= MAXREWRITE; + s->req->flags |= BF_READ_DONTWAIT; /* one read is usually enough */ + } /* activate default analysers enabled for this listener */ s->req->analysers = l->analysers; diff --git a/src/proto_http.c b/src/proto_http.c index 8c8ff6340..8ab41992b 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -1648,6 +1648,8 @@ int http_process_request(struct session *s, struct buffer *req) } buffer_write_dis(req); + req->flags |= BF_READ_DONTWAIT; /* try to get back here ASAP */ + /* just set the request timeout once at the beginning of the request */ if (!tick_isset(req->analyse_exp)) req->analyse_exp = tick_add_ifset(now_ms, s->fe->timeout.httpreq); diff --git a/src/proto_uxst.c b/src/proto_uxst.c index baf91ef1e..0edc2aff2 100644 --- a/src/proto_uxst.c +++ b/src/proto_uxst.c @@ -488,6 +488,7 @@ int uxst_event_accept(int fd) { s->req->cons = &s->si[1]; s->si[0].ib = s->si[1].ob = s->req; s->req->flags |= BF_READ_ATTACHED; /* the producer is already connected */ + s->req->flags |= BF_READ_DONTWAIT; /* we plan to read small requests */ s->req->analysers = l->analysers; @@ -684,6 +685,7 @@ int uxst_req_analyser_stats(struct session *s, struct buffer *req) return 0; } /* don't forward nor abort */ + req->flags |= BF_READ_DONTWAIT; /* we plan to read small requests */ return 0; case STATS_ST_REP: diff --git a/src/stream_sock.c b/src/stream_sock.c index a942d4081..83c3c8840 100644 --- a/src/stream_sock.c +++ b/src/stream_sock.c @@ -421,7 +421,7 @@ int stream_sock_read(int fd) { break; } - if (--read_poll <= 0) + if ((b->flags & BF_READ_DONTWAIT) || --read_poll <= 0) break; } else if (ret == 0) { @@ -467,13 +467,14 @@ int stream_sock_read(int fd) { /* we have to wake up if there is a special event or if we don't have * any more data to forward. */ - if ((b->flags & (BF_READ_NULL|BF_READ_ERROR|BF_SHUTR)) || + if ((b->flags & (BF_READ_NULL|BF_READ_ERROR|BF_SHUTR|BF_READ_DONTWAIT)) || !b->to_forward || si->state != SI_ST_EST || b->cons->state != SI_ST_EST || (si->flags & SI_FL_ERR)) task_wakeup(si->owner, TASK_WOKEN_IO); + b->flags &= ~BF_READ_DONTWAIT; fdtab[fd].ev &= ~FD_POLL_IN; return retval;