MAJOR: buffer rework: replace ->send_max with ->o

This is the first minor step of the buffer rework. It's only renaming,
it should have no impact.
This commit is contained in:
Willy Tarreau 2012-03-01 16:08:30 +01:00
parent 1122d9c03c
commit 2e046c6017
7 changed files with 107 additions and 107 deletions

View File

@ -54,7 +54,7 @@ unsigned long long buffer_forward(struct buffer *buf, unsigned long long bytes);
/* Initialize all fields in the buffer. The BF_OUT_EMPTY flags is set. */ /* Initialize all fields in the buffer. The BF_OUT_EMPTY flags is set. */
static inline void buffer_init(struct buffer *buf) static inline void buffer_init(struct buffer *buf)
{ {
buf->send_max = 0; buf->o = 0;
buf->to_forward = 0; buf->to_forward = 0;
buf->l = buf->total = 0; buf->l = buf->total = 0;
buf->pipe = NULL; buf->pipe = NULL;
@ -75,7 +75,7 @@ static inline void buffer_init(struct buffer *buf)
*/ */
static inline int buffer_reserved(const struct buffer *buf) static inline int buffer_reserved(const struct buffer *buf)
{ {
int ret = global.tune.maxrewrite - buf->to_forward - buf->send_max; int ret = global.tune.maxrewrite - buf->to_forward - buf->o;
if (buf->to_forward == BUF_INFINITE_FORWARD) if (buf->to_forward == BUF_INFINITE_FORWARD)
return 0; return 0;
@ -213,13 +213,13 @@ static inline int buffer_count(const struct buffer *buf, const char *from, const
*/ */
static inline int buffer_pending(const struct buffer *buf) static inline int buffer_pending(const struct buffer *buf)
{ {
return buf->l - buf->send_max; return buf->l - buf->o;
} }
/* Returns the size of the working area which the caller knows ends at <end>. /* Returns the size of the working area which the caller knows ends at <end>.
* If <end> equals buf->r (modulo size), then it means that the free area which * If <end> equals buf->r (modulo size), then it means that the free area which
* follows is part of the working area. Otherwise, the working area stops at * follows is part of the working area. Otherwise, the working area stops at
* <end>. It always starts at buf->w+send_max. The work area includes the * <end>. It always starts at buf->w+o. The work area includes the
* reserved area. * reserved area.
*/ */
static inline int buffer_work_area(const struct buffer *buf, const char *end) static inline int buffer_work_area(const struct buffer *buf, const char *end)
@ -227,7 +227,7 @@ static inline int buffer_work_area(const struct buffer *buf, const char *end)
end = buffer_pointer(buf, end); end = buffer_pointer(buf, end);
if (end == buf->r) /* pointer exactly at end, lets push forwards */ if (end == buf->r) /* pointer exactly at end, lets push forwards */
end = buf->w; end = buf->w;
return buffer_count(buf, buffer_pointer(buf, buf->w + buf->send_max), end); return buffer_count(buf, buffer_pointer(buf, buf->w + buf->o), end);
} }
/* Return 1 if the buffer has less than 1/4 of its capacity free, otherwise 0 */ /* Return 1 if the buffer has less than 1/4 of its capacity free, otherwise 0 */
@ -242,13 +242,13 @@ static inline int buffer_almost_full(const struct buffer *buf)
* Return the max amount of bytes that can be read from the buffer at once. * Return the max amount of bytes that can be read from the buffer at once.
* Note that this may be lower than the actual buffer length when the data * Note that this may be lower than the actual buffer length when the data
* wrap after the end, so it's preferable to call this function again after * wrap after the end, so it's preferable to call this function again after
* reading. Also note that this function respects the send_max limit. * reading. Also note that this function respects the ->o limit.
*/ */
static inline int buffer_contig_data(struct buffer *buf) static inline int buffer_contig_data(struct buffer *buf)
{ {
int ret; int ret;
if (!buf->send_max || !buf->l) if (!buf->o || !buf->l)
return 0; return 0;
if (buf->r > buf->w) if (buf->r > buf->w)
@ -257,8 +257,8 @@ static inline int buffer_contig_data(struct buffer *buf)
ret = buf->data + buf->size - buf->w; ret = buf->data + buf->size - buf->w;
/* limit the amount of outgoing data if required */ /* limit the amount of outgoing data if required */
if (ret > buf->send_max) if (ret > buf->o)
ret = buf->send_max; ret = buf->o;
return ret; return ret;
} }
@ -296,15 +296,15 @@ static inline void buffer_check_timeouts(struct buffer *b)
b->flags |= BF_ANA_TIMEOUT; b->flags |= BF_ANA_TIMEOUT;
} }
/* Schedule all remaining buffer data to be sent. send_max is not touched if it /* Schedule all remaining buffer data to be sent. ->o is not touched if it
* already covers those data. That permits doing a flush even after a forward, * already covers those data. That permits doing a flush even after a forward,
* although not recommended. * although not recommended.
*/ */
static inline void buffer_flush(struct buffer *buf) static inline void buffer_flush(struct buffer *buf)
{ {
if (buf->send_max < buf->l) if (buf->o < buf->l)
buf->send_max = buf->l; buf->o = buf->l;
if (buf->send_max) if (buf->o)
buf->flags &= ~BF_OUT_EMPTY; buf->flags &= ~BF_OUT_EMPTY;
} }
@ -314,7 +314,7 @@ static inline void buffer_flush(struct buffer *buf)
*/ */
static inline void buffer_erase(struct buffer *buf) static inline void buffer_erase(struct buffer *buf)
{ {
buf->send_max = 0; buf->o = 0;
buf->to_forward = 0; buf->to_forward = 0;
buf->r = buf->lr = buf->w = buf->data; buf->r = buf->lr = buf->w = buf->data;
buf->l = 0; buf->l = 0;
@ -330,14 +330,14 @@ static inline void buffer_erase(struct buffer *buf)
*/ */
static inline void buffer_cut_tail(struct buffer *buf) static inline void buffer_cut_tail(struct buffer *buf)
{ {
if (!buf->send_max) if (!buf->o)
return buffer_erase(buf); return buffer_erase(buf);
buf->to_forward = 0; buf->to_forward = 0;
if (buf->l == buf->send_max) if (buf->l == buf->o)
return; return;
buf->l = buf->send_max; buf->l = buf->o;
buf->r = buf->w + buf->l; buf->r = buf->w + buf->l;
if (buf->r >= buf->data + buf->size) if (buf->r >= buf->data + buf->size)
buf->r -= buf->size; buf->r -= buf->size;
@ -456,7 +456,7 @@ static inline int buffer_realign(struct buffer *buf)
* Advance the buffer's read pointer by <len> bytes. This is useful when data * Advance the buffer's read pointer by <len> bytes. This is useful when data
* have been read directly from the buffer. It is illegal to call this function * have been read directly from the buffer. It is illegal to call this function
* with <len> causing a wrapping at the end of the buffer. It's the caller's * with <len> causing a wrapping at the end of the buffer. It's the caller's
* responsibility to ensure that <len> is never larger than buf->send_max. * responsibility to ensure that <len> is never larger than buf->o.
*/ */
static inline void buffer_skip(struct buffer *buf, int len) static inline void buffer_skip(struct buffer *buf, int len)
{ {
@ -471,8 +471,8 @@ static inline void buffer_skip(struct buffer *buf, int len)
if (buf->l < buffer_max_len(buf)) if (buf->l < buffer_max_len(buf))
buf->flags &= ~BF_FULL; buf->flags &= ~BF_FULL;
buf->send_max -= len; buf->o -= len;
if (!buf->send_max && !buf->pipe) if (!buf->o && !buf->pipe)
buf->flags |= BF_OUT_EMPTY; buf->flags |= BF_OUT_EMPTY;
/* notify that some data was written to the SI from the buffer */ /* notify that some data was written to the SI from the buffer */
@ -496,7 +496,7 @@ static inline int buffer_write_chunk(struct buffer *buf, struct chunk *chunk)
} }
/* Tries to copy chunk <chunk> into buffer <buf> after length controls. /* Tries to copy chunk <chunk> into buffer <buf> after length controls.
* The send_max and to_forward pointers are updated. If the buffer's input is * The ->o and to_forward pointers are updated. If the buffer's input is
* closed, -2 is returned. If the block is too large for this buffer, -3 is * closed, -2 is returned. If the block is too large for this buffer, -3 is
* returned. If there is not enough room left in the buffer, -1 is returned. * returned. If there is not enough room left in the buffer, -1 is returned.
* Otherwise the number of bytes copied is returned (0 being a valid number). * Otherwise the number of bytes copied is returned (0 being a valid number).
@ -514,7 +514,7 @@ static inline int buffer_put_chunk(struct buffer *buf, struct chunk *chunk)
} }
/* Tries to copy string <str> at once into buffer <buf> after length controls. /* Tries to copy string <str> at once into buffer <buf> after length controls.
* The send_max and to_forward pointers are updated. If the buffer's input is * The ->o and to_forward pointers are updated. If the buffer's input is
* closed, -2 is returned. If the block is too large for this buffer, -3 is * closed, -2 is returned. If the block is too large for this buffer, -3 is
* returned. If there is not enough room left in the buffer, -1 is returned. * returned. If there is not enough room left in the buffer, -1 is returned.
* Otherwise the number of bytes copied is returned (0 being a valid number). * Otherwise the number of bytes copied is returned (0 being a valid number).
@ -530,7 +530,7 @@ static inline int buffer_put_string(struct buffer *buf, const char *str)
* Return one char from the buffer. If the buffer is empty and closed, return -2. * Return one char from the buffer. If the buffer is empty and closed, return -2.
* If the buffer is just empty, return -1. The buffer's pointer is not advanced, * If the buffer is just empty, return -1. The buffer's pointer is not advanced,
* it's up to the caller to call buffer_skip(buf, 1) when it has consumed the char. * it's up to the caller to call buffer_skip(buf, 1) when it has consumed the char.
* Also note that this function respects the send_max limit. * Also note that this function respects the ->o limit.
*/ */
static inline int buffer_get_char(struct buffer *buf) static inline int buffer_get_char(struct buffer *buf)
{ {
@ -579,7 +579,7 @@ static inline int buffer_feed(struct buffer *buf, const char *str)
* buffer <b>, and moves <end> just after the end of <str>. <b>'s parameters * buffer <b>, and moves <end> just after the end of <str>. <b>'s parameters
* (l, r, lr) are updated to be valid after the shift. the shift value * (l, r, lr) are updated to be valid after the shift. the shift value
* (positive or negative) is returned. If there's no space left, the move is * (positive or negative) is returned. If there's no space left, the move is
* not done. The function does not adjust ->send_max nor BF_OUT_EMPTY because * not done. The function does not adjust ->o nor BF_OUT_EMPTY because
* it does not make sense to use it on data scheduled to be sent. * it does not make sense to use it on data scheduled to be sent.
*/ */
static inline int buffer_replace(struct buffer *b, char *pos, char *end, const char *str) static inline int buffer_replace(struct buffer *b, char *pos, char *end, const char *str)

View File

@ -68,7 +68,7 @@
#define BF_WRITE_ERROR 0x000800 /* unrecoverable error on consumer side */ #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_ACTIVITY (BF_WRITE_NULL|BF_WRITE_PARTIAL|BF_WRITE_ERROR)
#define BF_OUT_EMPTY 0x001000 /* send_max and pipe are empty. Set by last change. */ #define BF_OUT_EMPTY 0x001000 /* out and pipe are empty. Set by last change. */
#define BF_SHUTW 0x002000 /* consumer has already shut down */ #define BF_SHUTW 0x002000 /* consumer has already shut down */
#define BF_SHUTW_NOW 0x004000 /* the consumer must shut down for writes ASAP */ #define BF_SHUTW_NOW 0x004000 /* the consumer must shut down for writes ASAP */
#define BF_AUTO_CLOSE 0x008000 /* producer can forward shutdown to other side */ #define BF_AUTO_CLOSE 0x008000 /* producer can forward shutdown to other side */
@ -183,8 +183,8 @@ struct buffer {
unsigned int l; /* data length */ unsigned int l; /* data length */
char *r, *w, *lr; /* read ptr, write ptr, last read */ char *r, *w, *lr; /* read ptr, write ptr, last read */
unsigned int size; /* buffer size in bytes */ unsigned int size; /* buffer size in bytes */
unsigned int send_max; /* number of bytes the sender can consume om this buffer, <= l */ unsigned int o; /* number of out bytes the sender can consume from this buffer */
unsigned int to_forward; /* number of bytes to forward after send_max without a wake-up */ unsigned int to_forward; /* number of bytes to forward after out without a wake-up */
unsigned int analysers; /* bit field indicating what to do on the buffer */ unsigned int analysers; /* bit field indicating what to do on the buffer */
int analyse_exp; /* expiration date for current analysers (if set) */ int analyse_exp; /* expiration date for current analysers (if set) */
void (*hijacker)(struct session *, struct buffer *); /* alternative content producer */ void (*hijacker)(struct session *, struct buffer *); /* alternative content producer */
@ -201,7 +201,7 @@ struct buffer {
/* Note about the buffer structure /* Note about the buffer structure
The buffer contains two length indicators, one to_forward counter and one The buffer contains two length indicators, one to_forward counter and one
send_max limit. First, it must be understood that the buffer is in fact ->o limit. First, it must be understood that the buffer is in fact
split in two parts : split in two parts :
- the visible data (->data, for ->l bytes) - the visible data (->data, for ->l bytes)
- the invisible data, typically in kernel buffers forwarded directly from - the invisible data, typically in kernel buffers forwarded directly from
@ -224,18 +224,18 @@ struct buffer {
ensure strict ordering of data between buffers. ensure strict ordering of data between buffers.
The producer is responsible for decreasing ->to_forward and increasing The producer is responsible for decreasing ->to_forward and increasing
->send_max. The ->to_forward parameter indicates how many bytes may be fed ->o. The ->to_forward parameter indicates how many bytes may be fed
into either data buffer without waking the parent up. The special value into either data buffer without waking the parent up. The special value
BUF_INFINITE_FORWARD is never decreased nor increased. The ->send_max BUF_INFINITE_FORWARD is never decreased nor increased. The ->o
parameter says how many bytes may be consumed from the visible buffer. Thus parameter says how many bytes may be consumed from the visible buffer. Thus
it may never exceed ->l. This parameter is updated by any buffer_write() as it may never exceed ->l. This parameter is updated by any buffer_write() as
well as any data forwarded through the visible buffer. Since the ->to_forward well as any data forwarded through the visible buffer. Since the ->to_forward
attribute applies to data after ->w+send_max, an analyser will not see a attribute applies to data after ->w+o, an analyser will not see a
buffer which has a non-null to_forward with send_max < l. A producer is buffer which has a non-null to_forward with o < l. A producer is
responsible for raising ->send_max by min(to_forward, l-send_max) when it responsible for raising ->o by min(to_forward, l-o) when it
injects data into the buffer. injects data into the buffer.
The consumer is responsible for decreasing ->send_max when it sends data The consumer is responsible for decreasing ->o when it sends data
from the visible buffer, and ->pipe->data when it sends data from the from the visible buffer, and ->pipe->data when it sends data from the
invisible buffer. invisible buffer.
@ -243,11 +243,11 @@ struct buffer {
buffer to be forwarded. We know the header length (300) and the amount of buffer to be forwarded. We know the header length (300) and the amount of
data to forward (content-length=9000). The buffer already contains 1000 data to forward (content-length=9000). The buffer already contains 1000
bytes of data after the 300 bytes of headers. Thus the caller will set bytes of data after the 300 bytes of headers. Thus the caller will set
->send_max to 300 indicating that it explicitly wants to send those data, ->o to 300 indicating that it explicitly wants to send those data,
and set ->to_forward to 9000 (content-length). This value must be normalised and set ->to_forward to 9000 (content-length). This value must be normalised
immediately after updating ->to_forward : since there are already 1300 bytes immediately after updating ->to_forward : since there are already 1300 bytes
in the buffer, 300 of which are already counted in ->send_max, and that size in the buffer, 300 of which are already counted in ->o, and that size
is smaller than ->to_forward, we must update ->send_max to 1300 to flush the is smaller than ->to_forward, we must update ->o to 1300 to flush the
whole buffer, and reduce ->to_forward to 8000. After that, the producer may whole buffer, and reduce ->to_forward to 8000. After that, the producer may
try to feed the additional data through the invisible buffer using a try to feed the additional data through the invisible buffer using a
platform-specific method such as splice(). platform-specific method such as splice().
@ -272,9 +272,9 @@ struct buffer {
A buffer may contain up to 5 areas : A buffer may contain up to 5 areas :
- the data waiting to be sent. These data are located between ->w and - the data waiting to be sent. These data are located between ->w and
->w+send_max ; ->w+o ;
- the data to process and possibly transform. These data start at - the data to process and possibly transform. These data start at
->w+send_max and may be up to r-w bytes long. Generally ->lr remains in ->w+o and may be up to r-w bytes long. Generally ->lr remains in
this area ; this area ;
- the data to preserve. They start at the end of the previous one and stop - the data to preserve. They start at the end of the previous one and stop
at ->r. The limit between the two solely depends on the protocol being at ->r. The limit between the two solely depends on the protocol being

View File

@ -35,7 +35,7 @@ int init_buffer()
* in the limit of the number of bytes to forward. This must be the only method * in the limit of the number of bytes to forward. This must be the only method
* to use to schedule bytes to be sent. If the requested number is too large, it * to use to schedule bytes to be sent. If the requested number is too large, it
* is automatically adjusted. The number of bytes taken into account is returned. * is automatically adjusted. The number of bytes taken into account is returned.
* Directly touching ->to_forward will cause lockups when send_max goes down to * Directly touching ->to_forward will cause lockups when ->o goes down to
* zero if nobody is ready to push the remaining data. * zero if nobody is ready to push the remaining data.
*/ */
unsigned long long buffer_forward(struct buffer *buf, unsigned long long bytes) unsigned long long buffer_forward(struct buffer *buf, unsigned long long bytes)
@ -45,15 +45,15 @@ unsigned long long buffer_forward(struct buffer *buf, unsigned long long bytes)
if (!bytes) if (!bytes)
return 0; return 0;
data_left = buf->l - buf->send_max; data_left = buf->l - buf->o;
if (bytes <= (unsigned long long)data_left) { if (bytes <= (unsigned long long)data_left) {
buf->send_max += bytes; buf->o += bytes;
buf->flags &= ~BF_OUT_EMPTY; buf->flags &= ~BF_OUT_EMPTY;
return bytes; return bytes;
} }
buf->send_max += data_left; buf->o += data_left;
if (buf->send_max) if (buf->o)
buf->flags &= ~BF_OUT_EMPTY; buf->flags &= ~BF_OUT_EMPTY;
if (buf->l < buffer_max_len(buf)) if (buf->l < buffer_max_len(buf))
@ -115,7 +115,7 @@ int buffer_write(struct buffer *buf, const char *msg, int len)
memcpy(buf->r, msg, len); memcpy(buf->r, msg, len);
buf->l += len; buf->l += len;
buf->send_max += len; buf->o += len;
buf->r += len; buf->r += len;
buf->total += len; buf->total += len;
if (buf->r == buf->data + buf->size) if (buf->r == buf->data + buf->size)
@ -129,7 +129,7 @@ int buffer_write(struct buffer *buf, const char *msg, int len)
} }
/* Tries to copy character <c> into buffer <buf> after length controls. The /* Tries to copy character <c> into buffer <buf> after length controls. The
* send_max and to_forward pointers are updated. If the buffer's input is * ->o and to_forward pointers are updated. If the buffer's input is
* closed, -2 is returned. If there is not enough room left in the buffer, -1 * closed, -2 is returned. If there is not enough room left in the buffer, -1
* is returned. Otherwise the number of bytes copied is returned (1). Buffer * is returned. Otherwise the number of bytes copied is returned (1). Buffer
* flags FULL, EMPTY and READ_PARTIAL are updated if some data can be * flags FULL, EMPTY and READ_PARTIAL are updated if some data can be
@ -157,7 +157,7 @@ int buffer_put_char(struct buffer *buf, char c)
if (buf->to_forward >= 1) { if (buf->to_forward >= 1) {
if (buf->to_forward != BUF_INFINITE_FORWARD) if (buf->to_forward != BUF_INFINITE_FORWARD)
buf->to_forward--; buf->to_forward--;
buf->send_max++; buf->o++;
buf->flags &= ~BF_OUT_EMPTY; buf->flags &= ~BF_OUT_EMPTY;
} }
@ -166,7 +166,7 @@ int buffer_put_char(struct buffer *buf, char c)
} }
/* Tries to copy block <blk> at once into buffer <buf> after length controls. /* Tries to copy block <blk> at once into buffer <buf> after length controls.
* The send_max and to_forward pointers are updated. If the buffer's input is * The ->o and to_forward pointers are updated. If the buffer's input is
* closed, -2 is returned. If the block is too large for this buffer, -3 is * closed, -2 is returned. If the block is too large for this buffer, -3 is
* returned. If there is not enough room left in the buffer, -1 is returned. * returned. If there is not enough room left in the buffer, -1 is returned.
* Otherwise the number of bytes copied is returned (0 being a valid number). * Otherwise the number of bytes copied is returned (0 being a valid number).
@ -211,7 +211,7 @@ int buffer_put_block(struct buffer *buf, const char *blk, int len)
fwd = buf->to_forward; fwd = buf->to_forward;
buf->to_forward -= fwd; buf->to_forward -= fwd;
} }
buf->send_max += fwd; buf->o += fwd;
buf->flags &= ~BF_OUT_EMPTY; buf->flags &= ~BF_OUT_EMPTY;
} }
@ -254,8 +254,8 @@ int buffer_get_line(struct buffer *buf, char *str, int len)
p = buf->w; p = buf->w;
if (max > buf->send_max) { if (max > buf->o) {
max = buf->send_max; max = buf->o;
str[max-1] = 0; str[max-1] = 0;
} }
while (max) { while (max) {
@ -269,7 +269,7 @@ int buffer_get_line(struct buffer *buf, char *str, int len)
if (p == buf->data + buf->size) if (p == buf->data + buf->size)
p = buf->data; p = buf->data;
} }
if (ret > 0 && ret < len && ret < buf->send_max && if (ret > 0 && ret < len && ret < buf->o &&
*(str-1) != '\n' && *(str-1) != '\n' &&
!(buf->flags & (BF_SHUTW|BF_SHUTW_NOW))) !(buf->flags & (BF_SHUTW|BF_SHUTW_NOW)))
ret = 0; ret = 0;
@ -294,7 +294,7 @@ int buffer_get_block(struct buffer *buf, char *blk, int len, int offset)
if (buf->flags & BF_SHUTW) if (buf->flags & BF_SHUTW)
return -1; return -1;
if (len + offset > buf->send_max) { if (len + offset > buf->o) {
if (buf->flags & (BF_SHUTW|BF_SHUTW_NOW)) if (buf->flags & (BF_SHUTW|BF_SHUTW_NOW))
return -1; return -1;
return 0; return 0;
@ -320,7 +320,7 @@ int buffer_get_block(struct buffer *buf, char *blk, int len, int offset)
* buffer <b>, and moves <end> just after the end of <str>. <b>'s parameters * buffer <b>, and moves <end> just after the end of <str>. <b>'s parameters
* (l, r, lr) are updated to be valid after the shift. the shift value * (l, r, lr) are updated to be valid after the shift. the shift value
* (positive or negative) is returned. If there's no space left, the move is * (positive or negative) is returned. If there's no space left, the move is
* not done. The function does not adjust ->send_max nor BF_OUT_EMPTY because * not done. The function does not adjust ->o nor BF_OUT_EMPTY because
* it does not make sense to use it on data scheduled to be sent. The string * it does not make sense to use it on data scheduled to be sent. The string
* length is taken from parameter <len>. If <len> is null, the <str> pointer * length is taken from parameter <len>. If <len> is null, the <str> pointer
* is allowed to be null. * is allowed to be null.

View File

@ -1500,7 +1500,7 @@ static void cli_io_handler(struct stream_interface *si)
* buffer is empty. This still allows pipelined requests * buffer is empty. This still allows pipelined requests
* to be sent in non-interactive mode. * to be sent in non-interactive mode.
*/ */
if ((res->flags & (BF_SHUTW|BF_SHUTW_NOW)) || (!si->applet.st1 && !req->send_max)) { if ((res->flags & (BF_SHUTW|BF_SHUTW_NOW)) || (!si->applet.st1 && !req->o)) {
si->applet.st0 = STAT_CLI_END; si->applet.st0 = STAT_CLI_END;
continue; continue;
} }
@ -1542,7 +1542,7 @@ static void cli_io_handler(struct stream_interface *si)
out: out:
DPRINTF(stderr, "%s@%d: st=%d, rqf=%x, rpf=%x, rql=%d, rqs=%d, rl=%d, rs=%d\n", DPRINTF(stderr, "%s@%d: st=%d, rqf=%x, rpf=%x, rql=%d, rqs=%d, rl=%d, rs=%d\n",
__FUNCTION__, __LINE__, __FUNCTION__, __LINE__,
si->state, req->flags, res->flags, req->l, req->send_max, res->l, res->send_max); si->state, req->flags, res->flags, req->l, req->o, res->l, res->o);
if (unlikely(si->state == SI_ST_DIS || si->state == SI_ST_CLO)) { if (unlikely(si->state == SI_ST_DIS || si->state == SI_ST_CLO)) {
/* check that we have released everything then unregister */ /* check that we have released everything then unregister */
@ -3370,11 +3370,11 @@ static int stats_dump_full_sess_to_buffer(struct stream_interface *si)
chunk_printf(&msg, chunk_printf(&msg,
" req=%p (f=0x%06x an=0x%x l=%d sndmx=%d pipe=%d fwd=%d)\n" " req=%p (f=0x%06x an=0x%x l=%d o=%d pipe=%d fwd=%d)\n"
" an_exp=%s", " an_exp=%s",
sess->req, sess->req,
sess->req->flags, sess->req->analysers, sess->req->flags, sess->req->analysers,
sess->req->l, sess->req->send_max, sess->req->l, sess->req->o,
sess->req->pipe ? sess->req->pipe->data : 0, sess->req->pipe ? sess->req->pipe->data : 0,
sess->req->to_forward, sess->req->to_forward,
sess->req->analyse_exp ? sess->req->analyse_exp ?
@ -3400,11 +3400,11 @@ static int stats_dump_full_sess_to_buffer(struct stream_interface *si)
sess->req->total); sess->req->total);
chunk_printf(&msg, chunk_printf(&msg,
" res=%p (f=0x%06x an=0x%x l=%d sndmx=%d pipe=%d fwd=%d)\n" " res=%p (f=0x%06x an=0x%x l=%d o=%d pipe=%d fwd=%d)\n"
" an_exp=%s", " an_exp=%s",
sess->rep, sess->rep,
sess->rep->flags, sess->rep->analysers, sess->rep->flags, sess->rep->analysers,
sess->rep->l, sess->rep->send_max, sess->rep->l, sess->rep->o,
sess->rep->pipe ? sess->rep->pipe->data : 0, sess->rep->pipe ? sess->rep->pipe->data : 0,
sess->rep->to_forward, sess->rep->to_forward,
sess->rep->analyse_exp ? sess->rep->analyse_exp ?

View File

@ -393,14 +393,14 @@ static void http_silent_debug(int line, struct session *s)
"[%04d] req: p=%d(%d) s=%d bf=%08x an=%08x data=%p size=%d l=%d w=%p r=%p lr=%p sm=%d fw=%ld tf=%08x\n", "[%04d] req: p=%d(%d) s=%d bf=%08x an=%08x data=%p size=%d l=%d w=%p r=%p lr=%p sm=%d fw=%ld tf=%08x\n",
line, line,
s->si[0].state, s->si[0].fd, s->txn.req.msg_state, s->req->flags, s->req->analysers, s->si[0].state, s->si[0].fd, s->txn.req.msg_state, s->req->flags, s->req->analysers,
s->req->data, s->req->size, s->req->l, s->req->w, s->req->r, s->req->lr, s->req->send_max, s->req->to_forward, s->txn.flags); s->req->data, s->req->size, s->req->l, s->req->w, s->req->r, s->req->lr, s->req->o, s->req->to_forward, s->txn.flags);
write(-1, trash, size); write(-1, trash, size);
size = 0; size = 0;
size += snprintf(trash + size, sizeof(trash) - size, size += snprintf(trash + size, sizeof(trash) - size,
" %04d rep: p=%d(%d) s=%d bf=%08x an=%08x data=%p size=%d l=%d w=%p r=%p lr=%p sm=%d fw=%ld\n", " %04d rep: p=%d(%d) s=%d bf=%08x an=%08x data=%p size=%d l=%d w=%p r=%p lr=%p sm=%d fw=%ld\n",
line, line,
s->si[1].state, s->si[1].fd, s->txn.rsp.msg_state, s->rep->flags, s->rep->analysers, s->si[1].state, s->si[1].fd, s->txn.rsp.msg_state, s->rep->flags, s->rep->analysers,
s->rep->data, s->rep->size, s->rep->l, s->rep->w, s->rep->r, s->rep->lr, s->rep->send_max, s->rep->to_forward); s->rep->data, s->rep->size, s->rep->l, s->rep->w, s->rep->r, s->rep->lr, s->rep->o, s->rep->to_forward);
write(-1, trash, size); write(-1, trash, size);
} }
@ -1295,13 +1295,13 @@ void http_msg_analyzer(struct buffer *buf, struct http_msg *msg, struct hdr_idx
if (likely(HTTP_IS_TOKEN(*ptr))) { if (likely(HTTP_IS_TOKEN(*ptr))) {
/* we have a start of message, but we have to check /* we have a start of message, but we have to check
* first if we need to remove some CRLF. We can only * first if we need to remove some CRLF. We can only
* do this when send_max=0. * do this when o=0.
*/ */
char *beg = buf->w + buf->send_max; char *beg = buf->w + buf->o;
if (beg >= buf->data + buf->size) if (beg >= buf->data + buf->size)
beg -= buf->size; beg -= buf->size;
if (unlikely(ptr != beg)) { if (unlikely(ptr != beg)) {
if (buf->send_max) if (buf->o)
goto http_msg_ood; goto http_msg_ood;
/* Remove empty leading lines, as recommended by RFC2616. */ /* Remove empty leading lines, as recommended by RFC2616. */
buffer_ignore(buf, ptr - beg); buffer_ignore(buf, ptr - beg);
@ -1364,13 +1364,13 @@ void http_msg_analyzer(struct buffer *buf, struct http_msg *msg, struct hdr_idx
if (likely(HTTP_IS_TOKEN(*ptr))) { if (likely(HTTP_IS_TOKEN(*ptr))) {
/* we have a start of message, but we have to check /* we have a start of message, but we have to check
* first if we need to remove some CRLF. We can only * first if we need to remove some CRLF. We can only
* do this when send_max=0. * do this when o=0.
*/ */
char *beg = buf->w + buf->send_max; char *beg = buf->w + buf->o;
if (beg >= buf->data + buf->size) if (beg >= buf->data + buf->size)
beg -= buf->size; beg -= buf->size;
if (likely(ptr != beg)) { if (likely(ptr != beg)) {
if (buf->send_max) if (buf->o)
goto http_msg_ood; goto http_msg_ood;
/* Remove empty leading lines, as recommended by RFC2616. */ /* Remove empty leading lines, as recommended by RFC2616. */
buffer_ignore(buf, ptr - beg); buffer_ignore(buf, ptr - beg);
@ -1944,7 +1944,7 @@ int http_skip_chunk_crlf(struct buffer *buf, struct http_msg *msg)
ptr = buf->data; ptr = buf->data;
} }
if (bytes > buf->l - buf->send_max) if (bytes > buf->l - buf->o)
return 0; return 0;
if (*ptr != '\n') { if (*ptr != '\n') {
@ -2069,7 +2069,7 @@ int http_wait_for_request(struct session *s, struct buffer *req, int an_bit)
unlikely((req->flags & BF_FULL) || unlikely((req->flags & BF_FULL) ||
req->r < req->lr || req->r < req->lr ||
req->r > req->data + req->size - global.tune.maxrewrite)) { req->r > req->data + req->size - global.tune.maxrewrite)) {
if (req->send_max) { if (req->o) {
if (req->flags & (BF_SHUTW|BF_SHUTW_NOW|BF_WRITE_ERROR|BF_WRITE_TIMEOUT)) if (req->flags & (BF_SHUTW|BF_SHUTW_NOW|BF_WRITE_ERROR|BF_WRITE_TIMEOUT))
goto failed_keep_alive; goto failed_keep_alive;
/* some data has still not left the buffer, wake us once that's done */ /* some data has still not left the buffer, wake us once that's done */
@ -2092,7 +2092,7 @@ int http_wait_for_request(struct session *s, struct buffer *req, int an_bit)
unlikely((s->rep->flags & BF_FULL) || unlikely((s->rep->flags & BF_FULL) ||
s->rep->r < s->rep->lr || s->rep->r < s->rep->lr ||
s->rep->r > s->rep->data + s->rep->size - global.tune.maxrewrite)) { s->rep->r > s->rep->data + s->rep->size - global.tune.maxrewrite)) {
if (s->rep->send_max) { if (s->rep->o) {
if (s->rep->flags & (BF_SHUTW|BF_SHUTW_NOW|BF_WRITE_ERROR|BF_WRITE_TIMEOUT)) if (s->rep->flags & (BF_SHUTW|BF_SHUTW_NOW|BF_WRITE_ERROR|BF_WRITE_TIMEOUT))
goto failed_keep_alive; goto failed_keep_alive;
/* don't let a connection request be initiated */ /* don't let a connection request be initiated */
@ -3755,8 +3755,8 @@ void http_end_txn_clean_session(struct session *s)
} }
/* don't count other requests' data */ /* don't count other requests' data */
s->logs.bytes_in -= s->req->l - s->req->send_max; s->logs.bytes_in -= s->req->l - s->req->o;
s->logs.bytes_out -= s->rep->l - s->rep->send_max; s->logs.bytes_out -= s->rep->l - s->rep->o;
/* let's do a final log if we need it */ /* let's do a final log if we need it */
if (s->logs.logwait && if (s->logs.logwait &&
@ -3775,8 +3775,8 @@ void http_end_txn_clean_session(struct session *s)
s->logs.prx_queue_size = 0; /* we get the number of pending conns before us */ s->logs.prx_queue_size = 0; /* we get the number of pending conns before us */
s->logs.srv_queue_size = 0; /* we will get this number soon */ s->logs.srv_queue_size = 0; /* we will get this number soon */
s->logs.bytes_in = s->req->total = s->req->l - s->req->send_max; s->logs.bytes_in = s->req->total = s->req->l - s->req->o;
s->logs.bytes_out = s->rep->total = s->rep->l - s->rep->send_max; s->logs.bytes_out = s->rep->total = s->rep->l - s->rep->o;
if (s->pend_pos) if (s->pend_pos)
pendconn_free(s->pend_pos); pendconn_free(s->pend_pos);
@ -3821,8 +3821,8 @@ void http_end_txn_clean_session(struct session *s)
* because the request will wait for it to flush a little * because the request will wait for it to flush a little
* bit before proceeding. * bit before proceeding.
*/ */
if (s->req->l > s->req->send_max) { if (s->req->l > s->req->o) {
if (s->rep->send_max && if (s->rep->o &&
!(s->rep->flags & BF_FULL) && !(s->rep->flags & BF_FULL) &&
s->rep->r <= s->rep->data + s->rep->size - global.tune.maxrewrite) s->rep->r <= s->rep->data + s->rep->size - global.tune.maxrewrite)
s->rep->flags |= BF_EXPECT_MORE; s->rep->flags |= BF_EXPECT_MORE;
@ -3835,10 +3835,10 @@ void http_end_txn_clean_session(struct session *s)
buffer_auto_close(s->rep); buffer_auto_close(s->rep);
/* make ->lr point to the first non-forwarded byte */ /* make ->lr point to the first non-forwarded byte */
s->req->lr = s->req->w + s->req->send_max; s->req->lr = s->req->w + s->req->o;
if (s->req->lr >= s->req->data + s->req->size) if (s->req->lr >= s->req->data + s->req->size)
s->req->lr -= s->req->size; s->req->lr -= s->req->size;
s->rep->lr = s->rep->w + s->rep->send_max; s->rep->lr = s->rep->w + s->rep->o;
if (s->rep->lr >= s->rep->data + s->rep->size) if (s->rep->lr >= s->rep->data + s->rep->size)
s->rep->lr -= s->req->size; s->rep->lr -= s->req->size;
@ -4087,7 +4087,7 @@ int http_sync_res_state(struct session *s)
if (txn->rsp.msg_state == HTTP_MSG_CLOSED) { if (txn->rsp.msg_state == HTTP_MSG_CLOSED) {
http_msg_closed: http_msg_closed:
/* drop any pending data */ /* drop any pending data */
buffer_ignore(buf, buf->l - buf->send_max); buffer_ignore(buf, buf->l - buf->o);
buffer_auto_close(buf); buffer_auto_close(buf);
buffer_auto_read(buf); buffer_auto_read(buf);
goto wait_other_side; goto wait_other_side;
@ -4153,7 +4153,7 @@ int http_resync_states(struct session *s)
buffer_abort(s->req); buffer_abort(s->req);
buffer_auto_close(s->req); buffer_auto_close(s->req);
buffer_auto_read(s->req); buffer_auto_read(s->req);
buffer_ignore(s->req, s->req->l - s->req->send_max); buffer_ignore(s->req, s->req->l - s->req->o);
} }
else if (txn->req.msg_state == HTTP_MSG_CLOSED && else if (txn->req.msg_state == HTTP_MSG_CLOSED &&
txn->rsp.msg_state == HTTP_MSG_DONE && txn->rsp.msg_state == HTTP_MSG_DONE &&
@ -4189,7 +4189,7 @@ int http_request_forward_body(struct session *s, struct buffer *req, int an_bit)
return 0; return 0;
if ((req->flags & (BF_READ_ERROR|BF_READ_TIMEOUT|BF_WRITE_ERROR|BF_WRITE_TIMEOUT)) || if ((req->flags & (BF_READ_ERROR|BF_READ_TIMEOUT|BF_WRITE_ERROR|BF_WRITE_TIMEOUT)) ||
((req->flags & BF_SHUTW) && (req->to_forward || req->send_max))) { ((req->flags & BF_SHUTW) && (req->to_forward || req->o))) {
/* Output closed while we were sending data. We must abort and /* Output closed while we were sending data. We must abort and
* wake the other side up. * wake the other side up.
*/ */
@ -4267,7 +4267,7 @@ int http_request_forward_body(struct session *s, struct buffer *req, int an_bit)
/* we want the CRLF after the data */ /* we want the CRLF after the data */
int ret; int ret;
req->lr = req->w + req->send_max; req->lr = req->w + req->o;
if (req->lr >= req->data + req->size) if (req->lr >= req->data + req->size)
req->lr -= req->size; req->lr -= req->size;
@ -4494,7 +4494,7 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit)
if (unlikely((rep->flags & BF_FULL) || if (unlikely((rep->flags & BF_FULL) ||
rep->r < rep->lr || rep->r < rep->lr ||
rep->r > rep->data + rep->size - global.tune.maxrewrite)) { rep->r > rep->data + rep->size - global.tune.maxrewrite)) {
if (rep->send_max) { if (rep->o) {
/* some data has still not left the buffer, wake us once that's done */ /* 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)) if (rep->flags & (BF_SHUTW|BF_SHUTW_NOW|BF_WRITE_ERROR|BF_WRITE_TIMEOUT))
goto abort_response; goto abort_response;
@ -4565,7 +4565,7 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit)
rep->analysers = 0; rep->analysers = 0;
txn->status = 502; txn->status = 502;
rep->prod->flags |= SI_FL_NOLINGER; rep->prod->flags |= SI_FL_NOLINGER;
buffer_ignore(rep, rep->l - rep->send_max); buffer_ignore(rep, rep->l - rep->o);
stream_int_retnclose(rep->cons, error_message(s, HTTP_ERR_502)); stream_int_retnclose(rep->cons, error_message(s, HTTP_ERR_502));
if (!(s->flags & SN_ERR_MASK)) if (!(s->flags & SN_ERR_MASK))
@ -4598,7 +4598,7 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit)
rep->analysers = 0; rep->analysers = 0;
txn->status = 502; txn->status = 502;
rep->prod->flags |= SI_FL_NOLINGER; rep->prod->flags |= SI_FL_NOLINGER;
buffer_ignore(rep, rep->l - rep->send_max); buffer_ignore(rep, rep->l - rep->o);
stream_int_retnclose(rep->cons, error_message(s, HTTP_ERR_502)); stream_int_retnclose(rep->cons, error_message(s, HTTP_ERR_502));
if (!(s->flags & SN_ERR_MASK)) if (!(s->flags & SN_ERR_MASK))
@ -4623,7 +4623,7 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit)
rep->analysers = 0; rep->analysers = 0;
txn->status = 504; txn->status = 504;
rep->prod->flags |= SI_FL_NOLINGER; rep->prod->flags |= SI_FL_NOLINGER;
buffer_ignore(rep, rep->l - rep->send_max); buffer_ignore(rep, rep->l - rep->o);
stream_int_retnclose(rep->cons, error_message(s, HTTP_ERR_504)); stream_int_retnclose(rep->cons, error_message(s, HTTP_ERR_504));
if (!(s->flags & SN_ERR_MASK)) if (!(s->flags & SN_ERR_MASK))
@ -4648,7 +4648,7 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit)
rep->analysers = 0; rep->analysers = 0;
txn->status = 502; txn->status = 502;
rep->prod->flags |= SI_FL_NOLINGER; rep->prod->flags |= SI_FL_NOLINGER;
buffer_ignore(rep, rep->l - rep->send_max); buffer_ignore(rep, rep->l - rep->o);
stream_int_retnclose(rep->cons, error_message(s, HTTP_ERR_502)); stream_int_retnclose(rep->cons, error_message(s, HTTP_ERR_502));
if (!(s->flags & SN_ERR_MASK)) if (!(s->flags & SN_ERR_MASK))
@ -4998,7 +4998,7 @@ int http_process_res_common(struct session *t, struct buffer *rep, int an_bit, s
rep->analysers = 0; rep->analysers = 0;
txn->status = 502; txn->status = 502;
rep->prod->flags |= SI_FL_NOLINGER; rep->prod->flags |= SI_FL_NOLINGER;
buffer_ignore(rep, rep->l - rep->send_max); buffer_ignore(rep, rep->l - rep->o);
stream_int_retnclose(rep->cons, error_message(t, HTTP_ERR_502)); stream_int_retnclose(rep->cons, error_message(t, HTTP_ERR_502));
if (!(t->flags & SN_ERR_MASK)) if (!(t->flags & SN_ERR_MASK))
t->flags |= SN_ERR_PRXCOND; t->flags |= SN_ERR_PRXCOND;
@ -5259,7 +5259,7 @@ int http_response_forward_body(struct session *s, struct buffer *res, int an_bit
return 0; return 0;
if ((res->flags & (BF_READ_ERROR|BF_READ_TIMEOUT|BF_WRITE_ERROR|BF_WRITE_TIMEOUT)) || if ((res->flags & (BF_READ_ERROR|BF_READ_TIMEOUT|BF_WRITE_ERROR|BF_WRITE_TIMEOUT)) ||
((res->flags & BF_SHUTW) && (res->to_forward || res->send_max)) || ((res->flags & BF_SHUTW) && (res->to_forward || res->o)) ||
!s->req->analysers) { !s->req->analysers) {
/* Output closed while we were sending data. We must abort and /* Output closed while we were sending data. We must abort and
* wake the other side up. * wake the other side up.
@ -5331,7 +5331,7 @@ int http_response_forward_body(struct session *s, struct buffer *res, int an_bit
/* we want the CRLF after the data */ /* we want the CRLF after the data */
int ret; int ret;
res->lr = res->w + res->send_max; res->lr = res->w + res->o;
if (res->lr >= res->data + res->size) if (res->lr >= res->data + res->size)
res->lr -= res->size; res->lr -= res->size;
@ -7456,8 +7456,8 @@ void http_reset_txn(struct session *s)
* a HEAD with some data, or sending more than the advertised * a HEAD with some data, or sending more than the advertised
* content-length. * content-length.
*/ */
if (unlikely(s->rep->l > s->rep->send_max)) { if (unlikely(s->rep->l > s->rep->o)) {
s->rep->l = s->rep->send_max; s->rep->l = s->rep->o;
s->rep->r = s->rep->w + s->rep->l; s->rep->r = s->rep->w + s->rep->l;
if (s->rep->r >= s->rep->data + s->rep->size) if (s->rep->r >= s->rep->data + s->rep->size)
s->rep->r -= s->rep->size; s->rep->r -= s->rep->size;

View File

@ -393,7 +393,7 @@ int tcp_connect_server(struct stream_interface *si)
* machine with the first ACK. We only do this if there are pending * machine with the first ACK. We only do this if there are pending
* data in the buffer. * data in the buffer.
*/ */
if ((be->options2 & PR_O2_SMARTCON) && si->ob->send_max) if ((be->options2 & PR_O2_SMARTCON) && si->ob->o)
setsockopt(fd, IPPROTO_TCP, TCP_QUICKACK, &zero, sizeof(zero)); setsockopt(fd, IPPROTO_TCP, TCP_QUICKACK, &zero, sizeof(zero));
#endif #endif

View File

@ -301,7 +301,7 @@ int stream_sock_read(int fd) {
b->l += ret; b->l += ret;
cur_read += ret; cur_read += ret;
/* if we're allowed to directly forward data, we must update send_max */ /* if we're allowed to directly forward data, we must update ->o */
if (b->to_forward && !(b->flags & (BF_SHUTW|BF_SHUTW_NOW))) { if (b->to_forward && !(b->flags & (BF_SHUTW|BF_SHUTW_NOW))) {
unsigned long fwd = ret; unsigned long fwd = ret;
if (b->to_forward != BUF_INFINITE_FORWARD) { if (b->to_forward != BUF_INFINITE_FORWARD) {
@ -309,7 +309,7 @@ int stream_sock_read(int fd) {
fwd = b->to_forward; fwd = b->to_forward;
b->to_forward -= fwd; b->to_forward -= fwd;
} }
b->send_max += fwd; b->o += fwd;
b->flags &= ~BF_OUT_EMPTY; b->flags &= ~BF_OUT_EMPTY;
} }
@ -446,7 +446,7 @@ int stream_sock_read(int fd) {
* HTTP chunking). * HTTP chunking).
*/ */
if (b->pipe || /* always try to send spliced data */ if (b->pipe || /* always try to send spliced data */
(b->send_max == b->l && (b->cons->flags & SI_FL_WAIT_DATA))) { (b->o == b->l && (b->cons->flags & SI_FL_WAIT_DATA))) {
int last_len = b->pipe ? b->pipe->data : 0; int last_len = b->pipe ? b->pipe->data : 0;
b->cons->chk_snd(b->cons); b->cons->chk_snd(b->cons);
@ -588,7 +588,7 @@ static int stream_sock_write_loop(struct stream_interface *si, struct buffer *b)
* in the normal buffer. * in the normal buffer.
*/ */
#endif #endif
if (!b->send_max) { if (!b->o) {
b->flags |= BF_OUT_EMPTY; b->flags |= BF_OUT_EMPTY;
return retval; return retval;
} }
@ -603,8 +603,8 @@ static int stream_sock_write_loop(struct stream_interface *si, struct buffer *b)
max = b->data + b->size - b->w; max = b->data + b->size - b->w;
/* limit the amount of outgoing data if required */ /* limit the amount of outgoing data if required */
if (max > b->send_max) if (max > b->o)
max = b->send_max; max = b->o;
/* check if we want to inform the kernel that we're interested in /* check if we want to inform the kernel that we're interested in
* sending more data after this call. We want this if : * sending more data after this call. We want this if :
@ -623,8 +623,8 @@ static int stream_sock_write_loop(struct stream_interface *si, struct buffer *b)
if ((!(b->flags & BF_NEVER_WAIT) && if ((!(b->flags & BF_NEVER_WAIT) &&
((b->to_forward && b->to_forward != BUF_INFINITE_FORWARD) || ((b->to_forward && b->to_forward != BUF_INFINITE_FORWARD) ||
(b->flags & BF_EXPECT_MORE))) || (b->flags & BF_EXPECT_MORE))) ||
((b->flags & (BF_SHUTW|BF_SHUTW_NOW|BF_HIJACK)) == BF_SHUTW_NOW && (max == b->send_max)) || ((b->flags & (BF_SHUTW|BF_SHUTW_NOW|BF_HIJACK)) == BF_SHUTW_NOW && (max == b->o)) ||
(max != b->l && max != b->send_max)) { (max != b->l && max != b->o)) {
send_flag |= MSG_MORE; send_flag |= MSG_MORE;
} }
@ -662,8 +662,8 @@ static int stream_sock_write_loop(struct stream_interface *si, struct buffer *b)
/* optimize data alignment in the buffer */ /* optimize data alignment in the buffer */
b->r = b->w = b->lr = b->data; b->r = b->w = b->lr = b->data;
b->send_max -= ret; b->o -= ret;
if (!b->send_max) { if (!b->o) {
/* Always clear both flags once everything has been sent, they're one-shot */ /* Always clear both flags once everything has been sent, they're one-shot */
b->flags &= ~(BF_EXPECT_MORE | BF_SEND_DONTWAIT); b->flags &= ~(BF_EXPECT_MORE | BF_SEND_DONTWAIT);
if (likely(!b->pipe)) if (likely(!b->pipe))
@ -757,7 +757,7 @@ int stream_sock_write(int fd)
/* Funny, we were called to write something but there wasn't /* Funny, we were called to write something but there wasn't
* anything. We can get there, for example if we were woken up * anything. We can get there, for example if we were woken up
* on a write event to finish the splice, but the send_max is 0 * on a write event to finish the splice, but the ->o is 0
* so we cannot write anything from the buffer. Let's disable * so we cannot write anything from the buffer. Let's disable
* the write event and pretend we never came there. * the write event and pretend we never came there.
*/ */
@ -766,7 +766,7 @@ int stream_sock_write(int fd)
if (b->flags & BF_OUT_EMPTY) { if (b->flags & BF_OUT_EMPTY) {
/* the connection is established but we can't write. Either the /* the connection is established but we can't write. Either the
* buffer is empty, or we just refrain from sending because the * buffer is empty, or we just refrain from sending because the
* send_max limit was reached. Maybe we just wrote the last * ->o limit was reached. Maybe we just wrote the last
* chunk and need to close. * chunk and need to close.
*/ */
if (((b->flags & (BF_SHUTW|BF_HIJACK|BF_SHUTW_NOW)) == BF_SHUTW_NOW) && if (((b->flags & (BF_SHUTW|BF_HIJACK|BF_SHUTW_NOW)) == BF_SHUTW_NOW) &&
@ -1097,7 +1097,7 @@ void stream_sock_chk_snd(struct stream_interface *si)
if (ob->flags & BF_OUT_EMPTY) { if (ob->flags & BF_OUT_EMPTY) {
/* the connection is established but we can't write. Either the /* the connection is established but we can't write. Either the
* buffer is empty, or we just refrain from sending because the * buffer is empty, or we just refrain from sending because the
* send_max limit was reached. Maybe we just wrote the last * ->o limit was reached. Maybe we just wrote the last
* chunk and need to close. * chunk and need to close.
*/ */
if (((ob->flags & (BF_SHUTW|BF_HIJACK|BF_AUTO_CLOSE|BF_SHUTW_NOW)) == if (((ob->flags & (BF_SHUTW|BF_HIJACK|BF_AUTO_CLOSE|BF_SHUTW_NOW)) ==