diff --git a/include/common/buffer.h b/include/common/buffer.h index 2c992c7f8..5ea8fab41 100644 --- a/include/common/buffer.h +++ b/include/common/buffer.h @@ -40,6 +40,7 @@ struct buffer { }; extern struct pool_head *pool2_buffer; +extern struct buffer buf_empty; int init_buffer(); int buffer_replace2(struct buffer *b, char *pos, char *end, const char *str, int len); @@ -409,13 +410,27 @@ static inline struct buffer *b_alloc(struct buffer **buf) return *buf; } -/* Releases buffer *buf. - */ -static inline void b_free(struct buffer **buf) +/* Releases buffer *buf (no check of emptiness) */ +static inline void __b_drop(struct buffer **buf) { pool_free2(pool2_buffer, *buf); } +/* Releases buffer *buf if allocated. */ +static inline void b_drop(struct buffer **buf) +{ + if (!(*buf)->size) + return; + __b_drop(buf); +} + +/* Releases buffer *buf if allocated, and replaces it with &buf_empty. */ +static inline void b_free(struct buffer **buf) +{ + b_drop(buf); + *buf = &buf_empty; +} + #endif /* _COMMON_BUFFER_H */ /* diff --git a/include/proto/channel.h b/include/proto/channel.h index cf7b41383..1c175e904 100644 --- a/include/proto/channel.h +++ b/include/proto/channel.h @@ -51,6 +51,7 @@ int bo_getblk(struct channel *chn, char *blk, int len, int offset); /* Initialize all fields in the channel. */ static inline void channel_init(struct channel *chn) { + chn->buf = &buf_empty; chn->to_forward = 0; chn->last_read = now_ms; chn->xfer_small = chn->xfer_large = 0; diff --git a/src/buffer.c b/src/buffer.c index 9037dd3fe..769102639 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -22,6 +22,10 @@ struct pool_head *pool2_buffer; +/* this buffer is used to have a valid pointer to an empty buffer in channels + * which convey no more data. + */ +struct buffer buf_empty = { .p = buf_empty.data }; /* perform minimal intializations, report 0 in case of error, 1 if OK. */ int init_buffer()