#endif
#if VMG_MULTIPLICITY && defined(USE_ITHREADS) && defined(dMY_CXT) && defined(MY_CXT) && defined(START_MY_CXT) && defined(MY_CXT_INIT) && (defined(MY_CXT_CLONE) || defined(dMY_CXT_SV))
-# define VMG_THREADSAFE 1
+# ifndef VMG_THREADSAFE
+# define VMG_THREADSAFE 1
+# endif
# ifndef MY_CXT_CLONE
# define MY_CXT_CLONE \
dMY_CXT_SV; \
sv_setuv(my_cxt_sv, PTR2UV(my_cxtp))
# endif
#else
+# undef VMG_THREADSAFE
# define VMG_THREADSAFE 0
# undef dMY_CXT
# define dMY_CXT dNOOP
/* --- Error messages ------------------------------------------------------ */
-static const char vmg_invalid_wiz[] = "Invalid wizard object";
-static const char vmg_wrongargnum[] = "Wrong number of arguments";
-static const char vmg_argstorefailed[] = "Error while storing arguments";
+static const char vmg_invalid_wiz[] = "Invalid wizard object";
+static const char vmg_wrongargnum[] = "Wrong number of arguments";
/* --- Context-safe global data -------------------------------------------- */
svr = POPs;
if (SvOK(svr))
ret = (int) SvIV(svr);
+ if (SvROK(svr))
+ SvREFCNT_inc(svr);
+ else
+ svr = NULL;
PUTBACK;
FREETMPS;
LEAVE;
+ if (svr && !SvTEMP(svr))
+ sv_2mortal(svr);
+
if (chain) {
vmg_dispell_guard_new(*chain);
*chain = NULL;
MUTEX_DESTROY(&vmg_op_name_init_mutex);
MUTEX_DESTROY(&vmg_vtable_refcount_mutex);
- vmg_loaded = 0;
-
return;
}
static int vmg_global_teardown_free(pTHX_ SV *sv, MAGIC *mg) {
- vmg_global_teardown_late_locked();
+ VMG_LOADED_LOCK;
+
+ if (vmg_loaded == 0)
+ vmg_global_teardown_late_locked();
+
VMG_LOADED_UNLOCK;
return 0;
#endif /* VMG_THREADSAFE */
-static void vmg_teardown(pTHX_ void *interp) {
+static void vmg_teardown(pTHX_ void *param) {
dMY_CXT;
-#if VMG_MULTIPLICITY
- if (aTHX != interp)
- return;
-#endif
-
#if VMG_THREADSAFE
VMG_LOADED_LOCK;
- if (vmg_loaded <= 1) {
- assert(vmg_loaded == 1);
+ if (vmg_loaded == 1) {
+ vmg_loaded = 0;
if (vmg_destruct_level() == 0) {
vmg_global_teardown_late_locked();
- VMG_LOADED_UNLOCK;
} else {
if (!PL_strtab)
PL_strtab = newHV();
vmg_sv_magicext((SV *) PL_strtab, NULL, &vmg_global_teardown_vtbl, NULL, 0);
- /* Lock until vmg_global_teardown_free() is called */
}
} else {
+ assert(vmg_loaded > 1);
--vmg_loaded;
- VMG_LOADED_UNLOCK;
}
+
+ VMG_LOADED_UNLOCK;
#endif
if (MY_CXT.depth == 0 && MY_CXT.freed_tokens) {
#if VMG_THREADSAFE
VMG_LOADED_LOCK;
- if (vmg_loaded <= 0) {
- assert(vmg_loaded == 0);
+ if (vmg_loaded == 0) {
MUTEX_INIT(&vmg_vtable_refcount_mutex);
MUTEX_INIT(&vmg_op_name_init_mutex);
+ vmg_loaded = 1;
+ } else {
+ assert(vmg_loaded > 0);
+ ++vmg_loaded;
}
- ++vmg_loaded;
VMG_LOADED_UNLOCK;
#endif
newCONSTSUB(stash, "VMG_OP_INFO_NAME", newSVuv(VMG_OP_INFO_NAME));
newCONSTSUB(stash, "VMG_OP_INFO_OBJECT", newSVuv(VMG_OP_INFO_OBJECT));
-#if VMG_MULTIPLICITY
- call_atexit(vmg_teardown, aTHX);
-#else
call_atexit(vmg_teardown, NULL);
-#endif
return;
}