From: Willy Tarreau Date: Fri, 9 Jan 2009 10:13:00 +0000 (+0100) Subject: [OPTIM] buffer: replace rlim by max_len X-Git-Tag: v1.3.16-rc1~80 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=03d60bbaf96b6e5c1e0a8a6abb6a145488464c58;p=thirdparty%2Fhaproxy.git [OPTIM] buffer: replace rlim by max_len In the buffers, the read limit used to leave some place for header rewriting was set by a pointer to the end of the buffer. Not only this required subtracts at every place in the code, but this will also soon not be usable anymore when we want to support keepalive. Let's replace this with a length limit, comparable to the buffer's length. This has also sightly reduced the code size. --- diff --git a/include/proto/buffers.h b/include/proto/buffers.h index b0aad624fa..1cd6650761 100644 --- a/include/proto/buffers.h +++ b/include/proto/buffers.h @@ -38,7 +38,7 @@ extern struct pool_head *pool2_buffer; /* perform minimal intializations, report 0 in case of error, 1 if OK. */ int init_buffer(); -/* Initializes all fields in the buffer. The ->rlim field is initialized last +/* Initializes all fields in the buffer. The ->max_len field is initialized last * so that the compiler can optimize it away if changed immediately after the * call to this function. By default, it is set to the full size of the buffer. * The BF_EMPTY flags is set. @@ -53,7 +53,7 @@ static inline void buffer_init(struct buffer *buf) buf->cons = NULL; buf->flags = BF_EMPTY; buf->r = buf->lr = buf->w = buf->data; - buf->rlim = buf->data + BUFSIZE; + buf->max_len = BUFSIZE; } /* returns 1 if the buffer is empty, 0 otherwise */ @@ -119,7 +119,7 @@ static inline void buffer_flush(struct buffer *buf) buf->r = buf->lr = buf->w = buf->data; buf->l = 0; buf->flags |= BF_EMPTY | BF_FULL; - if (buf->rlim) + if (buf->max_len) buf->flags &= ~BF_FULL; } @@ -241,7 +241,7 @@ static inline int buffer_max(const struct buffer *buf) */ static inline void buffer_set_rlim(struct buffer *buf, int size) { - buf->rlim = buf->data + size; + buf->max_len = size; if (buf->l < size) buf->flags &= ~BF_FULL; else diff --git a/include/types/buffers.h b/include/types/buffers.h index 1ceb9bc031..11383f2953 100644 --- a/include/types/buffers.h +++ b/include/types/buffers.h @@ -56,7 +56,7 @@ #define BF_READ_ERROR 0x000008 /* unrecoverable error on producer side */ #define BF_READ_ACTIVITY (BF_READ_NULL|BF_READ_PARTIAL|BF_READ_ERROR) -#define BF_FULL 0x000010 /* buffer cannot accept any more data (l >= rlim-data) */ +#define BF_FULL 0x000010 /* buffer cannot accept any more data (l >= max_len) */ #define BF_SHUTR 0x000020 /* producer has already shut down */ #define BF_SHUTR_NOW 0x000040 /* the producer must shut down for reads immediately */ #define BF_READ_NOEXP 0x000080 /* producer should not expire */ @@ -129,7 +129,7 @@ struct buffer { unsigned int l; /* data length */ unsigned int splice_len; /* number of bytes remaining in splice, out of buffer */ char *r, *w, *lr; /* read ptr, write ptr, last read */ - char *rlim; /* read limit, used for header rewriting */ + unsigned int max_len; /* read limit, used to keep room for header rewriting */ unsigned int send_max; /* number of bytes the sender can consume om this buffer, <= l */ unsigned int to_forward; /* number of bytes to forward after send_max without a wake-up */ unsigned int analysers; /* bit field indicating what to do on the buffer */ diff --git a/src/backend.c b/src/backend.c index a8ffdb6dfc..573e7994fa 100644 --- a/src/backend.c +++ b/src/backend.c @@ -1211,7 +1211,7 @@ struct server *get_server_ph_post(struct session *s) http_find_header2("Transfer-Encoding", 17, msg->sol, &txn->hdr_idx, &ctx); if (ctx.idx && ctx.vlen >= 7 && strncasecmp(ctx.line+ctx.val, "chunked", 7) == 0) { unsigned int chunk = 0; - while ( params < req->rlim && !HTTP_IS_CRLF(*params)) { + while ( params < (req->data+req->max_len) && !HTTP_IS_CRLF(*params)) { char c = *params; if (ishex(c)) { unsigned int hex = toupper(c) - '0'; diff --git a/src/buffers.c b/src/buffers.c index 3938fc315c..c8681cfb8c 100644 --- a/src/buffers.c +++ b/src/buffers.c @@ -54,7 +54,7 @@ int buffer_write(struct buffer *buf, const char *msg, int len) buf->flags &= ~(BF_EMPTY|BF_FULL); if (buf->l == 0) buf->flags |= BF_EMPTY; - if (buf->l >= buf->rlim - buf->data) + if (buf->l >= buf->max_len) buf->flags |= BF_FULL; return -1; @@ -88,7 +88,7 @@ int buffer_write_chunk(struct buffer *buf, struct chunk *chunk) buf->flags &= ~(BF_EMPTY|BF_FULL); if (buf->l == 0) buf->flags |= BF_EMPTY; - if (buf->l >= buf->rlim - buf->data) + if (buf->l >= buf->max_len) buf->flags |= BF_FULL; chunk->len = 0; @@ -129,7 +129,7 @@ int buffer_replace(struct buffer *b, char *pos, char *end, const char *str) b->flags &= ~(BF_EMPTY|BF_FULL); if (b->l == 0) b->flags |= BF_EMPTY; - if (b->l >= b->rlim - b->data) + if (b->l >= b->max_len) b->flags |= BF_FULL; return delta; @@ -170,7 +170,7 @@ int buffer_replace2(struct buffer *b, char *pos, char *end, const char *str, int b->flags &= ~(BF_EMPTY|BF_FULL); if (b->l == 0) b->flags |= BF_EMPTY; - if (b->l >= b->rlim - b->data) + if (b->l >= b->max_len) b->flags |= BF_FULL; return delta; @@ -214,7 +214,7 @@ int buffer_insert_line2(struct buffer *b, char *pos, const char *str, int len) b->flags &= ~(BF_EMPTY|BF_FULL); if (b->l == 0) b->flags |= BF_EMPTY; - if (b->l >= b->rlim - b->data) + if (b->l >= b->max_len) b->flags |= BF_FULL; return delta; diff --git a/src/client.c b/src/client.c index 5885f06f4f..bf8519f177 100644 --- a/src/client.c +++ b/src/client.c @@ -370,7 +370,7 @@ 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 */ - s->req->rlim -= MAXREWRITE; + s->req->max_len -= MAXREWRITE; /* activate default analysers enabled for this listener */ s->req->analysers = l->analysers; diff --git a/src/proto_tcp.c b/src/proto_tcp.c index 5a1424f3ab..94907ec762 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -666,8 +666,8 @@ acl_fetch_req_ssl_ver(struct proxy *px, struct session *l4, void *l7, int dir, * all the part of the request which fits in a buffer is already * there. */ - if (msg_len > l4->req->rlim - l4->req->w) - msg_len = l4->req->rlim - l4->req->w; + if (msg_len > l4->req->max_len + l4->req->data - l4->req->w) + msg_len = l4->req->max_len + l4->req->data - l4->req->w; if (bleft < msg_len) goto too_short; diff --git a/src/stream_sock.c b/src/stream_sock.c index dbb60e7d11..16d7c5404e 100644 --- a/src/stream_sock.c +++ b/src/stream_sock.c @@ -65,21 +65,18 @@ int stream_sock_read(int fd) { /* * 1. compute the maximum block size we can read at once. */ - if (b->l == 0) { /* let's realign the buffer to optimize I/O */ - b->r = b->w = b->lr = b->data; - max = b->rlim - b->data; + if (b->l == 0) { + /* let's realign the buffer to optimize I/O */ + b->r = b->w = b->lr = b->data; + max = b->max_len; } else if (b->r > b->w) { - max = b->rlim - b->r; + max = b->data + b->max_len - b->r; } else { max = b->w - b->r; - /* FIXME: theorically, if w>0, we shouldn't have rlim < data+size anymore - * since it means that the rewrite protection has been removed. This - * implies that the if statement can be removed. - */ - if (max > b->rlim - b->data) - max = b->rlim - b->data; + if (max > b->max_len) + max = b->max_len; } if (unlikely(max == 0)) { @@ -134,7 +131,7 @@ int stream_sock_read(int fd) { b->total += ret; - if (b->l >= b->rlim - b->data) { + if (b->l >= b->max_len) { /* The buffer is now full, there's no point in going through * the loop again. */ @@ -397,7 +394,7 @@ int stream_sock_write(int fd) { b->flags |= BF_WRITE_PARTIAL; - if (b->l < b->rlim - b->data) + if (b->l < b->max_len) b->flags &= ~BF_FULL; if (b->w == b->data + BUFSIZE) {