On Sun, 17 Sep 2000, Matt Sergeant wrote:

> On Sun, 17 Sep 2000, Alexander Farber (EED) wrote:
> 
> > Matt Sergeant wrote:
> > > > > #     my @vary = $r->header_out('Vary') if $r->header_out('Vary');
> > > > > #     push @vary, "Accept-Encoding", "User-Agent";
> > > 
> > > I think its a mod_perl bug. There's nothing leaky in the perl here.
> > 
> > Isn't it the same as
> > http://www.perl.com/pub/2000/05/p5pdigest/THISWEEK-20000521.html#my_x_if_0;_Trick
> 
> Nice catch!
> 
> Yes it is the same. Thats good news for Doug :-)

good news that i don't need to debug that, better news that i'm not the
sole cause of your leak hunting ;)
there is also a leak in DIR_MERGE, which the patch below should fix.
notice perl_perl_cmd_cleanup() has been removed, it was never being
called, argh.  mod_perl_cleanup_sv() does the same, without as much
tracing, but a directive handler class DESTROY method can add more trace
info if desired.  this patch also renames mod_perl_cleanup_av to
mod_perl_cleanup_sv, since _av was just casting to an SV* anyhow.

Index: src/modules/perl/perl_config.c
===================================================================
RCS file: /home/cvs/modperl/src/modules/perl/perl_config.c,v
retrieving revision 1.101
diff -u -r1.101 perl_config.c
--- src/modules/perl/perl_config.c      2000/08/15 19:36:33     1.101
+++ src/modules/perl/perl_config.c      2000/09/22 18:04:14
@@ -436,7 +436,7 @@
     sva = newSVpv(arg,0); 
     if(!*cmd) { 
         *cmd = newAV(); 
-       register_cleanup(p, (void*)*cmd, mod_perl_cleanup_av, mod_perl_noop);
+       register_cleanup(p, (void*)*cmd, mod_perl_cleanup_sv, mod_perl_noop);
        MP_TRACE_d(fprintf(stderr, "init `%s' stack\n", hook)); 
     } 
     MP_TRACE_d(fprintf(stderr, "perl_cmd_push_handlers: @%s, '%s'\n", hook, arg)); 
@@ -823,13 +823,13 @@
     return NULL;
 }
 
-void mod_perl_cleanup_av(void *data)
+void mod_perl_cleanup_sv(void *data)
 {
-    AV *av = (AV*)data;
-    if(SvREFCNT((SV*)av)) {
-       MP_TRACE_g(fprintf(stderr, "cleanup_av: SvREFCNT(0x%lx)==%d\n", 
-                          (unsigned long)av, (int)SvREFCNT((SV*)av)));
-       SvREFCNT_dec((SV*)av);
+    SV *sv = (SV*)data;
+    if (SvREFCNT(sv)) {
+        MP_TRACE_g(fprintf(stderr, "cleanup_sv: SvREFCNT(0x%lx)==%d\n",
+                           (unsigned long)sv, (int)SvREFCNT(sv)));
+        SvREFCNT_dec(sv);
     }
 }
 
@@ -895,6 +895,8 @@
        if((perl_eval_ok(parms ? parms->server : NULL) == OK) && (count == 1)) {
            *sv = POPs;
            ++SvREFCNT(*sv);
+            register_cleanup(parms->pool, (void*)*sv,
+                             mod_perl_cleanup_sv, mod_perl_noop);
        }
        PUTBACK;
        FREETMPS;LEAVE;
@@ -905,6 +907,8 @@
        /* return bless {}, $class */
        if(!SvTRUE(*sv)) {
            *sv = newRV_noinc((SV*)newHV());
+            register_cleanup(parms->pool, (void*)*sv,
+                             mod_perl_cleanup_sv, mod_perl_noop);
            return sv_bless(*sv, pclass);
        }
        else
@@ -929,7 +933,7 @@
        *basevp = (mod_perl_perl_dir_config *)basev,
        *addvp  = (mod_perl_perl_dir_config *)addv;
 
-    SV *sv, 
+    SV *sv=Nullsv, 
        *basesv = basevp ? basevp->obj : Nullsv,
        *addsv  = addvp  ? addvp->obj  : Nullsv;
 
@@ -958,16 +962,22 @@
        if((perl_eval_ok(NULL) == OK) && (count == 1)) {
            sv = POPs;
            ++SvREFCNT(sv);
-           mrg->obj = sv;
            mrg->pclass = SvCLASS(sv);
        }
        PUTBACK;
        FREETMPS;LEAVE;
     }
     else {
-       mrg->obj = newSVsv(basesv);
-       mrg->pclass = basevp->pclass;
+        sv = newSVsv(basesv);
+        mrg->pclass = basevp->pclass;
     }
+
+    if (sv) {
+        mrg->obj = sv;
+        register_cleanup(p, (void*)sv,
+                         mod_perl_cleanup_sv, mod_perl_noop);
+    }
+
     return (void *)mrg;
 }
 
@@ -979,18 +989,6 @@
 void *perl_perl_merge_srv_config(pool *p, void *basev, void *addv)
 {
     return perl_perl_merge_cfg(p, basev, addv, PERL_SERVER_MERGE);
-}
-
-void perl_perl_cmd_cleanup(void *data)
-{
-    mod_perl_perl_dir_config *cld = (mod_perl_perl_dir_config *)data;
-
-    if(cld->obj) {
-       MP_TRACE_c(fprintf(stderr, 
-                          "cmd_cleanup: SvREFCNT($%s::$obj) == %d\n",
-                          cld->pclass, (int)SvREFCNT(cld->obj)));
-       SvREFCNT_dec(cld->obj);
-    }
 }
 
 CHAR_P perl_cmd_perl_TAKE123(cmd_parms *cmd, mod_perl_perl_dir_config *data,
Index: src/modules/perl/mod_perl.h
===================================================================
RCS file: /home/cvs/modperl/src/modules/perl/mod_perl.h,v
retrieving revision 1.102
diff -u -r1.102 mod_perl.h
--- src/modules/perl/mod_perl.h 2000/08/15 19:36:33     1.102
+++ src/modules/perl/mod_perl.h 2000/09/22 18:04:26
@@ -1132,7 +1132,7 @@
 void perl_setup_env(request_rec *r);
 SV  *perl_bless_request_rec(request_rec *); 
 void perl_set_request_rec(request_rec *); 
-void mod_perl_cleanup_av(void *data);
+void mod_perl_cleanup_sv(void *data);
 void mod_perl_cleanup_handler(void *data);
 void mod_perl_end_cleanup(void *data);
 void mod_perl_register_cleanup(request_rec *r, SV *sv);
@@ -1192,7 +1192,6 @@
 void *perl_create_dir_config(pool *p, char *dirname);
 void *perl_create_server_config(pool *p, server_rec *s);
 perl_request_config *perl_create_request_config(pool *p, server_rec *s);
-void perl_perl_cmd_cleanup(void *data);
 
 void perl_section_self_boot(cmd_parms *parms, void *dummy, const char *arg);
 CHAR_P perl_section (cmd_parms *cmd, void *dummy, CHAR_P arg);

Reply via email to