]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: buffers: add new pointer wrappers and get rid of almost all buffer_wrap_add...
authorWilly Tarreau <w@1wt.eu>
Fri, 4 May 2012 19:35:27 +0000 (21:35 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 8 May 2012 10:28:14 +0000 (12:28 +0200)
buffer_wrap_add was convenient for the migration but is not handy at all.
Let's have new wrappers that report input begin/end and output begin/end
instead.

It looks like we'll also need a b_adv(ofs) to advance a buffer's pointer.

include/proto/buffers.h
src/buffers.c
src/proto_http.c
src/stream_sock.c

index f35da6496a0165e5d62a8a11f4574e5cbfc7eb4e..5caff85fb1cef25b920b9f1328c471d9bc1f699f 100644 (file)
@@ -69,6 +69,75 @@ static inline void buffer_init(struct buffer *buf)
 /* These functions are used to compute various buffer area sizes */
 /*****************************************************************/
 
+/* Returns an absolute pointer for a position relative to the current buffer's
+ * pointer. It is written so that it is optimal when <ofs> is a const. It is
+ * written as a macro instead of an inline function so that the compiler knows
+ * when it can optimize out the sign test on <ofs> when passed an unsigned int.
+ */
+#define b_ptr(b, ofs) \
+       ({            \
+               char *__ret = (b)->p + (ofs);                   \
+               if ((ofs) > 0 && __ret >= (b)->data + (b)->size)    \
+                       __ret -= (b)->size;                     \
+               else if ((ofs) < 0 && __ret < (b)->data)        \
+                       __ret += (b)->size;                     \
+               __ret;                                          \
+       })
+
+/* Returns the start of the input data in a buffer */
+static inline char *bi_ptr(const struct buffer *b)
+{
+       return b->p;
+}
+
+/* Returns the end of the input data in a buffer (pointer to next
+ * insertion point).
+ */
+static inline char *bi_end(const struct buffer *b)
+{
+       char *ret = b->p + b->i;
+
+       if (ret >= b->data + b->size)
+               ret -= b->size;
+       return ret;
+}
+
+/* Returns the amount of input data that can contiguously be read at once */
+static inline int bi_contig_data(const struct buffer *b)
+{
+       int data = b->data + b->size - b->p;
+
+       if (data > b->i)
+               data = b->i;
+       return data;
+}
+
+/* Returns the start of the output data in a buffer */
+static inline char *bo_ptr(const struct buffer *b)
+{
+       char *ret = b->p - b->o;
+
+       if (ret < b->data)
+               ret += b->size;
+       return ret;
+}
+
+/* Returns the end of the output data in a buffer */
+static inline char *bo_end(const struct buffer *b)
+{
+       return b->p;
+}
+
+/* Returns the amount of output data that can contiguously be read at once */
+static inline int bo_contig_data(const struct buffer *b)
+{
+       char *beg = b->p - b->o;
+
+       if (beg < b->data)
+               return b->data - beg;
+       return b->o;
+}
+
 /* Return the buffer's length in bytes by summing the input and the output */
 static inline int buffer_len(const struct buffer *buf)
 {
index 0352177a464269e745b64e5108cccf30bad8beba..40aa57a96fa165bfd4df27898562a0651c0a19e4 100644 (file)
@@ -46,7 +46,7 @@ unsigned long long buffer_forward(struct buffer *buf, unsigned long long bytes)
        if (!bytes)
                return 0;
        if (bytes <= (unsigned long long)buf->i) {
-               buf->p = buffer_wrap_add(buf, buf->p + bytes);
+               buf->p = b_ptr(buf, (unsigned int)bytes);
                buf->o += bytes;
                buf->i -= bytes;
                buf->flags &= ~BF_OUT_EMPTY;
@@ -54,7 +54,7 @@ unsigned long long buffer_forward(struct buffer *buf, unsigned long long bytes)
        }
 
        forwarded = buf->i;
-       buf->p = buffer_wrap_add(buf, buf->p + forwarded);
+       buf->p = bi_end(buf);
        buf->o += forwarded;
        buf->i = 0;
 
@@ -122,7 +122,7 @@ int buffer_write(struct buffer *buf, const char *msg, int len)
 
        memcpy(buf->p, msg, len);
        buf->o += len;
-       buf->p = buffer_wrap_add(buf, buf->p + len);
+       buf->p = b_ptr(buf, len);
        buf->total += len;
 
        buf->flags &= ~(BF_OUT_EMPTY|BF_FULL);
@@ -147,7 +147,7 @@ int buffer_put_char(struct buffer *buf, char c)
        if (buf->flags & BF_FULL)
                return -1;
 
-       *buffer_wrap_add(buf, buf->p + buf->i) = c;
+       *bi_end(buf) = c;
 
        buf->i++;
        if (buffer_len(buf) >= buffer_max_len(buf))
@@ -198,7 +198,7 @@ int buffer_put_block(struct buffer *buf, const char *blk, int len)
 
        /* OK so the data fits in the buffer in one or two blocks */
        max = buffer_contig_space_with_res(buf, buf->size - max);
-       memcpy(buffer_wrap_add(buf, buf->p + buf->i), blk, MIN(len, max));
+       memcpy(bi_end(buf), blk, MIN(len, max));
        if (len > max)
                memcpy(buf->data, blk + max, len - max);
 
@@ -213,7 +213,7 @@ int buffer_put_block(struct buffer *buf, const char *blk, int len)
                }
                buf->o += fwd;
                buf->i -= fwd;
-               buf->p = buffer_wrap_add(buf, buf->p + fwd);
+               buf->p = b_ptr(buf, fwd);
                buf->flags &= ~BF_OUT_EMPTY;
        }
 
@@ -251,7 +251,7 @@ int buffer_get_line(struct buffer *buf, char *str, int len)
                goto out;
        }
 
-       p = buffer_wrap_sub(buf, buf->p - buf->o);
+       p = bo_ptr(buf);
 
        if (max > buf->o) {
                max = buf->o;
@@ -297,14 +297,14 @@ int buffer_get_block(struct buffer *buf, char *blk, int len, int offset)
                return 0;
        }
 
-       firstblock = buf->data + buf->size - buffer_wrap_sub(buf, buf->p - buf->o);
+       firstblock = buf->data + buf->size - bo_ptr(buf);
        if (firstblock > offset) {
                if (firstblock >= len + offset) {
-                       memcpy(blk, buffer_wrap_sub(buf, buf->p - buf->o) + offset, len);
+                       memcpy(blk, bo_ptr(buf) + offset, len);
                        return len;
                }
 
-               memcpy(blk, buffer_wrap_sub(buf, buf->p - buf->o) + offset, firstblock - offset);
+               memcpy(blk, bo_ptr(buf) + offset, firstblock - offset);
                memcpy(blk + firstblock - offset, buf->data, len - firstblock + offset);
                return len;
        }
@@ -329,16 +329,16 @@ int buffer_replace2(struct buffer *b, char *pos, char *end, const char *str, int
 
        delta = len - (end - pos);
 
-       if (delta + buffer_wrap_add(b, b->p + b->i) >= b->data + b->size)
+       if (bi_end(b) + delta >= b->data + b->size)
                return 0;  /* no space left */
 
        if (buffer_not_empty(b) &&
-           delta + buffer_wrap_add(b, b->p + b->i) > buffer_wrap_sub(b, b->p - b->o) &&
-           buffer_wrap_sub(b, b->p - b->o) >= buffer_wrap_add(b, b->p + b->i))
+           bi_end(b) + delta > bo_ptr(b) &&
+           bo_ptr(b) >= bi_end(b))
                return 0;  /* no space left before wrapping data */
 
        /* first, protect the end of the buffer */
-       memmove(end + delta, end, buffer_wrap_add(b, b->p + b->i) - end);
+       memmove(end + delta, end, bi_end(b) - end);
 
        /* now, copy str over pos */
        if (len)
@@ -371,11 +371,11 @@ int buffer_insert_line2(struct buffer *b, char *pos, const char *str, int len)
 
        delta = len + 2;
 
-       if (delta + buffer_wrap_add(b, b->p + b->i) >= b->data + b->size)
+       if (bi_end(b) + delta >= b->data + b->size)
                return 0;  /* no space left */
 
        /* first, protect the end of the buffer */
-       memmove(pos + delta, pos, buffer_wrap_add(b, b->p + b->i) - pos);
+       memmove(pos + delta, pos, bi_end(b) - pos);
 
        /* now, copy str over pos */
        if (len && str) {
@@ -405,7 +405,7 @@ void buffer_bounce_realign(struct buffer *buf)
        int advance, to_move;
        char *from, *to;
 
-       from = buffer_wrap_sub(buf, buf->p - buf->o);
+       from = bo_ptr(buf);
        advance = buf->data + buf->size - from;
        if (!advance)
                return;
@@ -435,11 +435,11 @@ void buffer_bounce_realign(struct buffer *buf)
                         * empty area is either between buf->r and from or before from or
                         * after buf->r.
                         */
-                       if (from > buffer_wrap_add(buf, buf->p + buf->i)) {
-                               if (to >= buffer_wrap_add(buf, buf->p + buf->i) && to < from)
+                       if (from > bi_end(buf)) {
+                               if (to >= bi_end(buf) && to < from)
                                        break;
-                       } else if (from < buffer_wrap_add(buf, buf->p + buf->i)) {
-                               if (to < from || to >= buffer_wrap_add(buf, buf->p + buf->i))
+                       } else if (from < bi_end(buf)) {
+                               if (to < from || to >= bi_end(buf))
                                        break;
                        }
 
index 0dc2b51d62260dd5b22e27bdf4b7b199b028682c..eac0319cf84d0c3297037a2945ab9fa8bc170b95 100644 (file)
@@ -1744,10 +1744,10 @@ void http_change_connection_header(struct http_txn *txn, struct http_msg *msg, i
 int http_parse_chunk_size(struct http_msg *msg)
 {
        const struct buffer *buf = msg->buf;
-       const char *ptr = buffer_wrap_add(buf, buf->p + msg->next);
+       const char *ptr = b_ptr(buf, msg->next);
        const char *ptr_old = ptr;
        const char *end = buf->data + buf->size;
-       const char *stop = buffer_wrap_add(buf, buf->p + buf->i);
+       const char *stop = bi_end(buf);
        unsigned int chunk = 0;
 
        /* The chunk size is in the following form, though we are only
@@ -1856,8 +1856,8 @@ int http_forward_trailers(struct http_msg *msg)
        /* we have msg->next which points to next line. Look for CRLF. */
        while (1) {
                const char *p1 = NULL, *p2 = NULL;
-               const char *ptr = buffer_wrap_add(buf, buf->p + msg->next);
-               const char *stop = buffer_wrap_add(buf, buf->p + buf->i);
+               const char *ptr = b_ptr(buf, msg->next);
+               const char *stop = bi_end(buf);
                int bytes;
 
                /* scan current line and stop at LF or CRLF */
@@ -1890,7 +1890,7 @@ int http_forward_trailers(struct http_msg *msg)
                if (p2 >= buf->data + buf->size)
                        p2 = buf->data;
 
-               bytes = p2 - buffer_wrap_add(buf, buf->p + msg->next);
+               bytes = p2 - b_ptr(buf, msg->next);
                if (bytes < 0)
                        bytes += buf->size;
 
@@ -1899,7 +1899,7 @@ int http_forward_trailers(struct http_msg *msg)
                if (msg->sov >= buf->size)
                        msg->sov -= buf->size;
 
-               if (p1 == buffer_wrap_add(buf, buf->p + msg->next)) {
+               if (p1 == b_ptr(buf, msg->next)) {
                        /* LF/CRLF at beginning of line => end of trailers at p2.
                         * Everything was scheduled for forwarding, there's nothing
                         * left from this message.
@@ -2058,8 +2058,8 @@ int http_wait_for_request(struct session *s, struct buffer *req, int an_bit)
        if (buffer_not_empty(req) && msg->msg_state < HTTP_MSG_ERROR) {
                if ((txn->flags & TX_NOT_FIRST) &&
                    unlikely((req->flags & BF_FULL) ||
-                            buffer_wrap_add(req, req->p + req->i) < buffer_wrap_add(req, req->p + msg->next) ||
-                            buffer_wrap_add(req, req->p + req->i) > req->data + req->size - global.tune.maxrewrite)) {
+                            bi_end(req) < b_ptr(req, msg->next) ||
+                            bi_end(req) > req->data + req->size - global.tune.maxrewrite)) {
                        if (req->o) {
                                if (req->flags & (BF_SHUTW|BF_SHUTW_NOW|BF_WRITE_ERROR|BF_WRITE_TIMEOUT))
                                        goto failed_keep_alive;
@@ -2068,8 +2068,8 @@ int http_wait_for_request(struct session *s, struct buffer *req, int an_bit)
                                req->flags |= BF_READ_DONTWAIT; /* try to get back here ASAP */
                                return 0;
                        }
-                       if (buffer_wrap_add(req, req->p + req->i) < buffer_wrap_add(req, req->p + msg->next) ||
-                           buffer_wrap_add(req, req->p + req->i) > req->data + req->size - global.tune.maxrewrite)
+                       if (bi_end(req) < b_ptr(req, msg->next) ||
+                           bi_end(req) > req->data + req->size - global.tune.maxrewrite)
                                http_message_realign(msg);
                }
 
@@ -2082,8 +2082,8 @@ int http_wait_for_request(struct session *s, struct buffer *req, int an_bit)
                 */
                if ((txn->flags & TX_NOT_FIRST) &&
                    unlikely((s->rep->flags & BF_FULL) ||
-                            buffer_wrap_add(s->rep, s->rep->p + s->rep->i) < buffer_wrap_add(s->rep, s->rep->p + txn->rsp.next) ||
-                            buffer_wrap_add(s->rep, s->rep->p + s->rep->i) > s->rep->data + s->rep->size - global.tune.maxrewrite)) {
+                            bi_end(s->rep) < b_ptr(s->rep, txn->rsp.next) ||
+                            bi_end(s->rep) > s->rep->data + s->rep->size - global.tune.maxrewrite)) {
                        if (s->rep->o) {
                                if (s->rep->flags & (BF_SHUTW|BF_SHUTW_NOW|BF_WRITE_ERROR|BF_WRITE_TIMEOUT))
                                        goto failed_keep_alive;
@@ -3812,7 +3812,7 @@ void http_end_txn_clean_session(struct session *s)
        if (s->req->i) {
                if (s->rep->o &&
                    !(s->rep->flags & BF_FULL) &&
-                   buffer_wrap_add(s->rep, s->rep->p + s->rep->i) <= s->rep->data + s->rep->size - global.tune.maxrewrite)
+                   bi_end(s->rep) <= s->rep->data + s->rep->size - global.tune.maxrewrite)
                        s->rep->flags |= BF_EXPECT_MORE;
        }
 
@@ -4469,8 +4469,8 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit)
         */
        if (buffer_not_empty(rep) && msg->msg_state < HTTP_MSG_ERROR) {
                if (unlikely((rep->flags & BF_FULL) ||
-                            buffer_wrap_add(rep, rep->p + rep->i) < buffer_wrap_add(rep, rep->p + msg->next) ||
-                            buffer_wrap_add(rep, rep->p + rep->i) > rep->data + rep->size - global.tune.maxrewrite)) {
+                            bi_end(rep) < b_ptr(rep, msg->next) ||
+                            bi_end(rep) > rep->data + rep->size - global.tune.maxrewrite)) {
                        if (rep->o) {
                                /* some data has still not left the buffer, wake us once that's done */
                                if (rep->flags & (BF_SHUTW|BF_SHUTW_NOW|BF_WRITE_ERROR|BF_WRITE_TIMEOUT))
@@ -7221,24 +7221,24 @@ void http_capture_bad_message(struct error_snapshot *es, struct session *s,
 {
        struct buffer *buf = msg->buf;
 
-       if (buffer_wrap_add(buf, buf->p + buf->i) <= (buf->p + msg->som)) { /* message wraps */
+       if (bi_end(buf) <= (buf->p + msg->som)) { /* message wraps */
                int len1 = buf->size - msg->som - (buf->p - buf->data);
-               es->len = buffer_wrap_add(buf, buf->p + buf->i) - (buf->p + msg->som) + buf->size;
+               es->len = bi_end(buf) - (buf->p + msg->som) + buf->size;
                memcpy(es->buf, buf->p + msg->som, MIN(len1, sizeof(es->buf)));
                if (es->len > len1 && len1 < sizeof(es->buf))
                        memcpy(es->buf, buf->data, MIN(es->len, sizeof(es->buf)) - len1);
        }
        else {
-               es->len = buffer_wrap_add(buf, buf->p + buf->i) - (buf->p + msg->som);
+               es->len = bi_end(buf) - (buf->p + msg->som);
                memcpy(es->buf, buf->p + msg->som, MIN(es->len, sizeof(es->buf)));
        }
 
        if (msg->err_pos >= 0)
                es->pos  = msg->err_pos - msg->som - (buf->p - buf->data);
-       else if (buffer_wrap_add(buf, buf->p + msg->next) >= (buf->p + msg->som))
-               es->pos  = buffer_wrap_add(buf, buf->p + msg->next) - (buf->p + msg->som);
+       else if (b_ptr(buf, msg->next) >= (buf->p + msg->som))
+               es->pos  = b_ptr(buf, msg->next) - (buf->p + msg->som);
        else
-               es->pos  = buffer_wrap_add(buf, buf->p + msg->next) - (buf->p + msg->som) + buf->size;
+               es->pos  = b_ptr(buf, msg->next) - (buf->p + msg->som) + buf->size;
 
        es->when = date; // user-visible date
        es->sid  = s->uniq_id;
index 0baf825bf29bc1ac9e7aef62b627611465884fdf..038e8c81a100393de5ac0dceb1b90859f498deab 100644 (file)
@@ -295,7 +295,7 @@ int stream_sock_read(int fd) {
                /*
                 * 2. read the largest possible block
                 */
-               ret = recv(fd, buffer_wrap_add(b, b->p + b->i), max, 0);
+               ret = recv(fd, bi_end(b), max, 0);
 
                if (ret > 0) {
                        b->i += ret;
@@ -311,7 +311,7 @@ int stream_sock_read(int fd) {
                                }
                                b->o += fwd;
                                b->i -= fwd;
-                               b->p = buffer_wrap_add(b, b->p + fwd);
+                               b->p = b_ptr(b, fwd);
                                b->flags &= ~BF_OUT_EMPTY;
                        }
 
@@ -626,7 +626,7 @@ static int stream_sock_write_loop(struct stream_interface *si, struct buffer *b)
                        if (b->flags & BF_SEND_DONTWAIT)
                                send_flag &= ~MSG_MORE;
 
-                       ret = send(si->fd, buffer_wrap_sub(b, b->p - b->o), max, send_flag);
+                       ret = send(si->fd, bo_ptr(b), max, send_flag);
                } else {
                        int skerr;
                        socklen_t lskerr = sizeof(skerr);
@@ -635,7 +635,7 @@ static int stream_sock_write_loop(struct stream_interface *si, struct buffer *b)
                        if (ret == -1 || skerr)
                                ret = -1;
                        else
-                               ret = send(si->fd, buffer_wrap_sub(b, b->p - b->o), max, MSG_DONTWAIT);
+                               ret = send(si->fd, bo_ptr(b), max, MSG_DONTWAIT);
                }
 
                if (ret > 0) {