[MINOR] re-arrange buffer flags and rename some of them
The buffer flags became a big bazaar. Re-arrange them
so that their names are more explicit and so that they
are more easily readable in hex form. Some aggregates
have also been adjusted.
diff --git a/include/proto/buffers.h b/include/proto/buffers.h
index 194f4ee..e5df177 100644
--- a/include/proto/buffers.h
+++ b/include/proto/buffers.h
@@ -120,6 +120,18 @@
buf->flags &= ~BF_HIJACK;
}
+/* allows the consumer to send the buffer contents */
+static inline void buffer_write_ena(struct buffer *buf)
+{
+ buf->flags |= BF_WRITE_ENA;
+}
+
+/* prevents the consumer from sending the buffer contents */
+static inline void buffer_write_dis(struct buffer *buf)
+{
+ buf->flags &= ~BF_WRITE_ENA;
+}
+
/* returns the maximum number of bytes writable at once in this buffer */
static inline int buffer_max(const struct buffer *buf)
{
diff --git a/include/types/buffers.h b/include/types/buffers.h
index d67c932..c35ef37 100644
--- a/include/types/buffers.h
+++ b/include/types/buffers.h
@@ -26,53 +26,73 @@
#include <common/memory.h>
/* The BF_* macros designate Buffer Flags, which may be ORed in the bit field
- * member 'flags' in struct buffer. Some of them are persistent (BF_SHUT*),
- * some of them (BF_EMPTY,BF_FULL) may only be set by the low-level read/write
- * functions as well as those who change the buffer's read limit.
+ * member 'flags' in struct buffer. Here we have several types of flags :
+ *
+ * - pure status flags, reported by the lower layer, which must be cleared
+ * before doing further I/O :
+ * BF_*_NULL, BF_*_PARTIAL
+ *
+ * - pure status flags, reported by mid-layer, which must also be cleared
+ * before doing further I/O :
+ * BF_*_TIMEOUT, BF_*_ERROR
+ *
+ * - read-only indicators reported by lower levels :
+ * BF_STREAMER, BF_STREAMER_FAST
+ *
+ * - write-once status flags reported by the mid-level : BF_SHUTR, BF_SHUTW
+ *
+ * - persistent control flags managed only by higher level :
+ * BF_SHUT*_NOW, BF_*_ENA, BF_HIJACK
+ *
+ * The flags have been arranged for readability, so that the read and write
+ * bits have se same position in a byte (read being the lower byte and write
+ * the second one).
*/
-#define BF_EMPTY 1 /* buffer is empty */
-#define BF_FULL 2 /* buffer cannot accept any more data (l >= rlim-data) */
-#define BF_SHUTR 4 /* producer has already shut down */
-#define BF_SHUTW 8 /* consumer has already shut down */
+#define BF_READ_NULL 0x000001 /* last read detected on producer side */
+#define BF_READ_PARTIAL 0x000002 /* some data were read from producer */
+#define BF_READ_TIMEOUT 0x000004 /* timeout while waiting for producer */
+#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_READ_STATUS (BF_READ_NULL|BF_READ_PARTIAL|BF_READ_ERROR|BF_READ_TIMEOUT)
+#define BF_CLEAR_READ (~BF_READ_STATUS)
-#define BF_PARTIAL_READ 16
-#define BF_COMPLETE_READ 32
-#define BF_READ_ERROR 64
-#define BF_READ_NULL 128
-#define BF_READ_STATUS (BF_PARTIAL_READ|BF_COMPLETE_READ|BF_READ_ERROR|BF_READ_NULL)
-#define BF_CLEAR_READ (~BF_READ_STATUS)
+#define BF_FULL 0x000010 /* buffer cannot accept any more data (l >= rlim-data) */
+#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_ENA 0x000080 /* producer is allowed to feed data into the buffer */
-#define BF_PARTIAL_WRITE 256
-#define BF_COMPLETE_WRITE 512
-#define BF_WRITE_ERROR 1024
-#define BF_WRITE_NULL 2048
-#define BF_WRITE_STATUS (BF_PARTIAL_WRITE|BF_COMPLETE_WRITE|BF_WRITE_ERROR|BF_WRITE_NULL)
-#define BF_CLEAR_WRITE (~BF_WRITE_STATUS)
+#define BF_WRITE_NULL 0x000100 /* write(0) or connect() succeeded on consumer side */
+#define BF_WRITE_PARTIAL 0x000200 /* some data were written to the consumer */
+#define BF_WRITE_TIMEOUT 0x000400 /* timeout while waiting for consumer */
+#define BF_WRITE_ERROR 0x000800 /* unrecoverable error on consumer side */
+#define BF_WRITE_ACTIVITY (BF_WRITE_NULL|BF_WRITE_PARTIAL|BF_WRITE_ERROR)
+#define BF_WRITE_STATUS (BF_WRITE_NULL|BF_WRITE_PARTIAL|BF_WRITE_ERROR|BF_WRITE_TIMEOUT)
+#define BF_CLEAR_WRITE (~BF_WRITE_STATUS)
-#define BF_STREAMER 4096
-#define BF_STREAMER_FAST 8192
+#define BF_EMPTY 0x001000 /* buffer is empty */
+#define BF_SHUTW 0x002000 /* consumer has already shut down */
+#define BF_SHUTW_NOW 0x004000 /* the consumer must shut down for writes immediately */
+#define BF_WRITE_ENA 0x008000 /* consumer is allowed to forward all buffer contents */
-#define BF_MAY_FORWARD 16384 /* consumer side is allowed to forward the data */
-#define BF_READ_TIMEOUT 32768 /* timeout while waiting for producer */
-#define BF_WRITE_TIMEOUT 65536 /* timeout while waiting for consumer */
+#define BF_STREAMER 0x010000 /* the producer is identified as streaming data */
+#define BF_STREAMER_FAST 0x020000 /* the consumer seems to eat the stream very fast */
/* When either BF_SHUTR_NOW or BF_HIJACK is set, it is strictly forbidden for
* the stream interface to alter the buffer contents. When BF_SHUTW_NOW is set,
* it is strictly forbidden for the stream interface to send anything from the
* buffer.
*/
-#define BF_SHUTR_NOW 131072 /* the producer must shut down for reads ASAP */
-#define BF_SHUTW_NOW 262144 /* the consumer must shut down for writes ASAP */
-#define BF_HIJACK 524288 /* the producer is temporarily replaced */
+#define BF_HIJACK 0x040000 /* the producer is temporarily replaced */
-/* masks which define input bits for stream interfaces and stream analysers */
-#define BF_MASK_INTERFACE_I (BF_FULL|BF_HIJACK|BF_READ_NULL|BF_SHUTR|BF_SHUTR_NOW|BF_SHUTW)
-#define BF_MASK_INTERFACE_O (BF_EMPTY|BF_HIJACK|BF_MAY_FORWARD|BF_SHUTR|BF_SHUTW|BF_SHUTW_NOW)
+/* Masks which define input bits for stream interfaces and stream analysers */
+#define BF_MASK_INTERFACE_I (BF_FULL|BF_HIJACK|BF_READ_ENA|BF_READ_STATUS|BF_SHUTR_NOW|BF_SHUTR|BF_SHUTW)
+#define BF_MASK_INTERFACE_O (BF_EMPTY|BF_HIJACK|BF_WRITE_ENA|BF_WRITE_STATUS|BF_SHUTW_NOW|BF_SHUTR|BF_SHUTW)
#define BF_MASK_INTERFACE (BF_MASK_INTF_I | BF_MASK_INTF_O)
-#define BF_MASK_ANALYSER (BF_FULL|BF_READ_NULL|BF_READ_ERROR|BF_READ_TIMEOUT|BF_SHUTR|BF_WRITE_ERROR)
-#define BF_MASK_INJECTER (BF_FULL|BF_WRITE_STATUS|BF_WRITE_TIMEOUT|BF_SHUTW)
+#define BF_MASK_ANALYSER (BF_FULL|BF_READ_STATUS|BF_SHUTR|BF_WRITE_ERROR)
+#define BF_MASK_HIJACKER (BF_FULL|BF_WRITE_STATUS|BF_WRITE_TIMEOUT|BF_SHUTW)
+
/* Analysers (buffer->analysers).
* Those bits indicate that there are some processing to do on the buffer
diff --git a/src/client.c b/src/client.c
index 5df5c0d..606cf79 100644
--- a/src/client.c
+++ b/src/client.c
@@ -347,7 +347,7 @@
s->req->analysers |= AN_REQ_HTTP_HDR;
if (!s->req->analysers)
- s->req->flags |= BF_MAY_FORWARD; /* don't wait to establish connection */
+ buffer_write_ena(s->req); /* don't wait to establish connection */
s->req->rto = s->fe->timeout.client;
s->req->wto = s->be->timeout.server;
diff --git a/src/proto_http.c b/src/proto_http.c
index 66f8e16..1432fe3 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -544,7 +544,7 @@
void srv_close_with_err(struct session *t, int err, int finst,
int status, const struct chunk *msg)
{
- t->rep->flags |= BF_MAY_FORWARD;
+ buffer_write_ena(t->rep);
buffer_shutw(t->req);
buffer_shutr(t->rep);
if (status > 0 && msg) {
@@ -719,13 +719,13 @@
((rqf_srv ^ s->req->flags) & BF_MASK_INTERFACE_O)) {
resync = 1;
- if (s->req->cons->state < SI_ST_EST && s->req->flags & BF_MAY_FORWARD)
+ if (s->req->cons->state < SI_ST_EST && s->req->flags & BF_WRITE_ENA)
process_srv_conn(s);
if (s->req->cons->state == SI_ST_EST) {
- if ((s->req->flags & (BF_SHUTW|BF_EMPTY|BF_MAY_FORWARD)) == (BF_EMPTY|BF_MAY_FORWARD) &&
+ if ((s->req->flags & (BF_SHUTW|BF_EMPTY|BF_WRITE_ENA)) == (BF_EMPTY|BF_WRITE_ENA) &&
s->be->options & PR_O_FORCE_CLO &&
- s->rep->flags & BF_READ_STATUS) {
+ s->rep->flags & BF_READ_ACTIVITY) {
/* We want to force the connection to the server to close,
* and the server has begun to respond. That's the right
* time.
@@ -765,7 +765,7 @@
/* the analysers must block it themselves */
if (s->req->prod->state >= SI_ST_EST) {
resync = 1;
- s->req->flags |= BF_MAY_FORWARD;
+ buffer_write_ena(s->req);
if (s->req->analysers)
process_request(s);
}
@@ -776,7 +776,7 @@
/* In inject mode, we wake up everytime something has
* happened on the write side of the buffer.
*/
- if ((s->rep->flags & (BF_PARTIAL_WRITE|BF_WRITE_ERROR|BF_SHUTW)) &&
+ if ((s->rep->flags & (BF_WRITE_PARTIAL|BF_WRITE_ERROR|BF_SHUTW)) &&
!(s->rep->flags & BF_FULL)) {
if (produce_content(s) != 0)
resync = 1; /* completed, better re-check flags */
@@ -786,7 +786,7 @@
if ((rpf_rep ^ s->rep->flags) & BF_MASK_ANALYSER) {
/* the analysers must block it themselves */
resync = 1;
- s->rep->flags |= BF_MAY_FORWARD;
+ buffer_write_ena(s->rep);
if (s->rep->analysers)
process_response(s);
rpf_rep = s->rep->flags;
@@ -818,7 +818,7 @@
* request timeout is set and the server has not yet sent a response.
*/
- if ((s->rep->flags & (BF_MAY_FORWARD|BF_SHUTR)) == 0 &&
+ if ((s->rep->flags & (BF_WRITE_ENA|BF_SHUTR)) == 0 &&
(tick_isset(s->req->wex) || tick_isset(s->rep->rex)))
s->req->rex = TICK_ETERNITY;
@@ -1692,11 +1692,11 @@
* - all enabled analysers are called in turn from the lower to the higher
* bit.
* - if an analyser does not have enough data, it must return without calling
- * other ones. It should also probably reset the BF_MAY_FORWARD bit to ensure
+ * other ones. It should also probably reset the BF_WRITE_ENA bit to ensure
* that unprocessed data will not be forwarded. But that probably depends on
* the protocol. Generally it is not reset in case of errors.
* - if an analyser has enough data, it just has to pass on to the next
- * analyser without touching BF_MAY_FORWARD (it is enabled prior to
+ * analyser without touching BF_WRITE_ENA (it is enabled prior to
* analysis).
* - if an analyser thinks it has no added value anymore staying here, it must
* reset its bit from the analysers flags in order not to be called anymore.
@@ -1773,7 +1773,7 @@
if (rule->cond) {
ret = acl_exec_cond(rule->cond, t->fe, t, NULL, ACL_DIR_REQ | partial);
if (ret == ACL_PAT_MISS) {
- req->flags &= ~BF_MAY_FORWARD;
+ buffer_write_dis(req);
/* 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, t->fe->tcp_req.inspect_delay);
@@ -1931,7 +1931,7 @@
return 0;
}
- req->flags &= ~BF_MAY_FORWARD;
+ buffer_write_dis(req);
/* 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, t->fe->timeout.httpreq);
@@ -2519,7 +2519,7 @@
ctx.idx = 0;
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) {
- req->flags &= ~BF_MAY_FORWARD;
+ buffer_write_dis(req);
req->analysers |= AN_REQ_HTTP_BODY;
}
else {
@@ -2542,7 +2542,7 @@
hint = t->be->url_param_post_limit;
/* now do we really need to buffer more data? */
if (len < hint) {
- req->flags &= ~BF_MAY_FORWARD;
+ buffer_write_dis(req);
req->analysers |= AN_REQ_HTTP_BODY;
}
/* else... There are no body bytes to wait for */
@@ -2569,7 +2569,7 @@
/* flush the request so that we can drop the connection early
* if the client closes first.
*/
- req->flags &= ~BF_MAY_FORWARD;
+ buffer_write_dis(req);
req->analysers |= AN_REQ_HTTP_TARPIT;
req->analyse_exp = tick_add_ifset(now_ms, t->be->timeout.tarpit);
if (!req->analyse_exp)
@@ -2700,7 +2700,7 @@
* request timeout once at the beginning of the
* request.
*/
- req->flags &= ~BF_MAY_FORWARD;
+ buffer_write_dis(req);
if (!tick_isset(req->analyse_exp))
req->analyse_exp = tick_add_ifset(now_ms, t->fe->timeout.httpreq);
return 0;
@@ -2907,7 +2907,7 @@
return 0;
}
- rep->flags &= ~BF_MAY_FORWARD;
+ buffer_write_dis(rep);
return 0;
}
@@ -3464,7 +3464,7 @@
if ((req->flags & BF_SHUTW_NOW) ||
(rep->flags & BF_SHUTW) ||
((req->flags & BF_SHUTR) && /* FIXME: this should not prevent a connection from establishing */
- ((req->flags & BF_EMPTY && !(req->flags & BF_WRITE_STATUS)) ||
+ ((req->flags & BF_EMPTY && !(req->flags & BF_WRITE_ACTIVITY)) ||
t->be->options & PR_O_ABRT_CLOSE))) { /* give up */
trace_term(t, TT_HTTP_SRV_5);
@@ -3495,7 +3495,7 @@
if (!req->cons->err_type)
req->cons->err_type = SI_ET_CONN_ERR;
}
- else if (!(req->flags & BF_WRITE_STATUS)) {
+ else if (!(req->flags & BF_WRITE_ACTIVITY)) {
/* nothing happened, maybe we timed out */
if (tick_is_expired(req->wex, now_ms)) {
conn_err = SI_ET_CONN_TO;
@@ -3616,7 +3616,7 @@
}
if (!rep->analysers)
- t->rep->flags |= BF_MAY_FORWARD;
+ buffer_write_ena(t->rep);
req->wex = TICK_ETERNITY;
return 0;
}
@@ -3809,7 +3809,7 @@
/*
* Tries to establish a connection to the server and associate it to the
* request buffer's consumer side. It is assumed that this function will not be
- * be called with SI_ST_EST nor with BF_MAY_FORWARD cleared. It normally
+ * be called with SI_ST_EST nor with BF_WRITE_ENA cleared. It normally
* returns zero, but may return 1 if it absolutely wants to be called again.
*/
int process_srv_conn(struct session *t)
diff --git a/src/proto_uxst.c b/src/proto_uxst.c
index 050c38a..2185f9f 100644
--- a/src/proto_uxst.c
+++ b/src/proto_uxst.c
@@ -867,7 +867,7 @@
else if (s == SV_STCONN) { /* connection in progress */
if (c == CL_STCLOSE || c == CL_STSHUTW ||
(c == CL_STSHUTR &&
- ((t->req->flags & BF_EMPTY && !(req->flags & BF_WRITE_STATUS)) ||
+ ((t->req->flags & BF_EMPTY && !(req->flags & BF_WRITE_ACTIVITY)) ||
t->be->options & PR_O_ABRT_CLOSE))) { /* give up */
tv_eternity(&req->cex);
fd_delete(t->srv_fd);
@@ -877,11 +877,11 @@
srv_close_with_err(t, SN_ERR_CLICL, SN_FINST_C);
return 1;
}
- if (!(req->flags & BF_WRITE_STATUS) && !tv_isle(&req->cex, &now)) {
+ if (!(req->flags & BF_WRITE_ACTIVITY) && !tv_isle(&req->cex, &now)) {
//fprintf(stderr,"1: c=%d, s=%d, now=%d.%06d, exp=%d.%06d\n", c, s, now.tv_sec, now.tv_usec, req->cex.tv_sec, req->cex.tv_usec);
return 0; /* nothing changed */
}
- else if (!(req->flags & BF_WRITE_STATUS) || (req->flags & BF_WRITE_ERROR)) {
+ else if (!(req->flags & BF_WRITE_ACTIVITY) || (req->flags & BF_WRITE_ERROR)) {
/* timeout, asynchronous connect error or first write error */
//fprintf(stderr,"2: c=%d, s=%d\n", c, s);
@@ -889,7 +889,7 @@
if (t->srv)
t->srv->cur_sess--;
- if (!(req->flags & BF_WRITE_STATUS))
+ if (!(req->flags & BF_WRITE_ACTIVITY))
conn_err = SN_ERR_SRVTO; // it was a connect timeout.
else
conn_err = SN_ERR_SRVCL; // it was an asynchronous connect error.
diff --git a/src/senddata.c b/src/senddata.c
index dea2c96..5d4b8a6 100644
--- a/src/senddata.c
+++ b/src/senddata.c
@@ -60,7 +60,7 @@
buffer_write(s->rep, msg->str, msg->len);
s->rep->wex = tick_add_ifset(now_ms, s->rep->wto);
- s->rep->flags |= BF_MAY_FORWARD;
+ buffer_write_ena(s->rep);
}
diff --git a/src/stream_sock.c b/src/stream_sock.c
index 0b93531..4ddb121 100644
--- a/src/stream_sock.c
+++ b/src/stream_sock.c
@@ -112,7 +112,7 @@
b->r += ret;
b->l += ret;
cur_read += ret;
- b->flags |= BF_PARTIAL_READ;
+ b->flags |= BF_READ_PARTIAL;
b->flags &= ~BF_EMPTY;
if (b->r == b->data + BUFSIZE) {
@@ -233,10 +233,10 @@
* have at least read something.
*/
- if (tick_isset(b->rex) && b->flags & BF_PARTIAL_READ)
+ if (tick_isset(b->rex) && b->flags & BF_READ_PARTIAL)
b->rex = tick_add_ifset(now_ms, b->rto);
- if (!(b->flags & BF_READ_STATUS))
+ if (!(b->flags & BF_READ_ACTIVITY))
goto out_skip_wakeup;
out_wakeup:
task_wakeup(fdtab[fd].owner);
@@ -352,7 +352,7 @@
b->l -= ret;
b->w += ret;
- b->flags |= BF_PARTIAL_WRITE;
+ b->flags |= BF_WRITE_PARTIAL;
if (b->l < b->rlim - b->data)
b->flags &= ~BF_FULL;
@@ -395,7 +395,7 @@
* written something.
*/
- if (tick_isset(b->wex) && b->flags & BF_PARTIAL_WRITE) {
+ if (tick_isset(b->wex) && b->flags & BF_WRITE_PARTIAL) {
b->wex = tick_add_ifset(now_ms, b->wto);
if (tick_isset(b->wex)) {
/* FIXME: to prevent the client from expiring read timeouts during writes,
@@ -408,7 +408,7 @@
}
out_may_wakeup:
- if (!(b->flags & BF_WRITE_STATUS))
+ if (!(b->flags & BF_WRITE_ACTIVITY))
goto out_skip_wakeup;
out_wakeup:
task_wakeup(fdtab[fd].owner);
@@ -533,7 +533,7 @@
if (!(ob->flags & BF_SHUTW)) {
/* Forced write-shutdown or other end closed with empty buffer. */
if ((ob->flags & BF_SHUTW_NOW) ||
- (ob->flags & (BF_EMPTY|BF_HIJACK|BF_MAY_FORWARD|BF_SHUTR)) == (BF_EMPTY|BF_MAY_FORWARD|BF_SHUTR)) {
+ (ob->flags & (BF_EMPTY|BF_HIJACK|BF_WRITE_ENA|BF_SHUTR)) == (BF_EMPTY|BF_WRITE_ENA|BF_SHUTR)) {
//trace_term(t, TT_HTTP_SRV_11);
buffer_shutw(ob);
if (ib->flags & BF_SHUTR) {
@@ -582,7 +582,7 @@
* update it if is was not yet set, or if we already got some read status.
*/
EV_FD_COND_S(fd, DIR_RD);
- if (!tick_isset(ib->rex) || ib->flags & BF_READ_STATUS)
+ if (!tick_isset(ib->rex) || ib->flags & BF_READ_ACTIVITY)
ib->rex = tick_add_ifset(now_ms, ib->rto);
}
}
@@ -591,7 +591,7 @@
if (!(ob->flags & BF_SHUTW)) {
/* Write not closed, update FD status and timeout for writes */
if ((ob->flags & BF_EMPTY) ||
- (ob->flags & (BF_HIJACK|BF_MAY_FORWARD)) == 0) {
+ (ob->flags & (BF_HIJACK|BF_WRITE_ENA)) == 0) {
/* stop writing */
EV_FD_COND_C(fd, DIR_WR);
ob->wex = TICK_ETERNITY;
@@ -602,7 +602,7 @@
* update it if is was not yet set, or if we already got some write status.
*/
EV_FD_COND_S(fd, DIR_WR);
- if (!tick_isset(ob->wex) || ob->flags & BF_WRITE_STATUS) {
+ if (!tick_isset(ob->wex) || ob->flags & BF_WRITE_ACTIVITY) {
ob->wex = tick_add_ifset(now_ms, ob->wto);
if (tick_isset(ob->wex) && !(ib->flags & BF_SHUTR) && tick_isset(ib->rex)) {
/* Note: depending on the protocol, we don't know if we're waiting