croak("panic: magic_mutexfree");
MUTEX_DESTROY(MgMUTEXP(mg));
COND_DESTROY(MgCONDP(mg));
+ SvREFCNT_dec(sv);
return 0;
}
#endif /* USE_THREADS */
switch (o->op_type) {
case OP_ENTERSUB:
- if ((type == OP_DEFINED) &&
+ if ((type == OP_DEFINED || type == OP_LOCK) &&
!(o->op_flags & OPf_STACKED)) {
o->op_type = OP_RV2CV; /* entersub => rv2cv */
o->op_ppaddr = ppaddr[OP_RV2CV];
ck_null, /* egrent */
ck_null, /* getlogin */
ck_fun, /* syscall */
- ck_null, /* lock */
+ ck_rfun, /* lock */
};
#endif
syscall syscall ck_fun imst S L
# For multi-threading
-lock lock ck_null s S
+lock lock ck_rfun s S
PP(pp_lock)
{
dSP;
-#ifdef USE_THREADS
dTOPss;
+ SV *retsv = sv;
+#ifdef USE_THREADS
MAGIC *mg;
if (SvROK(sv))
DEBUG_L(PerlIO_printf(PerlIO_stderr(), "0x%lx: pp_lock lock 0x%lx\n",
(unsigned long)thr, (unsigned long)sv);)
MUTEX_UNLOCK(MgMUTEXP(mg));
+ SvREFCNT_inc(sv); /* keep alive until magic_mutexfree */
save_destructor(unlock_condpair, sv);
}
#endif /* USE_THREADS */
+ if (SvTYPE(retsv) == SVt_PVAV || SvTYPE(retsv) == SVt_PVHV
+ || SvTYPE(retsv) == SVt_PVCV) {
+ retsv = refto(retsv);
+ }
+ SETs(retsv);
RETURN;
}
DEBUG_L(PerlIO_printf(PerlIO_stderr(), "%p: pp_entersub lock %p\n",
thr, sv);)
MUTEX_UNLOCK(MgMUTEXP(mg));
+ SvREFCNT_inc(sv); /* Keep alive until magic_mutexfree */
save_destructor(unlock_condpair, sv);
}
MUTEX_LOCK(CvMUTEXP(cv));