blob: 36a82d8de4bdbd5b97ba9393c95ad9bb1b83cf23 [file] [log] [blame]
Willy Tarreaubaaee002006-06-26 02:48:02 +02001/*
2 include/proto/buffers.h
3 Buffer management definitions, macros and inline functions.
4
Willy Tarreauba392ce2008-08-16 21:13:23 +02005 Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu
Willy Tarreaubaaee002006-06-26 02:48:02 +02006
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation, version 2.1
10 exclusively.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20*/
21
22#ifndef _PROTO_BUFFERS_H
23#define _PROTO_BUFFERS_H
24
Willy Tarreau7341d942007-05-13 19:56:02 +020025#include <stdio.h>
Willy Tarreau0f772532006-12-23 20:51:41 +010026#include <stdlib.h>
Willy Tarreau7341d942007-05-13 19:56:02 +020027#include <string.h>
Willy Tarreau0f772532006-12-23 20:51:41 +010028
Willy Tarreaue3ba5f02006-06-29 18:54:54 +020029#include <common/config.h>
Willy Tarreau7341d942007-05-13 19:56:02 +020030#include <common/memory.h>
Willy Tarreau0c303ee2008-07-07 00:09:58 +020031#include <common/ticks.h>
Willy Tarreaufa645582007-06-03 15:59:52 +020032#include <common/time.h>
33
Willy Tarreaubaaee002006-06-26 02:48:02 +020034#include <types/buffers.h>
35
Willy Tarreau7341d942007-05-13 19:56:02 +020036extern struct pool_head *pool2_buffer;
37
38/* perform minimal intializations, report 0 in case of error, 1 if OK. */
39int init_buffer();
40
Willy Tarreau54469402006-07-29 16:59:06 +020041/* Initializes all fields in the buffer. The ->rlim field is initialized last
42 * so that the compiler can optimize it away if changed immediately after the
Willy Tarreaue393fe22008-08-16 22:18:07 +020043 * call to this function. By default, it is set to the full size of the buffer.
44 * The BF_EMPTY flags is set.
Willy Tarreau54469402006-07-29 16:59:06 +020045 */
46static inline void buffer_init(struct buffer *buf)
47{
Willy Tarreaue393fe22008-08-16 22:18:07 +020048 buf->l = buf->total = 0;
Willy Tarreau2df28e82008-08-17 15:20:19 +020049 buf->analysers = 0;
Willy Tarreaufa7e1022008-10-19 07:30:41 +020050 buf->cons = NULL;
Willy Tarreaue393fe22008-08-16 22:18:07 +020051 buf->flags = BF_EMPTY;
Willy Tarreau2df28e82008-08-17 15:20:19 +020052 buf->r = buf->lr = buf->w = buf->data;
Willy Tarreaue393fe22008-08-16 22:18:07 +020053 buf->rlim = buf->data + BUFSIZE;
Willy Tarreau54469402006-07-29 16:59:06 +020054}
55
Willy Tarreaubaaee002006-06-26 02:48:02 +020056/* returns 1 if the buffer is empty, 0 otherwise */
Willy Tarreaub17916e2006-10-15 15:17:57 +020057static inline int buffer_isempty(const struct buffer *buf)
Willy Tarreaubaaee002006-06-26 02:48:02 +020058{
59 return buf->l == 0;
60}
61
62/* returns 1 if the buffer is full, 0 otherwise */
Willy Tarreaub17916e2006-10-15 15:17:57 +020063static inline int buffer_isfull(const struct buffer *buf) {
Willy Tarreaubaaee002006-06-26 02:48:02 +020064 return buf->l == BUFSIZE;
65}
66
Willy Tarreau2eb52f02008-09-04 09:14:08 +020067/* Check buffer timeouts, and set the corresponding flags. The
68 * likely/unlikely have been optimized for fastest normal path.
69 */
70static inline void buffer_check_timeouts(struct buffer *b)
71{
72 if (likely(!(b->flags & (BF_SHUTR|BF_READ_TIMEOUT))) &&
73 unlikely(tick_is_expired(b->rex, now_ms)))
74 b->flags |= BF_READ_TIMEOUT;
75
76 if (likely(!(b->flags & (BF_SHUTW|BF_WRITE_TIMEOUT))) &&
77 unlikely(tick_is_expired(b->wex, now_ms)))
78 b->flags |= BF_WRITE_TIMEOUT;
79
80 if (likely(!(b->flags & BF_ANA_TIMEOUT)) &&
81 unlikely(tick_is_expired(b->analyse_exp, now_ms)))
82 b->flags |= BF_ANA_TIMEOUT;
83}
84
Willy Tarreaue393fe22008-08-16 22:18:07 +020085/* flushes any content from buffer <buf> and adjusts flags
86 * accordingly.
87 */
Willy Tarreaubaaee002006-06-26 02:48:02 +020088static inline void buffer_flush(struct buffer *buf)
89{
Willy Tarreaue09e0ce2007-03-18 16:31:29 +010090 buf->r = buf->lr = buf->w = buf->data;
Willy Tarreaubaaee002006-06-26 02:48:02 +020091 buf->l = 0;
Willy Tarreaue393fe22008-08-16 22:18:07 +020092 buf->flags |= BF_EMPTY | BF_FULL;
93 if (buf->rlim)
94 buf->flags &= ~BF_FULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +020095}
96
Willy Tarreauba392ce2008-08-16 21:13:23 +020097/* marks the buffer as "shutdown" for reads and cancels the timeout */
Willy Tarreaufa645582007-06-03 15:59:52 +020098static inline void buffer_shutr(struct buffer *buf)
99{
Willy Tarreau0c303ee2008-07-07 00:09:58 +0200100 buf->rex = TICK_ETERNITY;
Willy Tarreauba392ce2008-08-16 21:13:23 +0200101 buf->flags |= BF_SHUTR;
Willy Tarreaufa645582007-06-03 15:59:52 +0200102}
103
Willy Tarreauba392ce2008-08-16 21:13:23 +0200104/* marks the buffer as "shutdown" for writes and cancels the timeout */
Willy Tarreaufa645582007-06-03 15:59:52 +0200105static inline void buffer_shutw(struct buffer *buf)
106{
Willy Tarreau0c303ee2008-07-07 00:09:58 +0200107 buf->wex = TICK_ETERNITY;
Willy Tarreauba392ce2008-08-16 21:13:23 +0200108 buf->flags |= BF_SHUTW;
Willy Tarreaufa645582007-06-03 15:59:52 +0200109}
110
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200111/* marks the buffer as "shutdown" ASAP for reads */
112static inline void buffer_shutr_now(struct buffer *buf)
113{
Willy Tarreauefb453c2008-10-26 20:49:47 +0100114 buf->flags |= BF_SHUTR_NOW | BF_SHUTR;
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200115}
116
117/* marks the buffer as "shutdown" ASAP for writes */
118static inline void buffer_shutw_now(struct buffer *buf)
119{
120 buf->flags |= BF_SHUTW_NOW;
121}
122
123/* marks the buffer as "shutdown" ASAP in both directions */
124static inline void buffer_abort(struct buffer *buf)
125{
Willy Tarreauefb453c2008-10-26 20:49:47 +0100126 buf->flags |= BF_SHUTR_NOW | BF_SHUTR | BF_SHUTW_NOW;
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200127}
128
Willy Tarreau72b179a2008-08-28 16:01:32 +0200129/* set the buffer to hijacking mode */
130static inline void buffer_start_hijack(struct buffer *buf)
131{
132 buf->flags |= BF_HIJACK;
133}
134
135/* releases the buffer from hijacking mode */
136static inline void buffer_stop_hijack(struct buffer *buf)
137{
138 buf->flags &= ~BF_HIJACK;
139}
140
Willy Tarreau3da77c52008-08-29 09:58:42 +0200141/* allows the consumer to send the buffer contents */
142static inline void buffer_write_ena(struct buffer *buf)
143{
144 buf->flags |= BF_WRITE_ENA;
145}
146
147/* prevents the consumer from sending the buffer contents */
148static inline void buffer_write_dis(struct buffer *buf)
149{
150 buf->flags &= ~BF_WRITE_ENA;
151}
152
Willy Tarreaubaaee002006-06-26 02:48:02 +0200153/* returns the maximum number of bytes writable at once in this buffer */
Willy Tarreaub17916e2006-10-15 15:17:57 +0200154static inline int buffer_max(const struct buffer *buf)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200155{
156 if (buf->l == BUFSIZE)
157 return 0;
158 else if (buf->r >= buf->w)
159 return buf->data + BUFSIZE - buf->r;
160 else
161 return buf->w - buf->r;
162}
163
Willy Tarreaue393fe22008-08-16 22:18:07 +0200164/* sets the buffer read limit to <size> bytes, and adjusts the FULL
165 * flag accordingly.
166 */
167static inline void buffer_set_rlim(struct buffer *buf, int size)
168{
169 buf->rlim = buf->data + size;
170 if (buf->l < size)
171 buf->flags &= ~BF_FULL;
172 else
173 buf->flags |= BF_FULL;
174}
Willy Tarreaubaaee002006-06-26 02:48:02 +0200175
176/*
177 * Tries to realign the given buffer, and returns how many bytes can be written
178 * there at once without overwriting anything.
179 */
180static inline int buffer_realign(struct buffer *buf)
181{
182 if (buf->l == 0) {
183 /* let's realign the buffer to optimize I/O */
Willy Tarreaue09e0ce2007-03-18 16:31:29 +0100184 buf->r = buf->w = buf->lr = buf->data;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200185 }
186 return buffer_max(buf);
187}
188
189
190int buffer_write(struct buffer *buf, const char *msg, int len);
Willy Tarreauc0dde7a2007-01-01 21:38:07 +0100191int buffer_write_chunk(struct buffer *buf, struct chunk *chunk);
Willy Tarreau4af6f3a2007-03-18 22:36:26 +0100192int buffer_replace(struct buffer *b, char *pos, char *end, const char *str);
193int buffer_replace2(struct buffer *b, char *pos, char *end, const char *str, int len);
194int buffer_insert_line2(struct buffer *b, char *pos, const char *str, int len);
Willy Tarreauc0dde7a2007-01-01 21:38:07 +0100195int chunk_printf(struct chunk *chk, int size, const char *fmt, ...);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +0100196void buffer_dump(FILE *o, struct buffer *b, int from, int to);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200197
Willy Tarreau0f772532006-12-23 20:51:41 +0100198/*
199 * frees the destination chunk if already allocated, allocates a new string,
200 * and copies the source into it. The pointer to the destination string is
201 * returned, or NULL if the allocation fails or if any pointer is NULL..
202 */
203static inline char *chunk_dup(struct chunk *dst, const struct chunk *src) {
204 if (!dst || !src || !src->str)
205 return NULL;
206 if (dst->str)
207 free(dst->str);
208 dst->len = src->len;
209 dst->str = (char *)malloc(dst->len);
210 memcpy(dst->str, src->str, dst->len);
211 return dst->str;
212}
Willy Tarreaubaaee002006-06-26 02:48:02 +0200213
214#endif /* _PROTO_BUFFERS_H */
215
216/*
217 * Local variables:
218 * c-indent-level: 8
219 * c-basic-offset: 8
220 * End:
221 */