[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: 1.7 Performance via HTTP

From: Justin Erenkrantz <justin_at_erenkrantz.com>
Date: Thu, 12 May 2011 02:24:25 -0700

[ adding dev_at_httpd ]

On Thu, May 12, 2011 at 12:25 AM, Ivan Zhakov <ivan_at_visualsvn.com> wrote:
> On Thu, May 12, 2011 at 11:18, Justin Erenkrantz <justin_at_erenkrantz.com> wrote:
>> On Thu, May 12, 2011 at 12:16 AM, Ivan Zhakov <ivan_at_visualsvn.com> wrote:
>>> Unfortunately huge memory leak in mod_deflate/mod_dav prevents
>>> enabling gzip on compression on production servers, especially on
>>> Windows where single process mode is used:
>>> http://svn.haxx.se/dev/archive-2009-08/0274.shtml
>>
>> *shrug*
>>
>> Sounds like that would be a good thing to work on in either Dublin or
>> Berlin.  Again, the fix is pretty straightforward...  -- justin
>>
> It would be great! Since I'm not familiar with this part of codebase
> and cannot fix it myself.

This patch should fix the memory leak. As I mentioned in a follow-up,
we can discuss in Dublin or Berlin if there is a better way to solve
this dangling filter reference...but, this will do the trick and
should be back-portable to 2.2 (and 2.0 too, I guess). -- justin

Index: modules/filters/mod_deflate.c
===================================================================
--- modules/filters/mod_deflate.c (revision 1102210)
+++ modules/filters/mod_deflate.c (working copy)
@@ -303,6 +303,7 @@ typedef struct deflate_ctx_t
     unsigned char *validation_buffer;
     apr_size_t validation_buffer_length;
     int inflate_init;
+ int filter_init;
 } deflate_ctx;

 /* Number of validation bytes (CRC and length) after the compressed data */
@@ -445,6 +446,8 @@ static apr_status_t deflate_out_filter(ap_filter_t
         char *token;
         const char *encoding;

+ ctx = f->ctx = apr_pcalloc(r->pool, sizeof(*ctx));
+
         /*
          * Only work on main request, not subrequests,
          * that are not a 204 response with no content
@@ -563,7 +566,7 @@ static apr_status_t deflate_out_filter(ap_filter_t
          */

         if (r->status != HTTP_NOT_MODIFIED) {
- ctx = f->ctx = apr_pcalloc(r->pool, sizeof(*ctx));
+ ctx->filter_init = 1;
             ctx->bb = apr_brigade_create(r->pool, f->c->bucket_alloc);
             ctx->buffer = apr_palloc(r->pool, c->bufferSize);
             ctx->libz_end_func = deflateEnd;
@@ -583,6 +586,7 @@ static apr_status_t deflate_out_filter(ap_filter_t
                  * We are not able to init libz and pass data down the chain
                  * uncompressed.
                  */
+ ctx->filter_init = 0;
                 ap_remove_output_filter(f);
                 return ap_pass_brigade(f->next, bb);
             }
@@ -629,6 +633,11 @@ static apr_status_t deflate_out_filter(ap_filter_t
         /* initialize deflate output buffer */
         ctx->stream.next_out = ctx->buffer;
         ctx->stream.avail_out = c->bufferSize;
+ } else if (!ctx->filter_init) {
+ /* Hmm. We've run through the filter init before as we have a ctx,
+ * but we never initialized. We probably have a dangling ref. Bail.
+ */
+ return ap_pass_brigade(f->next, bb);
     }

     while (!APR_BRIGADE_EMPTY(bb))
Received on 2011-05-12 11:25:01 CEST

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.