mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-27 08:01:15 +00:00
MEDIUM: snapshots: dynamically allocate the snapshots
Now upon error we dynamically allocate the snapshot instead of overwriting it. This way there is no more memory wasted in the proxy to hold the two error snapshot descriptors. Also an appreciable side effect of this is that the proxy's lock is only taken during the pointer swap, no more while copying the buffer's contents. This saves 480 bytes of memory per proxy.
This commit is contained in:
parent
36b2736a69
commit
c55015ee5b
@ -410,7 +410,7 @@ struct proxy {
|
||||
|
||||
/* warning: these structs are huge, keep them at the bottom */
|
||||
struct sockaddr_storage dispatch_addr; /* the default address to connect to */
|
||||
struct error_snapshot invalid_req, invalid_rep; /* captures of last errors */
|
||||
struct error_snapshot *invalid_req, *invalid_rep; /* captures of last errors */
|
||||
|
||||
/* used only during configuration parsing */
|
||||
int no_options; /* PR_O_REDISP, PR_O_TRANSP, ... */
|
||||
|
30
src/proxy.c
30
src/proxy.c
@ -1356,6 +1356,15 @@ void proxy_capture_error(struct proxy *proxy, int is_back,
|
||||
struct error_snapshot *es;
|
||||
unsigned int buf_len;
|
||||
int len1, len2;
|
||||
unsigned int ev_id;
|
||||
|
||||
ev_id = HA_ATOMIC_XADD(&error_snapshot_id, 1);
|
||||
|
||||
es = malloc(sizeof(*es));
|
||||
if (!es)
|
||||
return;
|
||||
|
||||
es->ev_id = ev_id;
|
||||
|
||||
buf_len = b_data(buf) - buf_out;
|
||||
len1 = b_size(buf) - buf_len;
|
||||
@ -1363,9 +1372,6 @@ void proxy_capture_error(struct proxy *proxy, int is_back,
|
||||
len1 = buf_len;
|
||||
len2 = buf_len - len1;
|
||||
|
||||
HA_SPIN_LOCK(PROXY_LOCK, &proxy->lock);
|
||||
es = is_back ? &proxy->invalid_rep : &proxy->invalid_req;
|
||||
|
||||
es->buf_len = buf_len;
|
||||
|
||||
if (!es->buf)
|
||||
@ -1386,7 +1392,6 @@ void proxy_capture_error(struct proxy *proxy, int is_back,
|
||||
else
|
||||
memset(&es->src, 0, sizeof(es->src));
|
||||
|
||||
es->ev_id = HA_ATOMIC_XADD(&error_snapshot_id, 1);
|
||||
es->buf_wrap = b_wrap(buf) - b_peek(buf, buf_out);
|
||||
es->buf_out = buf_out;
|
||||
es->buf_ofs = buf_ofs;
|
||||
@ -1403,6 +1408,17 @@ void proxy_capture_error(struct proxy *proxy, int is_back,
|
||||
else
|
||||
memset(&es->ctx, 0, sizeof(es->ctx));
|
||||
es->show = show;
|
||||
|
||||
/* note: we still lock since we have to be certain that nobody is
|
||||
* dumping the output while we free.
|
||||
*/
|
||||
HA_SPIN_LOCK(PROXY_LOCK, &proxy->lock);
|
||||
if (is_back) {
|
||||
es = HA_ATOMIC_XCHG(&proxy->invalid_rep, es);
|
||||
} else {
|
||||
es = HA_ATOMIC_XCHG(&proxy->invalid_req, es);
|
||||
}
|
||||
free(es);
|
||||
HA_SPIN_UNLOCK(PROXY_LOCK, &proxy->lock);
|
||||
}
|
||||
|
||||
@ -2012,17 +2028,17 @@ static int cli_io_handler_show_errors(struct appctx *appctx)
|
||||
HA_SPIN_LOCK(PROXY_LOCK, &appctx->ctx.errors.px->lock);
|
||||
|
||||
if ((appctx->ctx.errors.flag & 1) == 0) {
|
||||
es = &appctx->ctx.errors.px->invalid_req;
|
||||
es = appctx->ctx.errors.px->invalid_req;
|
||||
if (appctx->ctx.errors.flag & 2) // skip req
|
||||
goto next;
|
||||
}
|
||||
else {
|
||||
es = &appctx->ctx.errors.px->invalid_rep;
|
||||
es = appctx->ctx.errors.px->invalid_rep;
|
||||
if (appctx->ctx.errors.flag & 4) // skip resp
|
||||
goto next;
|
||||
}
|
||||
|
||||
if (!es->when.tv_sec)
|
||||
if (!es)
|
||||
goto next;
|
||||
|
||||
if (appctx->ctx.errors.iid >= 0 &&
|
||||
|
Loading…
Reference in New Issue
Block a user