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_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_flush(struct comp_ctx *comp_ctx, struct buffer *out, int flag);
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
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_flush(struct comp_ctx *comp_ctx, struct buffer *out, int flag);
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 /* _PROTO_COMP_H */

View File

@ -50,11 +50,11 @@ struct comp_ctx {
struct comp_algo {
char *name;
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 (*flush)(struct comp_ctx *comp_ctx, struct buffer *out, int flag);
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;
};

View File

@ -159,7 +159,7 @@ struct session {
void (*srv_error)(struct session *s, /* the function to call upon unrecoverable server errors (or NULL) */
struct stream_interface *si);
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 */
char *unique_id; /* custom unique ID */
};

View File

@ -5442,7 +5442,7 @@ stats_error_parsing:
if (!strcmp(args[1], "algo")) {
int cur_arg;
struct comp_ctx ctx;
struct comp_ctx *ctx;
cur_arg = 2;
if (!*args[cur_arg]) {

View File

@ -37,6 +37,9 @@
#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 */
static struct pool_head *zlib_pool_deflate_state = 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;
#endif
static struct pool_head *pool_comp_ctx = NULL;
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);
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)
return -1;
} 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)
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)
return -1;
}
@ -223,9 +227,9 @@ int http_compression_buffer_end(struct session *s, struct buffer **in, struct bu
/* flush data here */
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
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)
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;
/* 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);
/* 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;
*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);
/* 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;
}
/*
* 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 ****
@ -298,7 +351,7 @@ int http_compression_buffer_end(struct session *s, struct buffer **in, struct bu
/*
* 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;
}
@ -336,7 +389,7 @@ int identity_reset(struct comp_ctx *comp_ctx)
/*
* Deinit the algorithm
*/
int identity_end(struct comp_ctx *comp_ctx)
int identity_end(struct comp_ctx **comp_ctx)
{
return 0;
}
@ -425,41 +478,47 @@ static void free_zlib(void *opaque, void *ptr)
zlib_memory_available += pool->size;
}
/**************************
**** 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)
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)
if (init_comp_ctx(comp_ctx) < 0)
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;
}
/**************************
**** 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;
strm->zfree = free_zlib;
strm->opaque = comp_ctx;
if (deflateInit(&comp_ctx->strm, level) != Z_OK)
if (init_comp_ctx(comp_ctx) < 0)
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;
}
@ -538,14 +597,16 @@ int deflate_reset(struct comp_ctx *comp_ctx)
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)
return -1;
ret = deflateEnd(strm);
return 0;
deinit_comp_ctx(comp_ctx);
return ret;
}
#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->comp_ctx.cur_lvl = global.tune.comp_maxlevel;
/* remove Content-Length header */
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);