mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2026-01-19 00:51:37 +01:00
MINOR: channel/buffer: replace buffer_slow_realign() with channel_slow_realign() and b_slow_realign()
Where relevant, the channel version is used instead. The buffer version was ported to be more generic and now takes a swap buffer and the output byte count to know where to set the alignment point. The H2 mux still uses buffer_slow_realign() with buf->o but it will change later.
This commit is contained in:
parent
d5b343bf9e
commit
4cf1300e6a
@ -329,6 +329,47 @@ static inline void b_realign_if_empty(struct buffer *b)
|
||||
b->p = b->data;
|
||||
}
|
||||
|
||||
/* b_slow_realign() : this function realigns a possibly wrapping buffer so that
|
||||
* the part remaining to be parsed is contiguous and starts at the beginning of
|
||||
* the buffer and the already parsed output part ends at the end of the buffer.
|
||||
* This provides the best conditions since it allows the largest inputs to be
|
||||
* processed at once and ensures that once the output data leaves, the whole
|
||||
* buffer is available at once. The number of output bytes supposedly present
|
||||
* at the beginning of the buffer and which need to be moved to the end must be
|
||||
* passed in <output>. A temporary swap area at least as large as b->size must
|
||||
* be provided in <swap>. It's up to the caller to ensure <output> is no larger
|
||||
* than the difference between the whole buffer's length and its input.
|
||||
*/
|
||||
static inline void b_slow_realign(struct buffer *b, char *swap, size_t output)
|
||||
{
|
||||
size_t block1 = output;
|
||||
size_t block2 = 0;
|
||||
|
||||
/* process output data in two steps to cover wrapping */
|
||||
if (block1 > b_size(b) - b_head_ofs(b)) {
|
||||
block2 = b_size(b) - b_head_ofs(b);
|
||||
block1 -= block2;
|
||||
}
|
||||
memcpy(swap + b_size(b) - output, b_head(b), block1);
|
||||
memcpy(swap + b_size(b) - block2, b_orig(b), block2);
|
||||
|
||||
/* process input data in two steps to cover wrapping */
|
||||
block1 = b_data(b) - output;
|
||||
block2 = 0;
|
||||
|
||||
if (block1 > b_tail_ofs(b)) {
|
||||
block2 = b_tail_ofs(b);
|
||||
block1 = block1 - block2;
|
||||
}
|
||||
memcpy(swap, b_peek(b, output), block1);
|
||||
memcpy(swap + block1, b_orig(b), block2);
|
||||
|
||||
/* reinject changes into the buffer */
|
||||
memcpy(b_orig(b), swap, b_data(b) - output);
|
||||
memcpy(b_wrap(b) - output, swap + b_size(b) - output, output);
|
||||
|
||||
b->p = b->data;
|
||||
}
|
||||
|
||||
#endif /* _COMMON_BUF_H */
|
||||
|
||||
|
||||
@ -52,7 +52,7 @@ void deinit_buffer();
|
||||
int buffer_replace2(struct buffer *b, char *pos, char *end, const char *str, int len);
|
||||
int buffer_insert_line2(struct buffer *b, char *pos, const char *str, int len);
|
||||
void buffer_dump(FILE *o, struct buffer *b, int from, int to);
|
||||
void buffer_slow_realign(struct buffer *buf);
|
||||
void buffer_slow_realign(struct buffer *buf, size_t output);
|
||||
|
||||
/*****************************************************************/
|
||||
/* These functions are used to compute various buffer area sizes */
|
||||
|
||||
@ -701,6 +701,17 @@ static inline void channel_truncate(struct channel *chn)
|
||||
chn->buf->i = 0;
|
||||
}
|
||||
|
||||
/* This function realigns a possibly wrapping channel buffer so that the input
|
||||
* part is contiguous and starts at the beginning of the buffer and the output
|
||||
* part ends at the end of the buffer. This provides the best conditions since
|
||||
* it allows the largest inputs to be processed at once and ensures that once
|
||||
* the output data leaves, the whole buffer is available at once.
|
||||
*/
|
||||
static inline void channel_slow_realign(struct channel *chn)
|
||||
{
|
||||
return buffer_slow_realign(chn->buf, co_data(chn));
|
||||
}
|
||||
|
||||
/*
|
||||
* Advance the channel buffer's read pointer by <len> bytes. This is useful
|
||||
* when data have been read directly from the buffer. It is illegal to call
|
||||
|
||||
36
src/buffer.c
36
src/buffer.c
@ -172,37 +172,15 @@ int buffer_insert_line2(struct buffer *b, char *pos, const char *str, int len)
|
||||
* contiguous and starts at the beginning of the buffer and the output part
|
||||
* ends at the end of the buffer. This provides the best conditions since it
|
||||
* allows the largest inputs to be processed at once and ensures that once the
|
||||
* output data leaves, the whole buffer is available at once.
|
||||
* output data leaves, the whole buffer is available at once. The number of
|
||||
* output bytes supposedly present at the beginning of the buffer and which
|
||||
* need to be moved to the end must be passed in <output>. It's up to the
|
||||
* caller to ensure <output> is no larger than the difference between the
|
||||
* while buffer's length and its input.
|
||||
*/
|
||||
void buffer_slow_realign(struct buffer *buf)
|
||||
void buffer_slow_realign(struct buffer *buf, size_t output)
|
||||
{
|
||||
int block1 = buf->o;
|
||||
int block2 = 0;
|
||||
|
||||
/* process output data in two steps to cover wrapping */
|
||||
if (block1 > buf->p - buf->data) {
|
||||
block2 = buf->p - buf->data;
|
||||
block1 -= block2;
|
||||
}
|
||||
memcpy(swap_buffer + buf->size - buf->o, bo_ptr(buf), block1);
|
||||
memcpy(swap_buffer + buf->size - block2, buf->data, block2);
|
||||
|
||||
/* process input data in two steps to cover wrapping */
|
||||
block1 = buf->i;
|
||||
block2 = 0;
|
||||
|
||||
if (block1 > buf->data + buf->size - buf->p) {
|
||||
block1 = buf->data + buf->size - buf->p;
|
||||
block2 = buf->i - block1;
|
||||
}
|
||||
memcpy(swap_buffer, bi_ptr(buf), block1);
|
||||
memcpy(swap_buffer + block1, buf->data, block2);
|
||||
|
||||
/* reinject changes into the buffer */
|
||||
memcpy(buf->data, swap_buffer, buf->i);
|
||||
memcpy(buf->data + buf->size - buf->o, swap_buffer + buf->size - buf->o, buf->o);
|
||||
|
||||
buf->p = buf->data;
|
||||
return b_slow_realign(buf, swap_buffer, output);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@ -3041,7 +3041,7 @@ __LJMP static int hlua_channel_send_yield(lua_State *L, int status, lua_KContext
|
||||
* detects a non contiguous buffer and realign it.
|
||||
*/
|
||||
if (bi_space_for_replace(chn->buf) < max)
|
||||
buffer_slow_realign(chn->buf);
|
||||
channel_slow_realign(chn);
|
||||
|
||||
/* Copy input data in the buffer. */
|
||||
max = buffer_replace2(chn->buf, chn->buf->p, chn->buf->p, str + l, max);
|
||||
|
||||
@ -2688,7 +2688,7 @@ static int h2_frt_decode_headers(struct h2s *h2s, struct buffer *buf, int count)
|
||||
/* it doesn't fit and the buffer is fragmented,
|
||||
* so let's defragment it and try again.
|
||||
*/
|
||||
buffer_slow_realign(buf);
|
||||
buffer_slow_realign(buf, 0);
|
||||
}
|
||||
|
||||
/* first check if we have some room after p+i */
|
||||
@ -2995,7 +2995,7 @@ static int h2s_frt_make_resp_headers(struct h2s *h2s, struct buffer *buf)
|
||||
if (outbuf.size >= 9 || !buffer_space_wraps(h2c->mbuf))
|
||||
break;
|
||||
realign_again:
|
||||
buffer_slow_realign(h2c->mbuf);
|
||||
buffer_slow_realign(h2c->mbuf, h2c->mbuf->o);
|
||||
}
|
||||
|
||||
if (outbuf.size < 9) {
|
||||
@ -3153,7 +3153,7 @@ static int h2s_frt_make_resp_data(struct h2s *h2s, struct buffer *buf)
|
||||
if (outbuf.size >= 9 || !buffer_space_wraps(h2c->mbuf))
|
||||
break;
|
||||
realign_again:
|
||||
buffer_slow_realign(h2c->mbuf);
|
||||
buffer_slow_realign(h2c->mbuf, h2c->mbuf->o);
|
||||
}
|
||||
|
||||
if (outbuf.size < 9) {
|
||||
|
||||
@ -1652,7 +1652,7 @@ int http_wait_for_request(struct stream *s, struct channel *req, int an_bit)
|
||||
}
|
||||
if (unlikely(bi_end(req->buf) < b_ptr(req->buf, msg->next) ||
|
||||
bi_end(req->buf) > req->buf->data + req->buf->size - global.tune.maxrewrite))
|
||||
buffer_slow_realign(req->buf);
|
||||
channel_slow_realign(req);
|
||||
}
|
||||
|
||||
if (likely(msg->next < req->buf->i)) /* some unparsed data are available */
|
||||
@ -5139,7 +5139,7 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
|
||||
|
||||
if (unlikely(bi_end(rep->buf) < b_ptr(rep->buf, msg->next) ||
|
||||
bi_end(rep->buf) > rep->buf->data + rep->buf->size - global.tune.maxrewrite))
|
||||
buffer_slow_realign(rep->buf);
|
||||
channel_slow_realign(rep);
|
||||
|
||||
if (likely(msg->next < rep->buf->i))
|
||||
http_msg_analyzer(msg, &txn->hdr_idx);
|
||||
@ -9517,7 +9517,7 @@ int smp_prefetch_http(struct proxy *px, struct stream *s, unsigned int opt,
|
||||
*/
|
||||
if (s->req.buf->p > s->req.buf->data &&
|
||||
s->req.buf->i + s->req.buf->p > s->req.buf->data + s->req.buf->size - global.tune.maxrewrite)
|
||||
buffer_slow_realign(s->req.buf);
|
||||
channel_slow_realign(&s->req);
|
||||
|
||||
if (unlikely(txn->req.msg_state < HTTP_MSG_BODY)) {
|
||||
if (msg->msg_state == HTTP_MSG_ERROR)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user