On Thursday 18 October 2007, Philippe M. Chiasson wrote:
> Any chance you can break the patch into multiple patches

This one makes PerlInterpScope more advisory. Using pnotes increment the 
refcnt of the interp thus binding it to the lifetime of the pnotes. So, using 
$c->pnotes binds the interp to the lifetime of the connection, $r->pnotes to 
the request lifetime.

$[rc]->pnotes_kill() can be used to prematurely drop pnotes and thus remove 
the binding.

Torsten
Index: src/modules/perl/modperl_types.h
===================================================================
--- src/modules/perl/modperl_types.h	(revision 5)
+++ src/modules/perl/modperl_types.h	(working copy)
@@ -246,6 +246,14 @@
 
 typedef struct {
     HV *pnotes;
+    apr_pool_t *pool;
+#ifdef USE_ITHREADS
+    modperl_interp_t *interp;
+#endif
+} modperl_pnotes_t;
+
+typedef struct {
+    modperl_pnotes_t pnotes;
     SV *global_request_obj;
     U8 flags;
     int status;
@@ -253,13 +261,10 @@
     MpAV *handlers_per_dir[MP_HANDLER_NUM_PER_DIR];
     MpAV *handlers_per_srv[MP_HANDLER_NUM_PER_SRV];
     modperl_perl_globals_t perl_globals;
-#ifdef USE_ITHREADS
-    modperl_interp_t *interp;
-#endif
 } modperl_config_req_t;
 
 struct modperl_config_con_t {
-    HV *pnotes;
+    modperl_pnotes_t pnotes;
 #ifdef USE_ITHREADS
     modperl_interp_t *interp;
 #endif
Index: src/modules/perl/modperl_util.c
===================================================================
--- src/modules/perl/modperl_util.c	(revision 7)
+++ src/modules/perl/modperl_util.c	(working copy)
@@ -829,49 +829,56 @@
     return data ? *(int *)data : 0;
  }
 
-#ifdef USE_ITHREADS
-typedef struct {
-    HV **pnotes;
-    PerlInterpreter *perl;
-} modperl_cleanup_pnotes_data_t;
-#endif
- 
 static MP_INLINE
 apr_status_t modperl_cleanup_pnotes(void *data) {
-    HV **pnotes = data;
+    modperl_pnotes_t *pnotes = data;
 
-    if (*pnotes) {
+    ap_assert(pnotes);
 #ifdef USE_ITHREADS
-        modperl_cleanup_pnotes_data_t *cleanup_data = data;
-        dTHXa(cleanup_data->perl);
-        pnotes = cleanup_data->pnotes;
-#else
-        pnotes = data;
+    {
+        dTHXa(pnotes->interp->perl);
 #endif
-        SvREFCNT_dec(*pnotes);
-        *pnotes = Nullhv;
+	SvREFCNT_dec(pnotes->pnotes);
+	pnotes->pnotes = NULL;
+	pnotes->pool = NULL;
+#ifdef USE_ITHREADS
+	MP_TRACE_i(MP_FUNC, "DO: calling interp_unselect(0x%lx)\n",
+		   pnotes->interp);
+	modperl_interp_unselect(pnotes->interp);
+	pnotes->interp = NULL;
     }
+#endif
 
     return APR_SUCCESS;   
 }
 
-SV *modperl_pnotes(pTHX_ HV **pnotes, SV *key, SV *val, 
-                   request_rec *r, conn_rec *c) {
+void modperl_pnotes_kill(void *data) {
+    modperl_pnotes_t *pnotes = data;
+
+    ap_assert(pnotes);
+
+    if( !pnotes->pnotes ) return;
+
+    apr_pool_cleanup_kill(pnotes->pool, pnotes, modperl_cleanup_pnotes);
+    modperl_cleanup_pnotes(pnotes);
+}
+
+SV *modperl_pnotes(pTHX_ modperl_pnotes_t *pnotes, SV *key, SV *val, 
+		   apr_pool_t *pool) {
     SV *retval = Nullsv;
 
-    if (!*pnotes) {
-        *pnotes = newHV();
-
-	apr_pool_t *pool = r ? r->pool : c->pool;
+    if (!pnotes->pnotes) {
+	pnotes->pool=pool;
 #ifdef USE_ITHREADS
-	modperl_cleanup_pnotes_data_t *cleanup_data = 
-            apr_palloc(pool, sizeof(*cleanup_data));
-	cleanup_data->pnotes = pnotes;
-	cleanup_data->perl = aTHX;
-#else
-	void *cleanup_data = pnotes;
+	pnotes->interp=MP_THX_INTERP_GET(aTHX);
+        pnotes->interp->refcnt++;
+        MP_TRACE_i(MP_FUNC, "TO: (0x%lx)->refcnt incremented to %ld\n",
+		   pnotes->interp, pnotes->interp->refcnt);
 #endif
-	apr_pool_cleanup_register(pool, cleanup_data,
+
+	pnotes->pnotes=newHV();
+
+	apr_pool_cleanup_register(pool, pnotes,
 				  modperl_cleanup_pnotes,
 				  apr_pool_cleanup_null);
     }
@@ -881,14 +888,14 @@
         char *k = SvPV(key, len);
 
         if (val) {
-            retval = *hv_store(*pnotes, k, len, SvREFCNT_inc(val), 0);
+            retval = *hv_store(pnotes->pnotes, k, len, SvREFCNT_inc(val), 0);
         }
-        else if (hv_exists(*pnotes, k, len)) {
-            retval = *hv_fetch(*pnotes, k, len, FALSE);
+        else if (hv_exists(pnotes->pnotes, k, len)) {
+            retval = *hv_fetch(pnotes->pnotes, k, len, FALSE);
         }
 
         return retval ? SvREFCNT_inc(retval) : &PL_sv_undef;
     }
-    return newRV_inc((SV *)*pnotes);
+    return newRV_inc((SV *)pnotes->pnotes);
 }
  
Index: src/modules/perl/modperl_util.h
===================================================================
--- src/modules/perl/modperl_util.h	(revision 2)
+++ src/modules/perl/modperl_util.h	(working copy)
@@ -134,7 +134,9 @@
 void modperl_restart_count_inc(server_rec *base_server);
 int  modperl_restart_count(void);
 
-SV *modperl_pnotes(pTHX_ HV **pnotes, SV *key, SV *val,
-                   request_rec *r, conn_rec *c);
+void modperl_pnotes_kill(void *data);
 
+SV *modperl_pnotes(pTHX_ modperl_pnotes_t *pnotes, SV *key, SV *val,
+		   apr_pool_t *pool );
+
 #endif /* MODPERL_UTIL_H */
Index: xs/Apache2/RequestUtil/Apache2__RequestUtil.h
===================================================================
--- xs/Apache2/RequestUtil/Apache2__RequestUtil.h	(revision 2)
+++ xs/Apache2/RequestUtil/Apache2__RequestUtil.h	(working copy)
@@ -218,9 +218,21 @@
         return &PL_sv_undef;
     }
 
-    return modperl_pnotes(aTHX_ &rcfg->pnotes, key, val, r, NULL);
+    return modperl_pnotes(aTHX_ &rcfg->pnotes, key, val, r->pool);
 }
 
+static MP_INLINE
+void mpxs_Apache2__RequestRec_pnotes_kill(pTHX_ request_rec *r)
+{
+    MP_dRCFG;
+
+    if (!rcfg) {
+        return;
+    }
+
+    modperl_pnotes_kill(&rcfg->pnotes);
+}
+
 #define mpxs_Apache2__RequestRec_dir_config(r, key, sv_val) \
     modperl_dir_config(aTHX_ r, r->server, key, sv_val)
 
Index: xs/Apache2/ConnectionUtil/Apache2__ConnectionUtil.h
===================================================================
--- xs/Apache2/ConnectionUtil/Apache2__ConnectionUtil.h	(revision 2)
+++ xs/Apache2/ConnectionUtil/Apache2__ConnectionUtil.h	(working copy)
@@ -25,5 +25,19 @@
         return &PL_sv_undef;
     }
     
-    return modperl_pnotes(aTHX_ &ccfg->pnotes, key, val, NULL, c);
+    return modperl_pnotes(aTHX_ &ccfg->pnotes, key, val, c->pool);
 }
+
+static MP_INLINE
+void mpxs_Apache2__Connection_pnotes_kill(pTHX_ conn_rec *c)
+{
+    MP_dCCFG;
+
+    modperl_config_con_init(c, ccfg);
+
+    if (!ccfg) {
+        return;
+    }
+
+    modperl_pnotes_kill(&ccfg->pnotes);
+}

Attachment: signature.asc
Description: This is a digitally signed message part.

Reply via email to