diff --git a/dist/threads-shared/shared.xs b/dist/threads-shared/shared.xs index 6a7f03c28998..e10659518bbf 100644 --- a/dist/threads-shared/shared.xs +++ b/dist/threads-shared/shared.xs @@ -1287,6 +1287,21 @@ S_shared_signal_hook(pTHX) { } #endif +#ifdef noshutdownhook + +static shutdown_proc_t old_shutdownhook; + +static void +shared_shutdown() { + PerlInterpreter* my_perl; + SHARED_CONTEXT; + perl_destruct(PL_sharedsv_space); + perl_free(PL_sharedsv_space); + PL_sharedsv_space = NULL; + old_shutdownhook(); +} +#endif + /* Saves a space for keeping SVs wider than an interpreter. */ static void @@ -1302,6 +1317,12 @@ Perl_sharedsv_init(pTHX) LEAVE; /* This balances the ENTER at the end of perl_construct. */ PERL_SET_CONTEXT((aTHX = caller_perl)); recursive_lock_init(aTHX_ &PL_sharedsv_lock); +#ifdef noshutdownhook + OP_CHECK_MUTEX_LOCK; + old_shutdownhook = PL_shutdownhook; + PL_shutdownhook = &shared_shutdown; + OP_CHECK_MUTEX_UNLOCK; +#endif } PL_lockhook = &Perl_sharedsv_locksv; PL_sharehook = &Perl_sharedsv_share; diff --git a/dosish.h b/dosish.h index 74aa1270556e..7a0e809e32f9 100644 --- a/dosish.h +++ b/dosish.h @@ -49,7 +49,7 @@ #ifndef PERL_SYS_TERM_BODY # define PERL_SYS_TERM_BODY() \ - HINTS_REFCNT_TERM; KEYWORD_PLUGIN_MUTEX_TERM; \ + SHUTDOWN_TERM; HINTS_REFCNT_TERM; KEYWORD_PLUGIN_MUTEX_TERM; \ OP_CHECK_MUTEX_TERM; OP_REFCNT_TERM; PERLIO_TERM; \ MALLOC_TERM; LOCALE_TERM; USER_PROP_MUTEX_TERM; \ ENV_TERM; diff --git a/embed.fnc b/embed.fnc index 003519ba8d04..14152df0703a 100644 --- a/embed.fnc +++ b/embed.fnc @@ -2843,6 +2843,7 @@ AdpbD |void |sv_nolocking |NULLOK SV *sv Adp |bool |sv_destroyable |NULLOK SV *sv AdpbD |void |sv_nounlocking |NULLOK SV *sv Adp |int |nothreadhook +AdpTG |void |noshutdownhook p |void |init_constants #if defined(PERL_IN_DOOP_C) diff --git a/embed.h b/embed.h index d91fa3c48510..535ac009772f 100644 --- a/embed.h +++ b/embed.h @@ -409,6 +409,7 @@ #define newXS_flags(a,b,c,d,e) Perl_newXS_flags(aTHX_ a,b,c,d,e) #define new_stackinfo(a,b) Perl_new_stackinfo(aTHX_ a,b) #define new_version(a) Perl_new_version(aTHX_ a) +#define noshutdownhook Perl_noshutdownhook #define nothreadhook() Perl_nothreadhook(aTHX) #define op_append_elem(a,b,c) Perl_op_append_elem(aTHX_ a,b,c) #define op_append_list(a,b,c) Perl_op_append_list(aTHX_ a,b,c) diff --git a/perl.c b/perl.c index b02e05318547..ea089a6350a9 100644 --- a/perl.c +++ b/perl.c @@ -447,6 +447,19 @@ Perl_nothreadhook(pTHX) return 0; } +/* +=for apidoc noshutdownhook + +Stub that provides shutdown hook. + +=cut +*/ + +void +Perl_noshutdownhook() +{ +} + #ifdef DEBUG_LEAKING_SCALARS_FORK_DUMP void Perl_dump_sv_child(pTHX_ SV *sv) diff --git a/perl.h b/perl.h index 75bb35eb2585..e028bfdb10fd 100644 --- a/perl.h +++ b/perl.h @@ -3221,6 +3221,8 @@ freeing any remaining Perl interpreters. #define PERL_SYS_INIT3(argc, argv, env) Perl_sys_init3(argc, argv, env) #define PERL_SYS_TERM() Perl_sys_term() +#define SHUTDOWN_TERM PL_shutdownhook(); + #ifndef PERL_WRITE_MSG_TO_CONSOLE # define PERL_WRITE_MSG_TO_CONSOLE(io, msg, len) PerlIO_write(io, msg, len) #endif @@ -4900,6 +4902,7 @@ typedef int (*thrhook_proc_t) (pTHX); typedef OP* (*PPADDR_t[]) (pTHX); typedef bool (*destroyable_proc_t) (pTHX_ SV *sv); typedef void (*despatch_signals_proc_t) (pTHX); +typedef void (*shutdown_proc_t)(); #if defined(__DYNAMIC__) && defined(PERL_DARWIN) && defined(PERL_CORE) # include /* for the env array */ diff --git a/perlvars.h b/perlvars.h index 2ecf29ed124d..c1192d146298 100644 --- a/perlvars.h +++ b/perlvars.h @@ -290,6 +290,8 @@ PERLVAR(G, user_prop_mutex, perl_mutex) /* Mutex for manipulating PL_user_defined_properties */ #endif +PERLVARI(G, shutdownhook, shutdown_proc_t, &Perl_noshutdownhook); + /* these record the best way to perform certain IO operations while * atomically setting FD_CLOEXEC. On the first call, a probe is done * and the result recorded for use by subsequent calls. diff --git a/proto.h b/proto.h index 9fbc40635512..aaab60e8bae9 100644 --- a/proto.h +++ b/proto.h @@ -2609,6 +2609,7 @@ PERL_CALLCONV_NO_RET void Perl_noperl_die(const char* pat, ...) #define PERL_ARGS_ASSERT_NOPERL_DIE \ assert(pat) +PERL_CALLCONV void Perl_noshutdownhook(void); PERL_CALLCONV int Perl_nothreadhook(pTHX); #define PERL_ARGS_ASSERT_NOTHREADHOOK PERL_CALLCONV void Perl_notify_parser_that_changed_to_utf8(pTHX); diff --git a/unixish.h b/unixish.h index eafc6f1e8b88..2c486190225f 100644 --- a/unixish.h +++ b/unixish.h @@ -153,6 +153,7 @@ int afstat(int fd, struct stat *statb); #ifndef PERL_SYS_TERM_BODY # define PERL_SYS_TERM_BODY() \ + SHUTDOWN_TERM; \ HINTS_REFCNT_TERM; KEYWORD_PLUGIN_MUTEX_TERM; \ OP_CHECK_MUTEX_TERM; OP_REFCNT_TERM; PERLIO_TERM; \ MALLOC_TERM; LOCALE_TERM; USER_PROP_MUTEX_TERM; \ diff --git a/vms/vmsish.h b/vms/vmsish.h index ba228e57671d..4182d5f408fc 100644 --- a/vms/vmsish.h +++ b/vms/vmsish.h @@ -309,7 +309,7 @@ struct interp_intern { #define BIT_BUCKET "/dev/null" #define PERL_SYS_INIT_BODY(c,v) MALLOC_CHECK_TAINT2(*c,*v) vms_image_init((c),(v)); PERLIO_INIT; MALLOC_INIT -#define PERL_SYS_TERM_BODY() HINTS_REFCNT_TERM; OP_REFCNT_TERM; \ +#define PERL_SYS_TERM_BODY() SHUTDOWN_TERM; HINTS_REFCNT_TERM; OP_REFCNT_TERM; \ PERLIO_TERM; MALLOC_TERM; LOCALE_TERM; \ ENV_TERM; #define dXSUB_SYS dNOOP diff --git a/win32/win32.c b/win32/win32.c index 70ab455275b6..c0c1f30630b5 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -5036,6 +5036,7 @@ Perl_win32_init(int *argcp, char ***argvp) void Perl_win32_term(void) { + SHUTDOWN_TERM; HINTS_REFCNT_TERM; OP_REFCNT_TERM; PERLIO_TERM;