You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@perl.apache.org by Geoffrey Young <ge...@modperlcookbook.org> on 2002/02/14 20:51:01 UTC

[1.3] per-connection cleanups

hi all...

  someone was asking the other day on IRC about per-connection
cleanups.  I figured that since ap_register_cleanup schedules stuff
based on pools that registering code based on the connection pool
would be easy enough, so I tried...

below is a patch that works.  it is pretty much stolen right from the
implementation of Apache::Server::register_cleanup() which allowed me
to do it quickly and with some assurances that the refcounting would
be ok :)

anyway, as I said, it works, but I'm trying to figure out how to keep
track of how to implement it.  now, if you call
$r->connection->register_cleanup(\&foo) it works but registers a
cleanup on each request of the connection, so once the connection is
closed your code gets run once for each request made during the
connection.

I thought about skipping registering the code if c->keepalives > 0,
but that would mean you only get one connection cleanup, period.

does it make sense to dig the name of the coderef out of the stash and
use that to monitor stuff - as in, you can only have one
Foo::Bar::cleanup registered?  I'm not sure how hard that would be,
but that's kinda the effect that would be interesting at least.

at any rate, I'm just playing around at this point, seeing if it could
be done :)

--Geoff



Index: Connection.xs
===================================================================
RCS file: /home/cvspublic/modperl/src/modules/perl/Connection.xs,v
retrieving revision 1.9
diff -u -r1.9 Connection.xs
--- Connection.xs       11 Apr 2000 16:38:27 -0000      1.9
+++ Connection.xs       14 Feb 2002 19:35:29 -0000
@@ -1,6 +1,38 @@
 #define CORE_PRIVATE 
 #include "mod_perl.h" 
 
+typedef struct {
+    request_rec *r;
+    SV *cv;
+    int refcnt;
+} conn_cleanup_t;
+
+static void conn_cleanup_handler(void *data)
+{
+    conn_cleanup_t *conn = (conn_cleanup_t*)data;
+    (void)acquire_mutex(mod_perl_mutex);
+    perl_call_handler(conn->cv, conn->r, Nullav);
+    if(conn->refcnt) SvREFCNT_dec(conn->cv);
+    (void)release_mutex(mod_perl_mutex);
+}
+
+static void ApacheConnection_register_cleanup(conn_rec *c, SV *cv)
+{
+    pool *p = c->pool;
+    server_rec *s = c->server;
+    conn_cleanup_t *conn = (conn_cleanup_t *)palloc(p,
sizeof(conn_cleanup_t));
+
+    conn->r = mp_fake_request_rec(s, p,
"Apache::Connection::register_cleanup");
+    conn->cv = cv;
+    if(SvREFCNT(conn->cv) == 1) {
+        conn->refcnt = 1;
+        SvREFCNT_inc(conn->cv);
+    }
+    else
+        conn->refcnt = 0;
+    register_cleanup(p, conn, conn_cleanup_handler, mod_perl_noop);
+}
+
 MODULE = Apache::Connection  PACKAGE = Apache::Connection
 
 PROTOTYPES: DISABLE
@@ -174,5 +206,14 @@
 #  int keptalive;              /* Did we use HTTP Keep-Alive? */
 #  int keepalives;             /* How many times have we used it? */
 #};
+
+
+void
+register_cleanup(conn, cv)
+    Apache::Connection conn
+    SV *cv
+
+    CODE:
+      ApacheConnection_register_cleanup(conn, cv);

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org
For additional commands, e-mail: dev-help@perl.apache.org