httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Doug MacEachern <do...@opengroup.org>
Subject Re: mod_perl and exit
Date Sat, 02 Aug 1997 23:33:07 GMT
With the patch below, mod_perl's exit() will jump out of a callback
without the C-level exit.
I show you this patch for two reasons.  First, to give you an idea of
why I put this off for so long.  Two, and more import, now that I can
jump out of a callback and maintain Perl interpreter sanity, how
should I terminate the child process?  Is there a need for some kind
of child_done() routine?  Or a new handler return code, say
`TERMINATE' which tells httpd to finish up logging, protocol,
child_exit, etc.?  I know I could hack something together that would
do for now, but I think it would make sense to have a one-step
function or return code so modules who need to shutdown a child don't
have to be tracking future additions to the post-handler stages of a
request. 

Actually, I'd be happy to leave the way it is and not do a C-level
exit, but then I'm taking away Rob's "recover memory" trick, do you
still use that Rob?   

-Doug

--- 1.59	1997/07/29 02:11:12
+++ Apache.xs	1997/08/02 23:11:02
@@ -54,12 +54,110 @@
 
 /* $Id: Apache.xs,v 1.59 1997/07/29 02:11:12 dougm Exp dougm $ */
 
+static I32
+my_dopoptoeval(I32 startingblock)
+{
+    I32 i;
+    register CONTEXT *cx;
+    for (i = startingblock; i >= 0; i--) {
+	cx = &cxstack[i];
+	switch (cx->cx_type) {
+	default:
+	    continue;
+	case CXt_EVAL:
+	    return i;
+	}
+    }
+    return i;
+}
+
+static void
+my_context_unwind(void)
+{
+    register CONTEXT *cx;
+    I32 gimme;
+    SV **newsp;
+
+    if (cxstack_ix >= 0) {
+	if (cxstack_ix > 0)
+	    dounwind(0);
+	POPBLOCK(cx,curpm);
+	LEAVE;
+    }
+
+    JMPENV_JUMP(2);
+}
+
+static OP *
+my_exit_jump(void)
+{
+
+    if (in_eval) {
+	I32 cxix;
+	register CONTEXT *cx;
+	I32 gimme;
+	SV **newsp;
+
+	cxix = my_dopoptoeval(cxstack_ix);
+	if (cxix >= 0) {
+	    I32 optype;
+
+	    if (cxix < cxstack_ix)
+		dounwind(cxix);
+
+	    POPBLOCK(cx,curpm);
+	    if (cx->cx_type != CXt_EVAL) {
+		PerlIO_printf(PerlIO_stderr(), "panic: huge mess!");
+	    }
+	    POPEVAL(cx);
+
+	    if (gimme == G_SCALAR)
+		*++newsp = &sv_undef;
+	    stack_sp = newsp;
+
+	    LEAVE;
+
+	    if (optype == OP_REQUIRE) {
+		PerlIO_printf(PerlIO_stderr(), "panic: module shouldn't exit!");
+	    }
+	    return pop_return();
+	}
+    }
+
+    my_context_unwind();
+    /* NOTREACHED */
+    return Nullop;
+}
+
+static void
+perl_call_halt(void)
+{
+    I32 oldrunlevel = runlevel;
+    int was_in_eval = in_eval;
+
+    if (curstack != mainstack) {
+        dSP;
+        SWITCHSTACK(curstack, mainstack);
+    }
+
+    restartop = my_exit_jump();
+    if ((!restartop && was_in_eval) || oldrunlevel > 1)
+	JMPENV_JUMP(3);
+}
+

 MODULE = Apache  PACKAGE = Apache   PREFIX = mod_perl_
 
 PROTOTYPES: DISABLE
 
 BOOT:
-    items = items;
+    items = items; /*avoid warning*/ 
 
 int
 max_requests_per_child(...)
@@ -182,12 +279,14 @@
 	    sts = (int)SvIV(ST(0));
     }
 
-    bflush(r->connection->client);
-    bclose(r->connection->client);
-    /* make sure we log the transaction, etc. */
-    PERL_EXIT_CLEANUP;
+    perl_call_halt();
+
+#ifndef DONE
+#define DONE -2
+#endif
 
-    exit(sts);
+    if(sts != DONE)
+        /* something like just_die */
 
 #shutup AutoLoader
 void 




Mime
View raw message