#define PL_Gtimesbase (my_vars->Gtimesbase)
#define PL_use_safe_putenv (my_vars->Guse_safe_putenv)
#define PL_Guse_safe_putenv (my_vars->Guse_safe_putenv)
+#define PL_veto_cleanup (my_vars->Gveto_cleanup)
+#define PL_Gveto_cleanup (my_vars->Gveto_cleanup)
#define PL_watch_pvx (my_vars->Gwatch_pvx)
#define PL_Gwatch_pvx (my_vars->Gwatch_pvx)
#define PL_Gthr_key PL_thr_key
#define PL_Gtimesbase PL_timesbase
#define PL_Guse_safe_putenv PL_use_safe_putenv
+#define PL_Gveto_cleanup PL_veto_cleanup
#define PL_Gwatch_pvx PL_watch_pvx
#endif /* PERL_GLOBAL_STRUCT */
if (CALL_FPTR(PL_threadhook)(aTHX)) {
/* Threads hook has vetoed further cleanup */
+ PL_veto_cleanup = TRUE;
return STATUS_EXIT;
}
void
perl_free(pTHXx)
{
+ if (PL_veto_cleanup)
+ return;
+
#ifdef PERL_TRACK_MEMPOOL
{
/*
perl_fini(void)
{
dVAR;
- if (PL_curinterp)
+ if (PL_curinterp && !PL_veto_cleanup)
FREE_THREAD_KEY;
}
#define PL_timesbase (*Perl_Gtimesbase_ptr(NULL))
#undef PL_use_safe_putenv
#define PL_use_safe_putenv (*Perl_Guse_safe_putenv_ptr(NULL))
+#undef PL_veto_cleanup
+#define PL_veto_cleanup (*Perl_Gveto_cleanup_ptr(NULL))
#undef PL_watch_pvx
#define PL_watch_pvx (*Perl_Gwatch_pvx_ptr(NULL))
#if defined(USE_ITHREADS)
PERLVAR(Gperlio_mutex, perl_mutex) /* Mutex for perlio fd refcounts */
#endif
+
+/* this is currently set without MUTEX protection, so keep it a type which
+ * can be set atomically (ie not a bit field) */
+PERLVARI(Gveto_cleanup, int, FALSE) /* exit without cleanup */
+
#endif
#ifndef PERL_SYS_TERM
-# define PERL_SYS_TERM() HINTS_REFCNT_TERM; OP_REFCNT_TERM; PERLIO_TERM; MALLOC_TERM
+# define PERL_SYS_TERM() \
+ if (!PL_veto_cleanup) { \
+ HINTS_REFCNT_TERM; OP_REFCNT_TERM; PERLIO_TERM; MALLOC_TERM; \
+ }
+
#endif
#define BIT_BUCKET "/dev/null"