my_plvarsp nulling and PERL_GLOBAL_STRUCT_PRIVATE
authorDavid Mitchell <davem@iabyn.com>
Wed, 23 Apr 2014 15:48:15 +0000 (16:48 +0100)
committerDavid Mitchell <davem@iabyn.com>
Thu, 24 Apr 2014 13:34:55 +0000 (14:34 +0100)
With PERL_GLOBAL_STRUCT_PRIVATE, all "global" vars are in a malloc()d
structure pointed to by the static var my_plvarsp. At exit, this struct is
freed and my_plvarsp is set to NULL.

My previous commit c1181d2b skipped the free if PL_veto_cleanup is set
(as it would be if other threads are still running for example), but
still left my_plvarsp getting set to NULL. Thus other threads could still
deref a null pointer if they accessed a "global" var just as the main
thread was exiting.

This commit makes the veto skip the NULLing in addition to the freeing.

This commit is quite late into the code freeze, but it's a follow-up to the
earlier attempt to get smokes not to fail, and all the affected code is
within #ifdef PERL_GLOBAL_STRUCT_PRIVATE, so it shouldn't affect
mainstream builds at all. (Famous last words.)

ext/ExtUtils-Miniperl/lib/ExtUtils/Miniperl.pm
lib/ExtUtils/t/Embed.t
miniperlmain.c

index 730c565..cede318 100644 (file)
@@ -8,7 +8,7 @@ use vars qw($VERSION @ISA @EXPORT);
 
 @ISA = qw(Exporter);
 @EXPORT = qw(writemain);
-$VERSION = 1;
+$VERSION = '1.01';
 
 # blead will run this with miniperl, hence we can't use autodie or File::Temp
 my $temp;
@@ -99,6 +99,8 @@ main(int argc, char **argv, char **env)
 #ifdef PERL_GLOBAL_STRUCT
     struct perl_vars *my_vars = init_global_struct();
 #  ifdef PERL_GLOBAL_STRUCT_PRIVATE
+    int veto;
+
     my_plvarsp = my_vars;
 #  endif
 #endif /* PERL_GLOBAL_STRUCT */
@@ -175,9 +177,13 @@ main(int argc, char **argv, char **env)
     PERL_SYS_TERM();
 
 #ifdef PERL_GLOBAL_STRUCT
+#  ifdef PERL_GLOBAL_STRUCT_PRIVATE
+    veto = my_plvarsp->Gveto_cleanup;
+#  endif
     free_global_struct(my_vars);
 #  ifdef PERL_GLOBAL_STRUCT_PRIVATE
-    my_plvarsp = NULL;
+    if (!veto)
+        my_plvarsp = NULL;
     /* Remember, functions registered with atexit() can run after this point,
        and may access "global" variables, and hence end up calling
        Perl_GetVarsPrivate()  */
index c02640c..4e05cfe 100644 (file)
@@ -177,6 +177,8 @@ int main(int argc, char **argv, char **env) {
 #ifdef PERL_GLOBAL_STRUCT
     struct perl_vars *my_vars = init_global_struct();
 #  ifdef PERL_GLOBAL_STRUCT_PRIVATE
+    int veto;
+
     my_plvarsp = my_vars;
 #  endif
 #endif /* PERL_GLOBAL_STRUCT */
@@ -215,9 +217,13 @@ int main(int argc, char **argv, char **env) {
     PERL_SYS_TERM();
 
 #ifdef PERL_GLOBAL_STRUCT
+#  ifdef PERL_GLOBAL_STRUCT_PRIVATE
+    veto = my_plvarsp->Gveto_cleanup;
+#  endif
     free_global_struct(my_vars);
 #  ifdef PERL_GLOBAL_STRUCT_PRIVATE
-    my_plvarsp = NULL;
+    if (!veto)
+        my_plvarsp = NULL;
     /* Remember, functions registered with atexit() can run after this point,
        and may access "global" variables, and hence end up calling
        Perl_GetVarsPrivate()  */
index a1ef2f1..f22dcbb 100644 (file)
@@ -70,6 +70,8 @@ main(int argc, char **argv, char **env)
 #ifdef PERL_GLOBAL_STRUCT
     struct perl_vars *my_vars = init_global_struct();
 #  ifdef PERL_GLOBAL_STRUCT_PRIVATE
+    int veto;
+
     my_plvarsp = my_vars;
 #  endif
 #endif /* PERL_GLOBAL_STRUCT */
@@ -146,9 +148,13 @@ main(int argc, char **argv, char **env)
     PERL_SYS_TERM();
 
 #ifdef PERL_GLOBAL_STRUCT
+#  ifdef PERL_GLOBAL_STRUCT_PRIVATE
+    veto = my_plvarsp->Gveto_cleanup;
+#  endif
     free_global_struct(my_vars);
 #  ifdef PERL_GLOBAL_STRUCT_PRIVATE
-    my_plvarsp = NULL;
+    if (!veto)
+        my_plvarsp = NULL;
     /* Remember, functions registered with atexit() can run after this point,
        and may access "global" variables, and hence end up calling
        Perl_GetVarsPrivate()  */