@@ -61,7 +61,7 @@ modperl_interp_t *modperl_interp_new(modperl_interp_pool_t *mip,
6161 clone_flags |= CLONEf_CLONE_HOST ;
6262#endif
6363
64-
64+ PERL_SET_CONTEXT ( perl );
6565 interp -> perl = perl_clone (perl , clone_flags );
6666 PERL_SET_CONTEXT (interp -> perl );
6767
@@ -85,7 +85,7 @@ modperl_interp_t *modperl_interp_new(modperl_interp_pool_t *mip,
8585 * are different things, although they use the same type.
8686 */
8787 if ((clone_flags & CLONEf_KEEP_PTR_TABLE )) {
88- dTHXa (interp -> perl );
88+ dTHXa (interp -> perl );
8989 ptr_table_free (PL_ptr_table );
9090 PL_ptr_table = NULL ;
9191 }
@@ -112,8 +112,6 @@ void modperl_interp_destroy(modperl_interp_t *interp)
112112 void * * handles ;
113113 dTHXa (interp -> perl );
114114
115- PERL_SET_CONTEXT (interp -> perl );
116-
117115 MP_TRACE_i (MP_FUNC , "interp == 0x%lx / perl: 0x%lx" ,
118116 (unsigned long )interp , (unsigned long )interp -> perl );
119117
@@ -249,12 +247,23 @@ void modperl_interp_init(server_rec *s, apr_pool_t *p,
249247 scfg -> mip = mip ;
250248}
251249
250+ static apr_status_t modperl_interp_pool_unselect (void * data )
251+ {
252+ modperl_interp_t * interp = (modperl_interp_t * )data ;
253+ if (interp -> refcnt > 1 ) {
254+ MP_TRACE_i (MP_FUNC , "BIZARRE REFCNT: unselect(interp=%pp): refcnt=%d" ,
255+ interp , interp -> refcnt );
256+ interp -> refcnt = 1 ;
257+ }
258+ return modperl_interp_unselect (data );
259+ }
260+
252261apr_status_t modperl_interp_unselect (void * data )
253262{
254263 modperl_interp_t * interp = (modperl_interp_t * )data ;
255264 modperl_interp_pool_t * mip = interp -> mip ;
256265 modperl_tipool_t * tipool = mip -> tipool ;
257-
266+
258267 MP_ASSERT (interp && MpInterpIN_USE (interp ) && interp -> refcnt > 0 );
259268 MP_TRACE_i (MP_FUNC , "unselect(interp=%pp): refcnt=%d" ,
260269 interp , interp -> refcnt );
@@ -274,8 +283,8 @@ apr_status_t modperl_interp_unselect(void *data)
274283 MpInterpIN_USE_Off (interp );
275284
276285 if (interp -> pool )
277- apr_pool_cleanup_kill (interp -> pool , interp , modperl_interp_unselect ), interp -> pool = NULL ;
278-
286+ apr_pool_cleanup_kill (interp -> pool , interp , modperl_interp_pool_unselect ), interp -> pool = NULL ;
287+
279288 modperl_thx_interp_set (interp -> perl , NULL );
280289#ifdef MP_DEBUG
281290 PERL_SET_CONTEXT (NULL );
@@ -305,7 +314,7 @@ apr_status_t modperl_interp_unselect(void *data)
305314
306315#define set_interp (p ) \
307316 (void)apr_pool_userdata_set((void *)interp, MP_INTERP_KEY, \
308- modperl_interp_unselect , \
317+ modperl_interp_pool_unselect , \
309318 p)
310319
311320modperl_interp_t * modperl_interp_pool_get (apr_pool_t * p )
@@ -321,6 +330,15 @@ void modperl_interp_pool_set(apr_pool_t *p,
321330 (void )apr_pool_userdata_set ((void * )interp , MP_INTERP_KEY , NULL , p );
322331}
323332
333+ modperl_interp_t * modperl_interp_pool_unset (apr_pool_t * p )
334+ {
335+ modperl_interp_t * interp = NULL ;
336+ get_interp (p );
337+ (void )apr_pool_userdata_set (NULL , MP_INTERP_KEY , NULL , p );
338+ return interp ;
339+ }
340+
341+
324342/*
325343 * used in the case where we don't have a request_rec or conn_rec,
326344 * such as for directive handlers per-{dir,srv} create and merge.
@@ -344,7 +362,7 @@ modperl_interp_t *modperl_interp_pool_select(apr_pool_t *p,
344362 modperl_init_vhost (s , p , NULL );
345363 if (!scfg -> mip ) {
346364 /* FIXME: We get here if global "server_rec" == s, scfg->mip
347- * is not created then. I'm not sure if that's bug or
365+ * is not created then. I'm not sure if that's bug or
348366 * bad/good design decicision. For now just return NULL.
349367 */
350368 return NULL ;
@@ -420,12 +438,13 @@ modperl_interp_t *modperl_interp_select(request_rec *r, conn_rec *c, server_rec
420438 return interp ;
421439 }
422440
423- if (r && !ap_is_initial_req (r ))
441+ if (!ap_is_initial_req (r ))
424442 r = r -> main ;
425-
443+
426444 p = r ? r -> pool : c ? c -> pool : NULL ;
427445
428446 if (r && !c ) c = r -> connection ;
447+
429448 if (c )
430449 ccfg = modperl_config_con_get (c );
431450
@@ -438,29 +457,19 @@ modperl_interp_t *modperl_interp_select(request_rec *r, conn_rec *c, server_rec
438457 PERL_SET_CONTEXT (interp -> perl );
439458 return interp ;
440459 }
441- #if 0
442- if (ccfg && ccfg -> interp ) {
443- ccfg -> interp -> refcnt ++ ;
444- MP_TRACE_i (MP_FUNC ,
445- "found interp 0x%lx in con config, refcnt incremented to %d" ,
446- (unsigned long )ccfg -> interp , ccfg -> interp -> refcnt );
447- PERL_SET_CONTEXT (interp -> perl );
448- return ccfg -> interp ;
449- }
450- #endif
460+
451461 MP_TRACE_i (MP_FUNC ,
452462 "fetching interp for %s:%d" , s -> server_hostname , s -> port );
453463 interp = modperl_interp_get (s );
454464 MP_TRACE_i (MP_FUNC , " --> got %pp (perl=%pp)" , interp , interp -> perl );
455465 ++ interp -> num_requests ; /* should only get here once per request */
456466 interp -> refcnt = 1 ;
457467
468+ PERL_SET_CONTEXT (interp -> perl );
458469 modperl_thx_interp_set (interp -> perl , interp );
459470
460- /* make sure ccfg is initialized */
471+ /* make sure ccfg/rcfg is initialized */
461472 modperl_config_con_init (c , ccfg );
462- if (r )
463- modperl_config_req_init (r , rcfg );
464473
465474 if (ccfg && ccfg -> interp == NULL )
466475 ccfg -> interp = interp ;
@@ -471,7 +480,22 @@ modperl_interp_t *modperl_interp_select(request_rec *r, conn_rec *c, server_rec
471480 "pulled interp %pp (perl=%pp) from mip, num_requests is %d" ,
472481 interp , interp -> perl , interp -> num_requests );
473482 if (p )
474- set_interp (p ), interp -> pool = p ;
483+ /* it is correct to bump the refcnt below, assuming mod_http2's h2_stream.c is patched:
484+
485+
486+ @@ -659,16 +659,16 @@ apr_status_t h2_stream_set_request_rec(h2_stream *stream,
487+ if (stream->rst_error) {
488+ return APR_ECONNRESET;
489+ }
490+ - status = h2_request_rcreate(&req, stream->pool, r,
491+ + status = h2_request_rcreate(&req, r->pool, r,
492+ &stream->session->hd_scratch);
493+ if (status == APR_SUCCESS) {
494+
495+
496+
497+ */
498+ interp -> refcnt ++ , set_interp (p ), interp -> pool = p ;
475499
476500 return interp ;
477501}
0 commit comments