MEDIUM: compression: use pool for comp_ctx

Use pool for comp_ctx, it is allocated during the comp_algo->init().
The allocation of comp_ctx is accounted for in the zlib_memory_available.
This commit is contained in:
William Lallemand 2012-11-16 18:06:41 +01:00 committed by Willy Tarreau
parent 1feca01896
commit 8b52bb3878
6 changed files with 104 additions and 46 deletions

View File

@ -33,22 +33,21 @@ int http_compression_buffer_init(struct session *s, struct buffer *in, struct bu
int http_compression_buffer_add_data(struct session *s, struct buffer *in, struct buffer *out); int http_compression_buffer_add_data(struct session *s, struct buffer *in, struct buffer *out);
int http_compression_buffer_end(struct session *s, struct buffer **in, struct buffer **out, int end); int http_compression_buffer_end(struct session *s, struct buffer **in, struct buffer **out, int end);
int identity_init(struct comp_ctx *comp_ctx, int level); int identity_init(struct comp_ctx **comp_ctx, int level);
int identity_add_data(struct comp_ctx *comp_ctx, const char *in_data, int in_len, struct buffer *out); int identity_add_data(struct comp_ctx *comp_ctx, const char *in_data, int in_len, struct buffer *out);
int identity_flush(struct comp_ctx *comp_ctx, struct buffer *out, int flag); int identity_flush(struct comp_ctx *comp_ctx, struct buffer *out, int flag);
int identity_reset(struct comp_ctx *comp_ctx); int identity_reset(struct comp_ctx *comp_ctx);
int identity_end(struct comp_ctx *comp_ctx); int identity_end(struct comp_ctx **comp_ctx);
#ifdef USE_ZLIB #ifdef USE_ZLIB
int deflate_init(struct comp_ctx **comp_ctx, int level);
int deflate_init(struct comp_ctx *comp_ctx, int level);
int deflate_add_data(struct comp_ctx *comp_ctx, const char *in_data, int in_len, struct buffer *out); int deflate_add_data(struct comp_ctx *comp_ctx, const char *in_data, int in_len, struct buffer *out);
int deflate_flush(struct comp_ctx *comp_ctx, struct buffer *out, int flag); int deflate_flush(struct comp_ctx *comp_ctx, struct buffer *out, int flag);
int deflate_reset(struct comp_ctx *comp_ctx); int deflate_reset(struct comp_ctx *comp_ctx);
int deflate_end(struct comp_ctx *comp_ctx); int deflate_end(struct comp_ctx **comp_ctx);
int gzip_init(struct comp_ctx *comp_ctx, int level); int gzip_init(struct comp_ctx **comp_ctx, int level);
#endif /* USE_ZLIB */ #endif /* USE_ZLIB */
#endif /* _PROTO_COMP_H */ #endif /* _PROTO_COMP_H */

View File

@ -50,11 +50,11 @@ struct comp_ctx {
struct comp_algo { struct comp_algo {
char *name; char *name;
int name_len; int name_len;
int (*init)(struct comp_ctx *comp_ctx, int level); int (*init)(struct comp_ctx **comp_ctx, int level);
int (*add_data)(struct comp_ctx *comp_ctx, const char *in_data, int in_len, struct buffer *out); int (*add_data)(struct comp_ctx *comp_ctx, const char *in_data, int in_len, struct buffer *out);
int (*flush)(struct comp_ctx *comp_ctx, struct buffer *out, int flag); int (*flush)(struct comp_ctx *comp_ctx, struct buffer *out, int flag);
int (*reset)(struct comp_ctx *comp_ctx); int (*reset)(struct comp_ctx *comp_ctx);
int (*end)(struct comp_ctx *comp_ctx); int (*end)(struct comp_ctx **comp_ctx);
struct comp_algo *next; struct comp_algo *next;
}; };

View File

@ -159,7 +159,7 @@ struct session {
void (*srv_error)(struct session *s, /* the function to call upon unrecoverable server errors (or NULL) */ void (*srv_error)(struct session *s, /* the function to call upon unrecoverable server errors (or NULL) */
struct stream_interface *si); struct stream_interface *si);
unsigned int uniq_id; /* unique ID used for the traces */ unsigned int uniq_id; /* unique ID used for the traces */
struct comp_ctx comp_ctx; /* HTTP compression context */ struct comp_ctx *comp_ctx; /* HTTP compression context */
struct comp_algo *comp_algo; /* HTTP compression algorithm if not NULL */ struct comp_algo *comp_algo; /* HTTP compression algorithm if not NULL */
char *unique_id; /* custom unique ID */ char *unique_id; /* custom unique ID */
}; };

View File

@ -5442,7 +5442,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
if (!strcmp(args[1], "algo")) { if (!strcmp(args[1], "algo")) {
int cur_arg; int cur_arg;
struct comp_ctx ctx; struct comp_ctx *ctx;
cur_arg = 2; cur_arg = 2;
if (!*args[cur_arg]) { if (!*args[cur_arg]) {

View File

@ -37,6 +37,9 @@
#ifdef USE_ZLIB #ifdef USE_ZLIB
static void *alloc_zlib(void *opaque, unsigned int items, unsigned int size);
static void free_zlib(void *opaque, void *ptr);
/* zlib allocation */ /* zlib allocation */
static struct pool_head *zlib_pool_deflate_state = NULL; static struct pool_head *zlib_pool_deflate_state = NULL;
static struct pool_head *zlib_pool_window = NULL; static struct pool_head *zlib_pool_window = NULL;
@ -46,9 +49,10 @@ static struct pool_head *zlib_pool_pending_buf = NULL;
static long long zlib_memory_available = -1; static long long zlib_memory_available = -1;
#endif #endif
static struct pool_head *pool_comp_ctx = NULL;
const struct comp_algo comp_algos[] = const struct comp_algo comp_algos[] =
{ {
@ -187,15 +191,15 @@ int http_compression_buffer_add_data(struct session *s, struct buffer *in, struc
left = data_process_len - bi_contig_data(in); left = data_process_len - bi_contig_data(in);
if (left <= 0) { if (left <= 0) {
consumed_data += ret = s->comp_algo->add_data(&s->comp_ctx, bi_ptr(in), data_process_len, out); consumed_data += ret = s->comp_algo->add_data(s->comp_ctx, bi_ptr(in), data_process_len, out);
if (ret < 0) if (ret < 0)
return -1; return -1;
} else { } else {
consumed_data += ret = s->comp_algo->add_data(&s->comp_ctx, bi_ptr(in), bi_contig_data(in), out); consumed_data += ret = s->comp_algo->add_data(s->comp_ctx, bi_ptr(in), bi_contig_data(in), out);
if (ret < 0) if (ret < 0)
return -1; return -1;
consumed_data += ret = s->comp_algo->add_data(&s->comp_ctx, in->data, left, out); consumed_data += ret = s->comp_algo->add_data(s->comp_ctx, in->data, left, out);
if (ret < 0) if (ret < 0)
return -1; return -1;
} }
@ -223,9 +227,9 @@ int http_compression_buffer_end(struct session *s, struct buffer **in, struct bu
/* flush data here */ /* flush data here */
if (end) if (end)
ret = s->comp_algo->flush(&s->comp_ctx, ob, Z_FINISH); /* end of data */ ret = s->comp_algo->flush(s->comp_ctx, ob, Z_FINISH); /* end of data */
else else
ret = s->comp_algo->flush(&s->comp_ctx, ob, Z_SYNC_FLUSH); /* end of buffer */ ret = s->comp_algo->flush(s->comp_ctx, ob, Z_SYNC_FLUSH); /* end of buffer */
if (ret < 0) if (ret < 0)
return -1; /* flush failed */ return -1; /* flush failed */
@ -257,9 +261,8 @@ int http_compression_buffer_end(struct session *s, struct buffer **in, struct bu
} }
to_forward = ob->i; to_forward = ob->i;
/* update input rate */ /* update input rate */
if (s->comp_ctx.cur_lvl > 0) if (s->comp_ctx && s->comp_ctx->cur_lvl > 0)
update_freq_ctr(&global.comp_bps_in, ib->o - ob->o); update_freq_ctr(&global.comp_bps_in, ib->o - ob->o);
/* copy the remaining data in the tmp buffer. */ /* copy the remaining data in the tmp buffer. */
@ -277,7 +280,7 @@ int http_compression_buffer_end(struct session *s, struct buffer **in, struct bu
*in = ob; *in = ob;
*out = ib; *out = ib;
if (s->comp_ctx.cur_lvl > 0) if (s->comp_ctx && s->comp_ctx->cur_lvl > 0)
update_freq_ctr(&global.comp_bps_out, to_forward); update_freq_ctr(&global.comp_bps_out, to_forward);
/* forward the new chunk without remaining data */ /* forward the new chunk without remaining data */
@ -290,6 +293,56 @@ int http_compression_buffer_end(struct session *s, struct buffer **in, struct bu
return to_forward; return to_forward;
} }
/*
* Alloc the comp_ctx
*/
static inline int init_comp_ctx(struct comp_ctx **comp_ctx)
{
#ifdef USE_ZLIB
z_stream *strm;
if (global.maxzlibmem > 0 && zlib_memory_available < 0)
zlib_memory_available = global.maxzlibmem * 1024 * 1024; /* Megabytes to bytes */
if (global.maxzlibmem > 0 && zlib_memory_available < sizeof(struct comp_ctx))
return -1;
#endif
if (unlikely(pool_comp_ctx == NULL))
pool_comp_ctx = create_pool("comp_ctx", sizeof(struct comp_ctx), MEM_F_SHARED);
*comp_ctx = pool_alloc2(pool_comp_ctx);
if (*comp_ctx == NULL)
return -1;
#ifdef USE_ZLIB
zlib_memory_available -= sizeof(struct comp_ctx);
strm = &(*comp_ctx)->strm;
strm->zalloc = alloc_zlib;
strm->zfree = free_zlib;
strm->opaque = *comp_ctx;
#endif
return 0;
}
/*
* Dealloc the comp_ctx
*/
static inline int deinit_comp_ctx(struct comp_ctx **comp_ctx)
{
if (!*comp_ctx)
return 0;
pool_free2(pool_comp_ctx, *comp_ctx);
*comp_ctx = NULL;
#ifdef USE_ZLIB
zlib_memory_available += sizeof(struct comp_ctx);
#endif
return 0;
}
/**************************** /****************************
**** Identity algorithm **** **** Identity algorithm ****
@ -298,7 +351,7 @@ int http_compression_buffer_end(struct session *s, struct buffer **in, struct bu
/* /*
* Init the identity algorithm * Init the identity algorithm
*/ */
int identity_init(struct comp_ctx *comp_ctx, int level) int identity_init(struct comp_ctx **comp_ctx, int level)
{ {
return 0; return 0;
} }
@ -336,7 +389,7 @@ int identity_reset(struct comp_ctx *comp_ctx)
/* /*
* Deinit the algorithm * Deinit the algorithm
*/ */
int identity_end(struct comp_ctx *comp_ctx) int identity_end(struct comp_ctx **comp_ctx)
{ {
return 0; return 0;
} }
@ -425,41 +478,47 @@ static void free_zlib(void *opaque, void *ptr)
zlib_memory_available += pool->size; zlib_memory_available += pool->size;
} }
/************************** /**************************
**** gzip algorithm **** **** gzip algorithm ****
***************************/ ***************************/
int gzip_init(struct comp_ctx *comp_ctx, int level) int gzip_init(struct comp_ctx **comp_ctx, int level)
{ {
z_stream *strm = &comp_ctx->strm; z_stream *strm;
if (global.maxzlibmem > 0 && zlib_memory_available < 0) if (init_comp_ctx(comp_ctx) < 0)
zlib_memory_available = global.maxzlibmem * 1024 * 1024; /* Megabytes to bytes */
strm->zalloc = alloc_zlib;
strm->zfree = free_zlib;
strm->opaque = comp_ctx;
if (deflateInit2(&comp_ctx->strm, level, Z_DEFLATED, global.tune.zlibwindowsize + 16, global.tune.zlibmemlevel, Z_DEFAULT_STRATEGY) != Z_OK)
return -1; return -1;
strm = &(*comp_ctx)->strm;
if (deflateInit2(strm, level, Z_DEFLATED, global.tune.zlibwindowsize + 16, global.tune.zlibmemlevel, Z_DEFAULT_STRATEGY) != Z_OK) {
deinit_comp_ctx(comp_ctx);
return -1;
}
(*comp_ctx)->cur_lvl = level;
return 0; return 0;
} }
/************************** /**************************
**** Deflate algorithm **** **** Deflate algorithm ****
***************************/ ***************************/
int deflate_init(struct comp_ctx *comp_ctx, int level) int deflate_init(struct comp_ctx **comp_ctx, int level)
{ {
z_stream *strm = &comp_ctx->strm; z_stream *strm;
strm->zalloc = alloc_zlib; if (init_comp_ctx(comp_ctx) < 0)
strm->zfree = free_zlib;
strm->opaque = comp_ctx;
if (deflateInit(&comp_ctx->strm, level) != Z_OK)
return -1; return -1;
strm = &(*comp_ctx)->strm;
if (deflateInit(strm, level) != Z_OK) {
deinit_comp_ctx(comp_ctx);
return -1;
}
(*comp_ctx)->cur_lvl = level;
return 0; return 0;
} }
@ -538,14 +597,16 @@ int deflate_reset(struct comp_ctx *comp_ctx)
return -1; return -1;
} }
int deflate_end(struct comp_ctx *comp_ctx) int deflate_end(struct comp_ctx **comp_ctx)
{ {
z_stream *strm = &comp_ctx->strm; z_stream *strm = &(*comp_ctx)->strm;
int ret;
if (deflateEnd(strm) != Z_OK) ret = deflateEnd(strm);
return -1;
return 0; deinit_comp_ctx(comp_ctx);
return ret;
} }
#endif /* USE_ZLIB */ #endif /* USE_ZLIB */

View File

@ -2105,8 +2105,6 @@ int select_compression_response_header(struct session *s, struct buffer *res)
s->flags |= SN_COMP_READY; s->flags |= SN_COMP_READY;
s->comp_ctx.cur_lvl = global.tune.comp_maxlevel;
/* remove Content-Length header */ /* remove Content-Length header */
if ((msg->flags & HTTP_MSGF_CNT_LEN) && http_find_header2("Content-Length", 14, res->p, &txn->hdr_idx, &ctx)) if ((msg->flags & HTTP_MSGF_CNT_LEN) && http_find_header2("Content-Length", 14, res->p, &txn->hdr_idx, &ctx))
http_remove_header2(msg, &txn->hdr_idx, &ctx); http_remove_header2(msg, &txn->hdr_idx, &ctx);