Skip to content

Commit 61760ea

Browse files
committed
interpreter-locks
1 parent eff1204 commit 61760ea

4 files changed

Lines changed: 33 additions & 19 deletions

File tree

src/modules/perl/modperl_interp.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ modperl_interp_t *modperl_interp_new(modperl_interp_pool_t *mip,
4848

4949
interp->mip = mip;
5050
interp->refcnt = 0;
51+
MUTEX_INIT(&interp->lock);
5152

5253
if (perl) {
5354
#ifdef MP_USE_GTOP
@@ -112,7 +113,7 @@ void modperl_interp_destroy(modperl_interp_t *interp)
112113
void **handles;
113114
dTHXa(interp->perl);
114115

115-
PERL_SET_CONTEXT(interp->perl);
116+
PERL_SET_CONTEXT(aTHX);
116117

117118
MP_TRACE_i(MP_FUNC, "interp == 0x%lx / perl: 0x%lx",
118119
(unsigned long)interp, (unsigned long)interp->perl);
@@ -124,11 +125,13 @@ void modperl_interp_destroy(modperl_interp_t *interp)
124125

125126
handles = modperl_xs_dl_handles_get(aTHX);
126127

127-
modperl_perl_destruct(interp->perl);
128+
modperl_perl_destruct(aTHX);
128129

129130
modperl_xs_dl_handles_close(handles);
130131

132+
MUTEX_DESTROY(&interp->lock);
131133
free(interp);
134+
132135
}
133136

134137
apr_status_t modperl_interp_cleanup(void *data)
@@ -257,6 +260,7 @@ static apr_status_t modperl_interp_pool_unselect(void *data)
257260
interp, interp->refcnt);
258261
interp->refcnt = 1;
259262
}
263+
interp->pool = NULL;
260264
return modperl_interp_unselect(data);
261265
}
262266

@@ -265,20 +269,22 @@ apr_status_t modperl_interp_unselect(void *data)
265269
modperl_interp_t *interp = (modperl_interp_t *)data;
266270
modperl_interp_pool_t *mip = interp->mip;
267271
modperl_tipool_t *tipool = mip->tipool;
268-
272+
MUTEX_LOCK(&interp->lock);
269273
MP_ASSERT(interp && MpInterpIN_USE(interp) && interp->refcnt > 0);
270274
MP_TRACE_i(MP_FUNC, "unselect(interp=%pp): refcnt=%d",
271275
interp, interp->refcnt);
272276

273277
if (--interp->refcnt > 0) {
274278
MP_TRACE_i(MP_FUNC, "interp=0x%lx, refcnt=%d -- interp still in use",
275279
(unsigned long)interp, interp->refcnt);
280+
MUTEX_UNLOCK(&interp->lock);
276281
return APR_SUCCESS;
277282
}
278283

279284
if (!MpInterpIN_USE(interp)){
280285
MP_TRACE_i(MP_FUNC, "interp=0x%pp, refcnt=%d -- interp already not in use",
281286
interp, interp->refcnt);
287+
MUTEX_UNLOCK(&interp->lock);
282288
return APR_SUCCESS;
283289
}
284290

@@ -301,6 +307,7 @@ apr_status_t modperl_interp_unselect(void *data)
301307
MP_TRACE_i(MP_FUNC, "interp=%pp freed, tipool(size=%ld, in_use=%ld)",
302308
interp, tipool->size, tipool->in_use);
303309
}
310+
MUTEX_UNLOCK(&interp->lock);
304311
return APR_SUCCESS;
305312
}
306313

@@ -450,9 +457,14 @@ modperl_interp_t *modperl_interp_select(request_rec *r, conn_rec *c, server_rec
450457
if (c)
451458
ccfg = modperl_config_con_get(c);
452459

460+
static perl_mutex lock = PTHREAD_MUTEX_INITIALIZER;
461+
MUTEX_LOCK(&lock);
453462
if (p && (interp = modperl_interp_pool_get(p)) && MpInterpIN_USE(interp)) {
463+
MUTEX_LOCK(&interp->lock);
464+
MUTEX_UNLOCK(&lock);
454465
interp->refcnt++;
455466
interp->num_requests++;
467+
MUTEX_UNLOCK(&interp->lock);
456468
MP_TRACE_i(MP_FUNC,
457469
"found interp 0x%lx (perl=0x%pp) in r->pool config, refcnt=%d",
458470
(unsigned long)interp, interp->perl, interp->refcnt);
@@ -463,6 +475,8 @@ modperl_interp_t *modperl_interp_select(request_rec *r, conn_rec *c, server_rec
463475
MP_TRACE_i(MP_FUNC,
464476
"fetching interp for %s:%d", s->server_hostname, s->port);
465477
interp = modperl_interp_get(s);
478+
MUTEX_LOCK(&interp->lock);
479+
MUTEX_UNLOCK(&lock);
466480
MP_TRACE_i(MP_FUNC, " --> got %pp (perl=%pp)", interp, interp->perl);
467481
++interp->num_requests; /* should only get here once per request */
468482
interp->refcnt = 1;
@@ -499,6 +513,7 @@ modperl_interp_t *modperl_interp_select(request_rec *r, conn_rec *c, server_rec
499513
*/
500514
interp->refcnt++, set_interp(p), interp->pool = p;
501515

516+
MUTEX_UNLOCK(&interp->lock);
502517
return interp;
503518
}
504519

src/modules/perl/modperl_tipool.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ void modperl_tipool_remove(modperl_tipool_t *tipool, modperl_list_t *listp)
248248
MP_TRACE_i(MP_FUNC, "removed 0x%lx (size=%d)",
249249
(unsigned long)listp, tipool->size);
250250

251+
free(listp);
251252
}
252253

253254
modperl_list_t *modperl_tipool_pop(modperl_tipool_t *tipool)
@@ -297,7 +298,6 @@ static void modperl_tipool_putback_base(modperl_tipool_t *tipool,
297298
int num_requests)
298299
{
299300
modperl_tipool_lock(tipool);
300-
301301
/* remove from busy list, add back to idle */
302302
/* XXX: option to sort list, e.g. on num_requests */
303303

@@ -335,18 +335,23 @@ static void modperl_tipool_putback_base(modperl_tipool_t *tipool,
335335
*/
336336
MANAGE_TIPOOL:
337337
if (tipool->func->tipool_destroy) {
338-
if (tipool->size - tipool->in_use > tipool->cfg->max_spare) {
338+
while (tipool->size - tipool->in_use > tipool->cfg->max_spare) {
339339
if (tipool->idle && tipool->idle->next) {
340-
MP_TRACE_i(MP_FUNC,
341-
"shrinking pool: max_spare=%d, %d of %d in use",
342-
tipool->cfg->max_spare, tipool->in_use,
343-
tipool->size);
344340
listp = modperl_list_last(tipool->idle->next);
345341
if (listp) {
342+
MP_TRACE_i(MP_FUNC,
343+
"shrinking pool: destroying 0x%lx, max_spare=%d, %d of %d in use",
344+
(unsigned long)listp->data, tipool->cfg->max_spare, tipool->in_use,
345+
tipool->size);
346+
void *data = listp->data;
346347
modperl_tipool_remove(tipool, listp);
347-
(*tipool->func->tipool_destroy)(tipool, tipool->data, listp->data);
348+
(*tipool->func->tipool_destroy)(tipool, tipool->data, data);
348349
}
350+
else
351+
break;
349352
}
353+
else
354+
break;
350355
}
351356
}
352357
if (tipool->func->tipool_rgrow) {

src/modules/perl/modperl_types.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,12 @@ struct modperl_interp_t {
6262
int num_requests;
6363
U8 flags;
6464
modperl_config_con_t *ccfg;
65-
int refcnt;
65+
volatile int refcnt;
6666
apr_pool_t *pool;
6767
#ifdef MP_TRACE
6868
unsigned long tid;
6969
#endif
70+
perl_mutex lock;
7071
};
7172

7273
typedef struct {

src/modules/perl/modperl_util.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
int modperl_require_module(pTHX_ const char *pv, int logfailure)
2020
{
2121
SV *sv;
22-
22+
PERL_SET_CONTEXT(aTHX);
2323
dSP;
2424
PUSHSTACKi(PERLSI_REQUIRE);
2525
ENTER;SAVETMPS;
@@ -835,14 +835,9 @@ apr_status_t modperl_cleanup_pnotes(void *data) {
835835

836836
dTHXa(pnotes->perl);
837837
MP_ASSERT_CONTEXT(aTHX);
838-
#ifdef USE_ITHREADS
839-
modperl_interp_t *interp = modperl_thx_interp_get(aTHX);
840-
interp->refcnt--;
841-
#endif
842838
SvREFCNT_dec(pnotes->pnotes);
843839
pnotes->pnotes = NULL;
844840
pnotes->pool = NULL;
845-
846841
return APR_SUCCESS;
847842
}
848843

@@ -867,8 +862,6 @@ SV *modperl_pnotes(pTHX_ modperl_pnotes_t *pnotes, SV *key, SV *val,
867862
apr_pool_cleanup_null);
868863
#ifdef USE_ITHREADS
869864
pnotes->perl = aTHX;
870-
modperl_interp_t *interp = modperl_thx_interp_get(aTHX);
871-
interp->refcnt++;
872865
#endif
873866
}
874867

0 commit comments

Comments
 (0)