]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: compression: use pool for comp_ctx
authorWilliam Lallemand <wlallemand@exceliance.fr>
Fri, 16 Nov 2012 17:06:41 +0000 (18:06 +0100)
committerWilly Tarreau <w@1wt.eu>
Wed, 21 Nov 2012 00:56:47 +0000 (01:56 +0100)
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.

include/proto/compression.h
include/types/compression.h
include/types/session.h
src/cfgparse.c
src/compression.c
src/proto_http.c

index cfab62a07511a7e50d3833ab26786e9204b37cd1..1614eddfcd9e5d7e29a3e75ea17957d0033e30f7 100644 (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 */
index cf56e457b3b6a542d24c223cef318a6aca67d03b..e4b1f273d35e760c60f04b6928d722ba7fa88f1f 100644 (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;
 };
 
index 284b7e892bb62458d602b291c59b5416f70701f2..e0d3c2274f606f1aeea174507dd8e0c0c18f5b8a 100644 (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 */
 };
index 10fc4a644bd353189688d17b17ccbfe11159d5b4..d4b3d9182b4d3136bd24ce4641d034934f866e1f 100644 (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]) {
index 72c9996b931acd0d21405c395d09e732692ca359..c1e1afd7950f23f3d67be4a6f9b8c486c0921880 100644 (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,23 +478,24 @@ 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 */
+       if (init_comp_ctx(comp_ctx) < 0)
+               return -1;
 
-       strm->zalloc = alloc_zlib;
-       strm->zfree = free_zlib;
-       strm->opaque = comp_ctx;
+       strm = &(*comp_ctx)->strm;
 
-       if (deflateInit2(&comp_ctx->strm, level, Z_DEFLATED, global.tune.zlibwindowsize + 16, global.tune.zlibmemlevel, Z_DEFAULT_STRATEGY) != Z_OK)
+       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;
 }
@@ -449,16 +503,21 @@ int gzip_init(struct comp_ctx *comp_ctx, int level)
 **** 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 (init_comp_ctx(comp_ctx) < 0)
+               return -1;
+
+       strm = &(*comp_ctx)->strm;
 
-       if (deflateInit(&comp_ctx->strm, level) != Z_OK)
+       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 */
index e410b6dddc2f36882d4141cf236be68e2337461a..8588b50e5f4550a1da3b9471dc2da0369fa64d0a 100644 (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);