Hello community,

here is the log from the commit of package perl-Scope-Upper for 
openSUSE:Factory checked in at 2015-04-15 16:26:49
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/perl-Scope-Upper (Old)
 and      /work/SRC/openSUSE:Factory/.perl-Scope-Upper.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "perl-Scope-Upper"

Changes:
--------
--- /work/SRC/openSUSE:Factory/perl-Scope-Upper/perl-Scope-Upper.changes        
2013-10-06 14:31:48.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.perl-Scope-Upper.new/perl-Scope-Upper.changes   
2015-04-15 16:26:51.000000000 +0200
@@ -1,0 +2,32 @@
+Tue Apr 14 19:22:47 UTC 2015 - [email protected]
+
+- updated to 0.27
+   see /usr/share/doc/packages/perl-Scope-Upper/Changes
+
+  0.27    2015-03-27 22:10 UTC
+          + Chg : The new environment variable to enable thread tests on older
+                  perls is PERL_FORCE_TEST_THREADS. Note that this variable
+                  should only be turned on by authors.
+          + Fix : Segfaults when the module is loaded by several threads (or
+                  Windows emulated processes) ran in parallel.
+          + Fix : Memory leak with the uid() feature.
+          + Fix : Update the Windows ActivePerl + gcc 3.4 workaround for
+                  ExtUtils::MakeMaker 7.04. Thanks Christian Walde for 
reporting
+                  and feedback on this issue.
+          + Fix : reap(), localize(), localize_elem() and localize_delete()
+                  will again work correctly on perl 5.19.4+ when the debugger
+                  is enabled.
+          + Fix : Silence some compiler warnings.
+  
+  0.26    2015-03-12 23:30 UTC
+          + Fix : [RT #100264] : Don't use CvPADLIST on XSUBs
+                  Thanks Father Chrysostomos for reporting and contributing a
+                  patch.
+          + Fix : Be really compatible with the optional OP_PARENT feature.
+  
+  0.25    2014-09-21 17:10 UTC
+          + Add : Support for the PERL_OP_PARENT optional feature introduced in
+                  perl 5.21.2.
+          + Fix : Work around an assertion failure in perl 5.21.4.
+
+-------------------------------------------------------------------

Old:
----
  Scope-Upper-0.24.tar.gz

New:
----
  Scope-Upper-0.27.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ perl-Scope-Upper.spec ++++++
--- /var/tmp/diff_new_pack.gHeWe9/_old  2015-04-15 16:26:51.000000000 +0200
+++ /var/tmp/diff_new_pack.gHeWe9/_new  2015-04-15 16:26:51.000000000 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package perl-Scope-Upper
 #
-# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,10 +17,10 @@
 
 
 Name:           perl-Scope-Upper
-Version:        0.24
+Version:        0.27
 Release:        0
 %define cpan_name Scope-Upper
-Summary:        Act on upper scopes.
+Summary:        Act on upper scopes
 License:        Artistic-1.0 or GPL-1.0+
 Group:          Development/Libraries/Perl
 Url:            http://search.cpan.org/dist/Scope-Upper/
@@ -28,13 +28,6 @@
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 BuildRequires:  perl
 BuildRequires:  perl-macros
-#BuildRequires: perl(feature)
-#BuildRequires: perl(Scope::Upper)
-#BuildRequires: perl(Scope::Upper::TestGenerator)
-#BuildRequires: perl(Scope::Upper::TestThreads)
-#BuildRequires: perl(Sub::Uplevel)
-#BuildRequires: perl(Test::Leaner)
-#BuildRequires: perl(VPIT::TestHelpers)
 %{perl_requires}
 
 %description

++++++ Scope-Upper-0.24.tar.gz -> Scope-Upper-0.27.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Scope-Upper-0.24/Changes new/Scope-Upper-0.27/Changes
--- old/Scope-Upper-0.24/Changes        2013-09-10 12:46:59.000000000 +0200
+++ new/Scope-Upper-0.27/Changes        2015-03-27 22:38:16.000000000 +0100
@@ -1,5 +1,31 @@
 Revision history for Scope-Upper
 
+0.27    2015-03-27 22:10 UTC
+        + Chg : The new environment variable to enable thread tests on older
+                perls is PERL_FORCE_TEST_THREADS. Note that this variable
+                should only be turned on by authors.
+        + Fix : Segfaults when the module is loaded by several threads (or
+                Windows emulated processes) ran in parallel.
+        + Fix : Memory leak with the uid() feature.
+        + Fix : Update the Windows ActivePerl + gcc 3.4 workaround for
+                ExtUtils::MakeMaker 7.04. Thanks Christian Walde for reporting
+                and feedback on this issue.
+        + Fix : reap(), localize(), localize_elem() and localize_delete()
+                will again work correctly on perl 5.19.4+ when the debugger
+                is enabled.
+        + Fix : Silence some compiler warnings.
+
+0.26    2015-03-12 23:30 UTC
+        + Fix : [RT #100264] : Don't use CvPADLIST on XSUBs
+                Thanks Father Chrysostomos for reporting and contributing a
+                patch.
+        + Fix : Be really compatible with the optional OP_PARENT feature.
+
+0.25    2014-09-21 17:10 UTC
+        + Add : Support for the PERL_OP_PARENT optional feature introduced in
+                perl 5.21.2.
+        + Fix : Work around an assertion failure in perl 5.21.4.
+
 0.24    2013-09-10 11:10 UTC
         + Fix : Lexicals returned with unwind(), yield() and leave() will no
                 longer be lost on perl 5.19.4 and above.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Scope-Upper-0.24/MANIFEST 
new/Scope-Upper-0.27/MANIFEST
--- old/Scope-Upper-0.24/MANIFEST       2013-09-09 18:43:19.000000000 +0200
+++ new/Scope-Upper-0.27/MANIFEST       2015-03-23 20:15:17.000000000 +0100
@@ -14,6 +14,7 @@
 t/05-words.t
 t/06-want_at.t
 t/07-context_info.t
+t/09-load-threads.t
 t/11-reap-level.t
 t/12-reap-block.t
 t/13-reap-ctl.t
@@ -63,6 +64,5 @@
 t/86-stress-uplevel.t
 t/87-stress-uid.t
 t/lib/Scope/Upper/TestGenerator.pm
-t/lib/Scope/Upper/TestThreads.pm
 t/lib/Test/Leaner.pm
 t/lib/VPIT/TestHelpers.pm
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Scope-Upper-0.24/META.json 
new/Scope-Upper-0.27/META.json
--- old/Scope-Upper-0.24/META.json      2013-09-10 12:47:55.000000000 +0200
+++ new/Scope-Upper-0.27/META.json      2015-03-27 22:38:59.000000000 +0100
@@ -4,7 +4,7 @@
       "Vincent Pit <[email protected]>"
    ],
    "dynamic_config" : 1,
-   "generated_by" : "ExtUtils::MakeMaker version 6.76, CPAN::Meta::Converter 
version 2.132510",
+   "generated_by" : "ExtUtils::MakeMaker version 7.04, CPAN::Meta::Converter 
version 2.150001",
    "license" : [
       "perl_5"
    ],
@@ -25,6 +25,7 @@
             "Config" : "0",
             "Exporter" : "0",
             "ExtUtils::MakeMaker" : "0",
+            "POSIX" : "0",
             "Test::More" : "0",
             "XSLoader" : "0",
             "base" : "0"
@@ -58,5 +59,5 @@
          "url" : "http://git.profvince.com/?p=perl%2Fmodules%2FScope-Upper.git";
       }
    },
-   "version" : "0.24"
+   "version" : "0.27"
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Scope-Upper-0.24/META.yml 
new/Scope-Upper-0.27/META.yml
--- old/Scope-Upper-0.24/META.yml       2013-09-10 12:47:55.000000000 +0200
+++ new/Scope-Upper-0.27/META.yml       2015-03-27 22:38:59.000000000 +0100
@@ -3,34 +3,35 @@
 author:
   - 'Vincent Pit <[email protected]>'
 build_requires:
-  Config: 0
-  Exporter: 0
-  ExtUtils::MakeMaker: 0
-  Test::More: 0
-  XSLoader: 0
-  base: 0
+  Config: '0'
+  Exporter: '0'
+  ExtUtils::MakeMaker: '0'
+  POSIX: '0'
+  Test::More: '0'
+  XSLoader: '0'
+  base: '0'
 configure_requires:
-  Config: 0
-  ExtUtils::MakeMaker: 0
+  Config: '0'
+  ExtUtils::MakeMaker: '0'
 dynamic_config: 1
-generated_by: 'ExtUtils::MakeMaker version 6.76, CPAN::Meta::Converter version 
2.132510'
+generated_by: 'ExtUtils::MakeMaker version 7.04, CPAN::Meta::Converter version 
2.150001'
 license: perl
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
-  version: 1.4
+  version: '1.4'
 name: Scope-Upper
 no_index:
   directory:
     - t
     - inc
 requires:
-  Exporter: 0
-  XSLoader: 0
-  base: 0
-  perl: 5.006001
+  Exporter: '0'
+  XSLoader: '0'
+  base: '0'
+  perl: '5.006001'
 resources:
   bugtracker: http://rt.cpan.org/Dist/Display.html?Name=Scope-Upper
   homepage: http://search.cpan.org/dist/Scope-Upper/
   license: http://dev.perl.org/licenses/
   repository: http://git.profvince.com/?p=perl%2Fmodules%2FScope-Upper.git
-version: 0.24
+version: '0.27'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Scope-Upper-0.24/Makefile.PL 
new/Scope-Upper-0.27/Makefile.PL
--- old/Scope-Upper-0.24/Makefile.PL    2013-08-29 01:17:08.000000000 +0200
+++ new/Scope-Upper-0.27/Makefile.PL    2015-03-27 20:07:42.000000000 +0100
@@ -35,7 +35,16 @@
                   @Config{qw<bin sitebin>};
   $macro{LDDLFLAGS}    = "$lddlflags $libdirs $libperl";
   $macro{LDFLAGS}      = "$ldflags $libdirs $libperl";
-  $macro{PERL_ARCHIVE} = '',
+  eval <<'  MY_SECTION';
+   package MY;
+   sub dynamic_lib {
+    my $self = shift;
+    my $inherited = $self->SUPER::dynamic_lib(@_);
+    $inherited =~ s/"?\$\(PERL_ARCHIVE\)"?//g;
+    return $inherited;
+   }
+  MY_SECTION
+  die $@ if $@;
  }
 }
 print $is_gcc_34 ? "yes\n" : "no\n";
@@ -64,6 +73,7 @@
 my %BUILD_REQUIRES = (
  'ExtUtils::MakeMaker' => 0,
  'Config'              => 0,
+ 'POSIX'               => 0,
  'Test::More'          => 0,
  %PREREQ_PM,
 );
@@ -112,6 +122,6 @@
 sub postamble {
  return <<'POSTAMBLE';
 testdeb: all
-       PERL_DL_NONLAZY=1 PERLDB_OPTS="NonStop=1" $(FULLPERLRUN) -MTAP::Harness 
-e 'TAP::Harness->new({verbosity => q{$(VERBOSE)}, lib => [ q{$(INST_LIB)}, 
q{$(INST_ARCHLIB)} ], switches => [ q{-d} ]})->runtests(@ARGV)' $(TEST_FILES)
+       PERL_DL_NONLAZY=1 PERLDB_OPTS="NonStop=1" $(FULLPERLRUN) -MTAP::Harness 
-e 'TAP::Harness->new({verbosity => q{$(TEST_VERBOSE)}, lib => [ 
q{$(INST_LIB)}, q{$(INST_ARCHLIB)} ], switches => [ q{-d} ]})->runtests(@ARGV)' 
$(TEST_FILES)
 POSTAMBLE
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Scope-Upper-0.24/README new/Scope-Upper-0.27/README
--- old/Scope-Upper-0.24/README 2013-09-10 12:47:55.000000000 +0200
+++ new/Scope-Upper-0.27/README 2015-03-27 22:38:59.000000000 +0100
@@ -2,7 +2,7 @@
     Scope::Upper - Act on upper scopes.
 
 VERSION
-    Version 0.24
+    Version 0.27
 
 SYNOPSIS
     "reap", "localize", "localize_elem", "localize_delete" and "WORDS" :
@@ -737,6 +737,11 @@
     version of "uplevel" should still run way faster than the pure-Perl
     version from Sub::Uplevel.
 
+    Starting from "perl" 5.19.4, it is unfortunately no longer possible to
+    reliably throw exceptions from "uplevel"'d code while the debugger is in
+    use. This may be solved in a future version depending on how the core
+    evolves.
+
 DEPENDENCIES
     perl 5.6.1.
 
@@ -785,8 +790,8 @@
     Thanks to Shawn M. Moore for motivation.
 
 COPYRIGHT & LICENSE
-    Copyright 2008,2009,2010,2011,2012,2013 Vincent Pit, all rights
-    reserved.
+    Copyright 2008,2009,2010,2011,2012,2013,2014,2015 Vincent Pit, all
+    rights reserved.
 
     This program is free software; you can redistribute it and/or modify it
     under the same terms as Perl itself.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Scope-Upper-0.24/Upper.xs 
new/Scope-Upper-0.27/Upper.xs
--- old/Scope-Upper-0.24/Upper.xs       2013-09-09 18:41:51.000000000 +0200
+++ new/Scope-Upper-0.27/Upper.xs       2015-03-27 20:44:54.000000000 +0100
@@ -72,7 +72,7 @@
 #endif
 
 #ifndef newSV_type
-STATIC SV *su_newSV_type(pTHX_ svtype t) {
+static SV *su_newSV_type(pTHX_ svtype t) {
  SV *sv = newSV(0);
  SvUPGRADE(sv, t);
  return sv;
@@ -182,7 +182,7 @@
 #endif
 
 #ifndef OP_GIMME_REVERSE
-STATIC U8 su_op_gimme_reverse(U8 gimme) {
+static U8 su_op_gimme_reverse(U8 gimme) {
  switch (gimme) {
   case G_VOID:
    return OPf_WANT_VOID;
@@ -197,6 +197,14 @@
 #define OP_GIMME_REVERSE(G) su_op_gimme_reverse(G)
 #endif
 
+#ifndef OpSIBLING
+# ifdef OP_SIBLING
+#  define OpSIBLING(O) OP_SIBLING(O)
+# else
+#  define OpSIBLING(O) ((O)->op_sibling)
+# endif
+#endif
+
 #ifndef PERL_MAGIC_tied
 # define PERL_MAGIC_tied 'P'
 #endif
@@ -241,7 +249,7 @@
 # undef  MY_CXT
 # define MY_CXT       su_globaldata
 # undef  START_MY_CXT
-# define START_MY_CXT STATIC my_cxt_t MY_CXT;
+# define START_MY_CXT static my_cxt_t MY_CXT;
 # undef  MY_CXT_INIT
 # define MY_CXT_INIT  NOOP
 # undef  MY_CXT_CLONE
@@ -257,11 +265,11 @@
  STRLEN  size;
 } su_uv_array;
 
-STATIC su_uv_array su_uid_seq_counter;
+static su_uv_array su_uid_seq_counter;
 
 #ifdef USE_ITHREADS
 
-STATIC perl_mutex su_uid_seq_counter_mutex;
+static perl_mutex su_uid_seq_counter_mutex;
 
 #define SU_LOCK(M)   MUTEX_LOCK(M)
 #define SU_UNLOCK(M) MUTEX_UNLOCK(M)
@@ -273,7 +281,7 @@
 
 #endif /* !USE_ITHREADS */
 
-STATIC UV su_uid_seq_next(pTHX_ UV depth) {
+static UV su_uid_seq_next(pTHX_ UV depth) {
 #define su_uid_seq_next(D) su_uid_seq_next(aTHX_ (D))
  UV seq;
  UV *seqs;
@@ -309,7 +317,7 @@
 
 #define SU_UID_ACTIVE 1
 
-STATIC UV su_uid_depth(pTHX_ I32 cxix) {
+static UV su_uid_depth(pTHX_ I32 cxix) {
 #define su_uid_depth(I) su_uid_depth(aTHX_ (I))
  const PERL_SI *si;
  UV depth;
@@ -327,7 +335,7 @@
  STRLEN   alloc;
 } su_uid_storage;
 
-STATIC void su_uid_storage_dup(pTHX_ su_uid_storage *new_cxt, const 
su_uid_storage *old_cxt, UV max_depth) {
+static void su_uid_storage_dup(pTHX_ su_uid_storage *new_cxt, const 
su_uid_storage *old_cxt, UV max_depth) {
 #define su_uid_storage_dup(N, O, D) su_uid_storage_dup(aTHX_ (N), (O), (D))
  su_uid **old_map = old_cxt->map;
 
@@ -428,7 +436,7 @@
  bool           died;
 } su_uplevel_ud;
 
-STATIC su_uplevel_ud *su_uplevel_ud_new(pTHX) {
+static su_uplevel_ud *su_uplevel_ud_new(pTHX) {
 #define su_uplevel_ud_new() su_uplevel_ud_new(aTHX)
  su_uplevel_ud *sud;
  PERL_SI       *si;
@@ -451,7 +459,7 @@
  return sud;
 }
 
-STATIC void su_uplevel_ud_delete(pTHX_ su_uplevel_ud *sud) {
+static void su_uplevel_ud_delete(pTHX_ su_uplevel_ud *sud) {
 #define su_uplevel_ud_delete(S) su_uplevel_ud_delete(aTHX_ (S))
  PERL_SI *si = sud->si;
 
@@ -555,7 +563,7 @@
 
 /* ... Saving array elements ............................................... */
 
-STATIC I32 su_av_key2idx(pTHX_ AV *av, I32 key) {
+static I32 su_av_key2idx(pTHX_ AV *av, I32 key) {
 #define su_av_key2idx(A, K) su_av_key2idx(aTHX_ (A), (K))
  I32 idx;
 
@@ -590,7 +598,7 @@
  I32 idx;
 } su_ud_adelete;
 
-STATIC void su_adelete(pTHX_ void *ud_) {
+static void su_adelete(pTHX_ void *ud_) {
  su_ud_adelete *ud = (su_ud_adelete *) ud_;
 
  av_delete(ud->av, ud->idx, G_DISCARD);
@@ -599,7 +607,7 @@
  Safefree(ud);
 }
 
-STATIC void su_save_adelete(pTHX_ AV *av, I32 idx) {
+static void su_save_adelete(pTHX_ AV *av, I32 idx) {
 #define su_save_adelete(A, K) su_save_adelete(aTHX_ (A), (K))
  su_ud_adelete *ud;
 
@@ -615,7 +623,7 @@
 
 #endif /* SAVEADELETE */
 
-STATIC void su_save_aelem(pTHX_ AV *av, SV *key, SV *val) {
+static void su_save_aelem(pTHX_ AV *av, SV *key, SV *val) {
 #define su_save_aelem(A, K, V) su_save_aelem(aTHX_ (A), (K), (V))
  I32 idx;
  I32 preeminent = 1;
@@ -645,7 +653,7 @@
 
 /* ... Saving hash elements ................................................ */
 
-STATIC void su_save_helem(pTHX_ HV *hv, SV *keysv, SV *val) {
+static void su_save_helem(pTHX_ HV *hv, SV *keysv, SV *val) {
 #define su_save_helem(H, K, V) su_save_helem(aTHX_ (H), (K), (V))
  I32 preeminent = 1;
  HE *he;
@@ -692,7 +700,7 @@
  CV *old_cv;
 } su_save_gvcv_ud;
 
-STATIC void su_restore_gvcv(pTHX_ void *ud_) {
+static void su_restore_gvcv(pTHX_ void *ud_) {
  su_save_gvcv_ud *ud = ud_;
  GV              *gv = ud->gv;
 
@@ -703,7 +711,7 @@
  Safefree(ud);
 }
 
-STATIC void su_save_gvcv(pTHX_ GV *gv) {
+static void su_save_gvcv(pTHX_ GV *gv) {
 #define su_save_gvcv(G) su_save_gvcv(aTHX_ (G))
  su_save_gvcv_ud *ud;
 
@@ -746,7 +754,7 @@
  SV *cb;
 } su_ud_reap;
 
-STATIC void su_call(pTHX_ void *ud_) {
+static void su_call(pTHX_ void *ud_) {
  su_ud_reap *ud = (su_ud_reap *) ud_;
 #if SU_SAVE_LAST_CX
  I32 cxix;
@@ -789,7 +797,7 @@
  SU_UD_FREE(ud);
 }
 
-STATIC void su_reap(pTHX_ void *ud) {
+static void su_reap(pTHX_ void *ud) {
 #define su_reap(U) su_reap(aTHX_ (U))
  SU_D({
   PerlIO_printf(Perl_debug_log,
@@ -817,7 +825,7 @@
  SU_UD_FREE(U);           \
 } STMT_END
 
-STATIC I32 su_ud_localize_init(pTHX_ su_ud_localize *ud, SV *sv, SV *val, SV 
*elem) {
+static I32 su_ud_localize_init(pTHX_ su_ud_localize *ud, SV *sv, SV *val, SV 
*elem) {
 #define su_ud_localize_init(UD, S, V, E) su_ud_localize_init(aTHX_ (UD), (S), 
(V), (E))
  UV deref = 0;
  svtype t = SVt_NULL;
@@ -898,7 +906,7 @@
  return size;
 }
 
-STATIC void su_localize(pTHX_ void *ud_) {
+static void su_localize(pTHX_ void *ud_) {
 #define su_localize(U) su_localize(aTHX_ (U))
  su_ud_localize *ud = (su_ud_localize *) ud_;
  SV *sv   = ud->sv;
@@ -971,7 +979,7 @@
 # define SU_CXNAME(C) "XXX"
 #endif
 
-STATIC void su_pop(pTHX_ void *ud) {
+static void su_pop(pTHX_ void *ud) {
 #define su_pop(U) su_pop(aTHX_ (U))
  I32 depth, base, mark, *origin;
  depth = SU_UD_DEPTH(ud);
@@ -993,9 +1001,26 @@
                      ud,                24, ' ',    mark,        base));
 
  if (base < mark) {
+#if SU_HAS_PERL(5, 19, 4)
+  I32 save = -1;
+  PERL_CONTEXT *cx;
+#endif
+
   SU_D(PerlIO_printf(Perl_debug_log, "%p: clear leftovers\n", ud));
+
+#if SU_HAS_PERL(5, 19, 4)
+  cx = cxstack + cxstack_ix;
+  if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT)
+   save = PL_scopestack[cx->blk_oldscopesp - 1];
+#endif
+
   PL_savestack_ix = mark;
   leave_scope(base);
+
+#if SU_HAS_PERL(5, 19, 4)
+  if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT)
+   PL_scopestack[cx->blk_oldscopesp - 1] = save;
+#endif
  }
  PL_savestack_ix = base;
 
@@ -1029,7 +1054,7 @@
 
 /* --- Initialize the stack and the action userdata ------------------------ */
 
-STATIC I32 su_init(pTHX_ void *ud, I32 cxix, I32 size) {
+static I32 su_init(pTHX_ void *ud, I32 cxix, I32 size) {
 #define su_init(U, C, S) su_init(aTHX_ (U), (C), (S))
  I32 i, depth = 1, pad, offset, *origin;
 
@@ -1117,7 +1142,7 @@
 
 /* --- Unwind stack -------------------------------------------------------- */
 
-STATIC void su_unwind(pTHX_ void *ud_) {
+static void su_unwind(pTHX_ void *ud_) {
  dMY_CXT;
  I32 cxix  = MY_CXT.unwind_storage.cxix;
  I32 items = MY_CXT.unwind_storage.items;
@@ -1173,7 +1198,7 @@
 # define SU_RETOP_LOOP(C) ((C)->blk_loop.last_op->op_next)
 #endif
 
-STATIC void su_yield(pTHX_ void *ud_) {
+static void su_yield(pTHX_ void *ud_) {
  dMY_CXT;
  PERL_CONTEXT *cx;
  const char   *which = ud_;
@@ -1348,7 +1373,7 @@
 #define SU_UPLEVEL_SAVE(f, t) STMT_START { sud->old_##f = PL_##f; PL_##f = 
(t); } STMT_END
 #define SU_UPLEVEL_RESTORE(f) STMT_START { PL_##f = sud->old_##f; } STMT_END
 
-STATIC su_uplevel_ud *su_uplevel_storage_new(pTHX_ I32 cxix) {
+static su_uplevel_ud *su_uplevel_storage_new(pTHX_ I32 cxix) {
 #define su_uplevel_storage_new(I) su_uplevel_storage_new(aTHX_ (I))
  su_uplevel_ud *sud;
  UV depth;
@@ -1373,7 +1398,9 @@
  return sud;
 }
 
-STATIC void su_uplevel_storage_delete(pTHX_ su_uplevel_ud *sud) {
+#if SU_HAS_PERL(5, 13, 7)
+
+static void su_uplevel_storage_delete(pTHX_ su_uplevel_ud *sud) {
 #define su_uplevel_storage_delete(S) su_uplevel_storage_delete(aTHX_ (S))
  dMY_CXT;
 
@@ -1400,8 +1427,10 @@
  }
 }
 
-STATIC int su_uplevel_goto_static(const OP *o) {
- for (; o; o = o->op_sibling) {
+#endif
+
+static int su_uplevel_goto_static(const OP *o) {
+ for (; o; o = OpSIBLING(o)) {
   /* goto ops are unops with kids. */
   if (!(o->op_flags & OPf_KIDS))
    continue;
@@ -1425,7 +1454,7 @@
 
 #if SU_UPLEVEL_HIJACKS_RUNOPS
 
-STATIC int su_uplevel_goto_runops(pTHX) {
+static int su_uplevel_goto_runops(pTHX) {
 #define su_uplevel_goto_runops() su_uplevel_goto_runops(aTHX)
  register OP *op;
  dVAR;
@@ -1485,7 +1514,7 @@
 
 #define su_at_underscore(C) PadARRAY(PadlistARRAY(CvPADLIST(C))[CvDEPTH(C)])[0]
 
-STATIC void su_uplevel_restore(pTHX_ void *sus_) {
+static void su_uplevel_restore(pTHX_ void *sus_) {
  su_uplevel_ud *sud = sus_;
  PERL_SI *cur = sud->old_curstackinfo;
  PERL_SI *si  = sud->si;
@@ -1529,8 +1558,10 @@
   * depth to be 0, or perl would complain about it being "still in use".
   * But we *know* that it cannot be so. */
  if (sud->renamed) {
-  CvDEPTH(sud->renamed)   = 0;
-  CvPADLIST(sud->renamed) = NULL;
+  if (!CvISXSUB(sud->renamed)) {
+   CvDEPTH(sud->renamed)   = 0;
+   CvPADLIST(sud->renamed) = NULL;
+  }
   SvREFCNT_dec(sud->renamed);
  }
 
@@ -1645,7 +1676,7 @@
  return;
 }
 
-STATIC CV *su_cv_clone(pTHX_ CV *proto, GV *gv) {
+static CV *su_cv_clone(pTHX_ CV *proto, GV *gv) {
 #define su_cv_clone(P, G) su_cv_clone(aTHX_ (P), (G))
  dVAR;
  CV *cv;
@@ -1664,6 +1695,9 @@
 #endif
 
  CvGV_set(cv, gv);
+#if SU_RELEASE && SU_HAS_PERL_EXACT(5, 21, 4)
+ CvNAMED_off(cv);
+#endif
  CvSTASH_set(cv, CvSTASH(proto));
  /* Commit 4c74a7df, publicized with perl 5.13.3, began to add backrefs to
   * stashes. CvSTASH_set() started to do it as well with commit c68d95645
@@ -1681,13 +1715,13 @@
   CvROOT(cv)       = OpREFCNT_inc(CvROOT(proto));
   OP_REFCNT_UNLOCK;
   CvSTART(cv)      = CvSTART(proto);
+  CvPADLIST(cv)    = CvPADLIST(proto);
  }
  CvOUTSIDE(cv)     = CvOUTSIDE(proto);
 #ifdef CVf_WEAKOUTSIDE
  if (!(CvFLAGS(proto) & CVf_WEAKOUTSIDE))
 #endif
   SvREFCNT_inc_simple_void(CvOUTSIDE(cv));
- CvPADLIST(cv)     = CvPADLIST(proto);
 #ifdef CvOUTSIDE_SEQ
  CvOUTSIDE_SEQ(cv) = CvOUTSIDE_SEQ(proto);
 #endif
@@ -1703,7 +1737,7 @@
  return cv;
 }
 
-STATIC I32 su_uplevel(pTHX_ CV *callback, I32 cxix, I32 args) {
+static I32 su_uplevel(pTHX_ CV *callback, I32 cxix, I32 args) {
 #define su_uplevel(C, I, A) su_uplevel(aTHX_ (C), (I), (A))
  su_uplevel_ud *sud;
  const PERL_CONTEXT *cx = cxstack + cxix;
@@ -1884,7 +1918,7 @@
 
 /* --- Unique context ID --------------------------------------------------- */
 
-STATIC su_uid *su_uid_storage_fetch(pTHX_ UV depth) {
+static su_uid *su_uid_storage_fetch(pTHX_ UV depth) {
 #define su_uid_storage_fetch(D) su_uid_storage_fetch(aTHX_ (D))
  su_uid **map, *uid;
  STRLEN alloc;
@@ -1919,7 +1953,7 @@
  return uid;
 }
 
-STATIC int su_uid_storage_check(pTHX_ UV depth, UV seq) {
+static int su_uid_storage_check(pTHX_ UV depth, UV seq) {
 #define su_uid_storage_check(D, S) su_uid_storage_check(aTHX_ (D), (S))
  su_uid *uid;
  dMY_CXT;
@@ -1932,19 +1966,21 @@
  return uid && (uid->seq == seq) && (uid->flags & SU_UID_ACTIVE);
 }
 
-STATIC void su_uid_drop(pTHX_ void *ud_) {
+static void su_uid_drop(pTHX_ void *ud_) {
  su_uid *uid = ud_;
 
  uid->flags &= ~SU_UID_ACTIVE;
 }
 
-STATIC void su_uid_bump(pTHX_ void *ud_) {
+static void su_uid_bump(pTHX_ void *ud_) {
  su_ud_reap *ud  = ud_;
 
  SAVEDESTRUCTOR_X(su_uid_drop, ud->cb);
+
+ SU_UD_FREE(ud);
 }
 
-STATIC SV *su_uid_get(pTHX_ I32 cxix) {
+static SV *su_uid_get(pTHX_ I32 cxix) {
 #define su_uid_get(I) su_uid_get(aTHX_ (I))
  su_uid *uid;
  SV *uid_sv;
@@ -1979,7 +2015,7 @@
 
 #define IS_NUMBER_IN_UV 0x1
 
-STATIC int su_grok_number(pTHX_ const char *s, STRLEN len, UV *valuep) {
+static int su_grok_number(pTHX_ const char *s, STRLEN len, UV *valuep) {
 #define su_grok_number(S, L, VP) su_grok_number(aTHX_ (S), (L), (VP))
  STRLEN i;
  SV *tmpsv;
@@ -2000,7 +2036,7 @@
 
 #endif /* !grok_number */
 
-STATIC int su_uid_validate(pTHX_ SV *uid) {
+static int su_uid_validate(pTHX_ SV *uid) {
 #define su_uid_validate(U) su_uid_validate(aTHX_ (U))
  const char *s;
  STRLEN len, p = 0;
@@ -2032,7 +2068,7 @@
 /* Remove sequences of BLOCKs having DB for stash, followed by a SUB context
  * for the debugger callback. */
 
-STATIC I32 su_context_skip_db(pTHX_ I32 cxix) {
+static I32 su_context_skip_db(pTHX_ I32 cxix) {
 #define su_context_skip_db(C) su_context_skip_db(aTHX_ (C))
  I32 i;
 
@@ -2067,7 +2103,7 @@
 }
 
 
-STATIC I32 su_context_normalize_up(pTHX_ I32 cxix) {
+static I32 su_context_normalize_up(pTHX_ I32 cxix) {
 #define su_context_normalize_up(C) su_context_normalize_up(aTHX_ (C))
  PERL_CONTEXT *cx;
 
@@ -2093,8 +2129,8 @@
      return cxix - 1;
     break;
    case CXt_SUBST:
-    if (cx->blk_oldcop && cx->blk_oldcop->op_sibling
-                       && cx->blk_oldcop->op_sibling->op_type == OP_SUBST)
+    if (cx->blk_oldcop && OpSIBLING(cx->blk_oldcop)
+                       && OpSIBLING(cx->blk_oldcop)->op_type == OP_SUBST)
      return cxix - 1;
     break;
   }
@@ -2103,7 +2139,7 @@
  return cxix;
 }
 
-STATIC I32 su_context_normalize_down(pTHX_ I32 cxix) {
+static I32 su_context_normalize_down(pTHX_ I32 cxix) {
 #define su_context_normalize_down(C) su_context_normalize_down(aTHX_ (C))
  PERL_CONTEXT *next;
 
@@ -2129,8 +2165,8 @@
      return cxix + 1;
     break;
    case CXt_SUBST:
-    if (next->blk_oldcop && next->blk_oldcop->op_sibling
-                         && next->blk_oldcop->op_sibling->op_type == OP_SUBST)
+    if (next->blk_oldcop && OpSIBLING(next->blk_oldcop)
+                         && OpSIBLING(next->blk_oldcop)->op_type == OP_SUBST)
      return cxix + 1;
     break;
   }
@@ -2141,7 +2177,7 @@
 
 #define su_context_here() 
su_context_normalize_up(su_context_skip_db(cxstack_ix))
 
-STATIC I32 su_context_gimme(pTHX_ I32 cxix) {
+static I32 su_context_gimme(pTHX_ I32 cxix) {
 #define su_context_gimme(C) su_context_gimme(aTHX_ (C))
  I32 i;
 
@@ -2160,8 +2196,8 @@
 #endif
    case CXt_SUBST: {
     const COP *cop = cx->blk_oldcop;
-    if (cop && cop->op_sibling) {
-     switch (cop->op_sibling->op_flags & OPf_WANT) {
+    if (cop && OpSIBLING(cop)) {
+     switch (OpSIBLING(cop)->op_flags & OPf_WANT) {
       case OPf_WANT_VOID:
        return G_VOID;
       case OPf_WANT_SCALAR:
@@ -2183,9 +2219,77 @@
  return G_VOID;
 }
 
+/* --- Global setup/teardown ----------------------------------------------- */
+
+static U32 su_initialized = 0;
+
+static void su_global_teardown(pTHX_ void *root) {
+ if (!su_initialized)
+  return;
+
+#if SU_MULTIPLICITY
+ if (aTHX != root)
+  return;
+#endif
+
+ SU_LOCK(&su_uid_seq_counter_mutex);
+ PerlMemShared_free(su_uid_seq_counter.seqs);
+ su_uid_seq_counter.size = 0;
+ SU_UNLOCK(&su_uid_seq_counter_mutex);
+
+ MUTEX_DESTROY(&su_uid_seq_counter_mutex);
+
+ su_initialized = 0;
+
+ return;
+}
+
+XS(XS_Scope__Upper_unwind);
+XS(XS_Scope__Upper_yield);
+XS(XS_Scope__Upper_leave);
+
+#if SU_HAS_PERL(5, 9, 0)
+# define SU_XS_FILE_TYPE const char
+#else
+# define SU_XS_FILE_TYPE char
+#endif
+
+static void su_global_setup(pTHX_ SU_XS_FILE_TYPE *file) {
+#define su_global_setup(F) su_global_setup(aTHX_ (F))
+ HV *stash;
+
+ if (su_initialized)
+  return;
+
+ MUTEX_INIT(&su_uid_seq_counter_mutex);
+
+ SU_LOCK(&su_uid_seq_counter_mutex);
+ su_uid_seq_counter.seqs = NULL;
+ su_uid_seq_counter.size = 0;
+ SU_UNLOCK(&su_uid_seq_counter_mutex);
+
+ stash = gv_stashpv(__PACKAGE__, 1);
+ newCONSTSUB(stash, "TOP",           newSViv(0));
+ newCONSTSUB(stash, "SU_THREADSAFE", newSVuv(SU_THREADSAFE));
+
+ newXSproto("Scope::Upper::unwind", XS_Scope__Upper_unwind, file, NULL);
+ newXSproto("Scope::Upper::yield",  XS_Scope__Upper_yield,  file, NULL);
+ newXSproto("Scope::Upper::leave",  XS_Scope__Upper_leave,  file, NULL);
+
+#if SU_MULTIPLICITY
+ call_atexit(su_global_teardown, aTHX);
+#else
+ call_atexit(su_global_teardown, NULL);
+#endif
+
+ su_initialized = 1;
+
+ return;
+}
+
 /* --- Interpreter setup/teardown ------------------------------------------ */
 
-STATIC void su_teardown(pTHX_ void *param) {
+static void su_local_teardown(pTHX_ void *param) {
  su_uplevel_ud *cur;
  su_uid **map;
  dMY_CXT;
@@ -2211,8 +2315,8 @@
  return;
 }
 
-STATIC void su_setup(pTHX) {
-#define su_setup() su_setup(aTHX)
+static void su_local_setup(pTHX) {
+#define su_local_setup() su_local_setup(aTHX)
  MY_CXT_INIT;
 
  MY_CXT.stack_placeholder = NULL;
@@ -2242,7 +2346,7 @@
  MY_CXT.uid_storage.used  = 0;
  MY_CXT.uid_storage.alloc = 0;
 
- call_atexit(su_teardown, NULL);
+ call_atexit(su_local_teardown, NULL);
 
  return;
 }
@@ -2285,8 +2389,6 @@
 # define SU_INFO_COUNT 10
 #endif
 
-XS(XS_Scope__Upper_unwind); /* prototype to pass -Wmissing-prototypes */
-
 XS(XS_Scope__Upper_unwind) {
 #ifdef dVAR
  dVAR; dXSARGS;
@@ -2329,9 +2431,7 @@
  croak("Can't return outside a subroutine");
 }
 
-STATIC const char su_yield_name[] = "yield";
-
-XS(XS_Scope__Upper_yield); /* prototype to pass -Wmissing-prototypes */
+static const char su_yield_name[] = "yield";
 
 XS(XS_Scope__Upper_yield) {
 #ifdef dVAR
@@ -2360,9 +2460,7 @@
  return;
 }
 
-STATIC const char su_leave_name[] = "leave";
-
-XS(XS_Scope__Upper_leave); /* prototype to pass -Wmissing-prototypes */
+static const char su_leave_name[] = "leave";
 
 XS(XS_Scope__Upper_leave) {
 #ifdef dVAR
@@ -2371,7 +2469,6 @@
  dXSARGS;
 #endif
  dMY_CXT;
- I32 cxix;
 
  PERL_UNUSED_VAR(cv); /* -W */
  PERL_UNUSED_VAR(ax); /* -Wall */
@@ -2392,22 +2489,8 @@
 
 BOOT:
 {
- HV *stash;
-
- MUTEX_INIT(&su_uid_seq_counter_mutex);
-
- su_uid_seq_counter.seqs = NULL;
- su_uid_seq_counter.size = 0;
-
- stash = gv_stashpv(__PACKAGE__, 1);
- newCONSTSUB(stash, "TOP",           newSViv(0));
- newCONSTSUB(stash, "SU_THREADSAFE", newSVuv(SU_THREADSAFE));
-
- newXSproto("Scope::Upper::unwind", XS_Scope__Upper_unwind, file, NULL);
- newXSproto("Scope::Upper::yield",  XS_Scope__Upper_yield,  file, NULL);
- newXSproto("Scope::Upper::leave",  XS_Scope__Upper_leave,  file, NULL);
-
- su_setup();
+ su_global_setup(file);
+ su_local_setup();
 }
 
 #if SU_THREADSAFE
@@ -2693,7 +2776,9 @@
     goto context_info_warnings_off;
 #endif
   } else if (old_warnings == pWARN_NONE) {
+#if !SU_HAS_PERL(5, 17, 4)
 context_info_warnings_off:
+#endif
    mask = su_newmortal_pvn(WARN_NONEstring, WARNsize);
   } else if (old_warnings == pWARN_ALL) {
    HV *bits;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Scope-Upper-0.24/lib/Scope/Upper.pm 
new/Scope-Upper-0.27/lib/Scope/Upper.pm
--- old/Scope-Upper-0.24/lib/Scope/Upper.pm     2013-09-10 12:45:53.000000000 
+0200
+++ new/Scope-Upper-0.27/lib/Scope/Upper.pm     2015-03-27 22:35:12.000000000 
+0100
@@ -11,13 +11,13 @@
 
 =head1 VERSION
 
-Version 0.24
+Version 0.27
 
 =cut
 
 our $VERSION;
 BEGIN {
- $VERSION = '0.24';
+ $VERSION = '0.27';
 }
 
 =head1 SYNOPSIS
@@ -792,6 +792,9 @@
 Moreover, in order to handle C<goto> statements properly, L</uplevel> 
currently has to suffer a run-time overhead proportional to the size of the 
callback in every case (with a small ratio), and proportional to the size of 
B<all> the code executed as the result of the L</uplevel> call (including 
subroutine calls inside the callback) when a C<goto> statement is found in the 
L</uplevel> callback.
 Despite this shortcoming, this XS version of L</uplevel> should still run way 
faster than the pure-Perl version from L<Sub::Uplevel>.
 
+Starting from C<perl> 5.19.4, it is unfortunately no longer possible to 
reliably throw exceptions from L</uplevel>'d code while the debugger is in use.
+This may be solved in a future version depending on how the core evolves.
+
 =head1 DEPENDENCIES
 
 L<perl> 5.6.1.
@@ -841,7 +844,7 @@
 
 =head1 COPYRIGHT & LICENSE
 
-Copyright 2008,2009,2010,2011,2012,2013 Vincent Pit, all rights reserved.
+Copyright 2008,2009,2010,2011,2012,2013,2014,2015 Vincent Pit, all rights 
reserved.
 
 This program is free software; you can redistribute it and/or modify it under 
the same terms as Perl itself.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Scope-Upper-0.24/t/09-load-threads.t 
new/Scope-Upper-0.27/t/09-load-threads.t
--- old/Scope-Upper-0.24/t/09-load-threads.t    1970-01-01 01:00:00.000000000 
+0100
+++ new/Scope-Upper-0.27/t/09-load-threads.t    2015-03-24 03:24:56.000000000 
+0100
@@ -0,0 +1,259 @@
+#!perl
+
+use strict;
+use warnings;
+
+use lib 't/lib';
+use VPIT::TestHelpers;
+
+my ($module, $thread_safe_var);
+BEGIN {
+ $module          = 'Scope::Upper';
+ $thread_safe_var = 'Scope::Upper::SU_THREADSAFE()';
+}
+
+sub load_test {
+ my $res;
+ {
+  my $var = 0;
+  if (defined &Scope::Upper::reap) {
+   &Scope::Upper::reap(sub { $var *= 2 });
+   $var = 1;
+  }
+  $res = $var;
+ }
+ if ($res == 2) {
+  return 1;
+ } elsif ($res == 1) {
+  return 2;
+ } else {
+  return $res;
+ }
+}
+
+# Keep the rest of the file untouched
+
+BEGIN {
+ my $is_threadsafe;
+
+ if (defined $thread_safe_var) {
+  my $stat = run_perl "require POSIX; require $module; exit($thread_safe_var ? 
POSIX::EXIT_SUCCESS() : POSIX::EXIT_FAILURE())";
+  if (defined $stat) {
+   require POSIX;
+   my $res  = $stat >> 8;
+   if ($res == POSIX::EXIT_SUCCESS()) {
+    $is_threadsafe = 1;
+   } elsif ($res == POSIX::EXIT_FAILURE()) {
+    $is_threadsafe = !1;
+   }
+  }
+  if (not defined $is_threadsafe) {
+   skip_all "Could not detect if $module is thread safe or not";
+  }
+ }
+
+ VPIT::TestHelpers->import(
+  threads => [ $module => $is_threadsafe ],
+ )
+}
+
+my $could_not_create_thread = 'Could not create thread';
+
+use Test::Leaner tests => 1 + (2 + 2 * 2) + 6 + (2 * 4) + 2;
+
+sub is_loaded {
+ my ($affirmative, $desc) = @_;
+
+ my $res = load_test();
+
+ if ($affirmative) {
+  is $res, 1, "$desc: module loaded";
+ } else {
+  is $res, 0, "$desc: module not loaded";
+ }
+}
+
+BEGIN {
+ local $@;
+ my $code = eval "sub { require $module }";
+ die $@ if $@;
+ *do_load = $code;
+}
+
+is_loaded 0, 'main body, beginning';
+
+# Test serial loadings
+
+SKIP: {
+ my $thr = spawn(sub {
+  my $here = "first serial thread";
+  is_loaded 0, "$here, beginning";
+
+  do_load;
+  is_loaded 1, "$here, after loading";
+
+  return;
+ });
+
+ skip "$could_not_create_thread (serial 1)" => 2 unless defined $thr;
+
+ $thr->join;
+ if (my $err = $thr->error) {
+  die $err;
+ }
+}
+
+is_loaded 0, 'main body, in between serial loadings';
+
+SKIP: {
+ my $thr = spawn(sub {
+  my $here = "second serial thread";
+  is_loaded 0, "$here, beginning";
+
+  do_load;
+  is_loaded 1, "$here, after loading";
+
+  return;
+ });
+
+ skip "$could_not_create_thread (serial 2)" => 2 unless defined $thr;
+
+ $thr->join;
+ if (my $err = $thr->error) {
+  die $err;
+ }
+}
+
+is_loaded 0, 'main body, after serial loadings';
+
+# Test nested loadings
+
+SKIP: {
+ my $thr = spawn(sub {
+  my $here = 'parent thread';
+  is_loaded 0, "$here, beginning";
+
+  SKIP: {
+   my $kid = spawn(sub {
+    my $here = 'child thread';
+    is_loaded 0, "$here, beginning";
+
+    do_load;
+    is_loaded 1, "$here, after loading";
+
+    return;
+   });
+
+   skip "$could_not_create_thread (nested child)" => 2 unless defined $kid;
+
+   $kid->join;
+   if (my $err = $kid->error) {
+    die "in child thread: $err\n";
+   }
+  }
+
+  is_loaded 0, "$here, after child terminated";
+
+  do_load;
+  is_loaded 1, "$here, after loading";
+
+  return;
+ });
+
+ skip "$could_not_create_thread (nested parent)" => (3 + 2) unless defined 
$thr;
+
+ $thr->join;
+ if (my $err = $thr->error) {
+  die $err;
+ }
+}
+
+is_loaded 0, 'main body, after nested loadings';
+
+# Test parallel loadings
+
+use threads;
+use threads::shared;
+
+my @locks = (1) x 5;
+share($_) for @locks;
+
+sub sync_master {
+ my ($id) = @_;
+
+ {
+  lock $locks[$id];
+  $locks[$id] = 0;
+  cond_broadcast $locks[$id];
+ }
+}
+
+sub sync_slave {
+ my ($id) = @_;
+
+ {
+  lock $locks[$id];
+  cond_wait $locks[$id] until $locks[$id] == 0;
+ }
+}
+
+SKIP: {
+ my $thr1 = spawn(sub {
+  my $here = 'first simultaneous thread';
+  is_loaded 0, "$here, beginning";
+  sync_slave 0;
+
+  do_load;
+  is_loaded 1, "$here, after loading";
+  sync_slave 1;
+  sync_slave 2;
+
+  sync_slave 3;
+  is_loaded 1, "$here, still loaded while also loaded in the other thread";
+  sync_slave 4;
+
+  is_loaded 1, "$here, end";
+
+  return;
+ });
+
+ skip "$could_not_create_thread (parallel 1)" => (4 * 2) unless defined $thr1;
+
+ my $thr2 = spawn(sub {
+  my $here = 'second simultaneous thread';
+  is_loaded 0, "$here, beginning";
+  sync_slave 0;
+
+  sync_slave 1;
+  is_loaded 0, "$here, loaded in other thread but not here";
+  sync_slave 2;
+
+  do_load;
+  is_loaded 1, "$here, after loading";
+  sync_slave 3;
+  sync_slave 4;
+
+  is_loaded 1, "$here, end";
+
+  return;
+ });
+
+ sync_master($_) for 0 .. $#locks;
+
+ $thr1->join;
+ if (my $err = $thr1->error) {
+  die $err;
+ }
+
+ skip "$could_not_create_thread (parallel 2)" => (4 * 1) unless defined $thr2;
+
+ $thr2->join;
+ if (my $err = $thr2->error) {
+  die $err;
+ }
+}
+
+is_loaded 0, 'main body, after simultaneous threads';
+
+do_load;
+is_loaded 1, 'main body, loaded at end';
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Scope-Upper-0.24/t/54-unwind-threads.t 
new/Scope-Upper-0.27/t/54-unwind-threads.t
--- old/Scope-Upper-0.24/t/54-unwind-threads.t  2011-10-22 19:36:05.000000000 
+0200
+++ new/Scope-Upper-0.27/t/54-unwind-threads.t  2015-03-19 19:35:42.000000000 
+0100
@@ -3,13 +3,16 @@
 use strict;
 use warnings;
 
+use Scope::Upper qw<unwind UP>;
+
 use lib 't/lib';
-use Scope::Upper::TestThreads;
+use VPIT::TestHelpers (
+ threads => [ 'Scope::Upper' => Scope::Upper::SU_THREADSAFE ],
+ 'usleep',
+);
 
 use Test::Leaner;
 
-use Scope::Upper qw<unwind UP>;
-
 our $z;
 
 sub up1 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Scope-Upper-0.24/t/59-yield-threads.t 
new/Scope-Upper-0.27/t/59-yield-threads.t
--- old/Scope-Upper-0.24/t/59-yield-threads.t   2012-09-13 22:50:39.000000000 
+0200
+++ new/Scope-Upper-0.27/t/59-yield-threads.t   2015-03-19 19:36:00.000000000 
+0100
@@ -3,13 +3,16 @@
 use strict;
 use warnings;
 
+use Scope::Upper qw<yield UP>;
+
 use lib 't/lib';
-use Scope::Upper::TestThreads;
+use VPIT::TestHelpers (
+ threads => [ 'Scope::Upper' => Scope::Upper::SU_THREADSAFE ],
+ 'usleep',
+);
 
 use Test::Leaner;
 
-use Scope::Upper qw<yield UP>;
-
 our $z;
 
 sub up1 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Scope-Upper-0.24/t/69-uplevel-threads.t 
new/Scope-Upper-0.27/t/69-uplevel-threads.t
--- old/Scope-Upper-0.24/t/69-uplevel-threads.t 2011-10-22 18:46:59.000000000 
+0200
+++ new/Scope-Upper-0.27/t/69-uplevel-threads.t 2015-03-19 19:36:15.000000000 
+0100
@@ -3,13 +3,16 @@
 use strict;
 use warnings;
 
+use Scope::Upper qw<uplevel UP>;
+
 use lib 't/lib';
-use Scope::Upper::TestThreads;
+use VPIT::TestHelpers (
+ threads => [ 'Scope::Upper' => Scope::Upper::SU_THREADSAFE ],
+ 'usleep',
+);
 
 use Test::Leaner;
 
-use Scope::Upper qw<uplevel UP>;
-
 sub depth {
  my $depth = 0;
  while (1) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Scope-Upper-0.24/t/79-uid-threads.t 
new/Scope-Upper-0.27/t/79-uid-threads.t
--- old/Scope-Upper-0.24/t/79-uid-threads.t     2011-10-22 18:49:03.000000000 
+0200
+++ new/Scope-Upper-0.27/t/79-uid-threads.t     2015-03-19 19:36:20.000000000 
+0100
@@ -3,13 +3,16 @@
 use strict;
 use warnings;
 
+use Scope::Upper qw<uid validate_uid UP HERE>;
+
 use lib 't/lib';
-use Scope::Upper::TestThreads;
+use VPIT::TestHelpers (
+ threads => [ 'Scope::Upper' => Scope::Upper::SU_THREADSAFE ],
+ 'usleep',
+);
 
 use Test::Leaner;
 
-use Scope::Upper qw<uid validate_uid UP HERE>;
-
 my $top = uid;
 
 sub cb {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Scope-Upper-0.24/t/lib/Scope/Upper/TestThreads.pm 
new/Scope-Upper-0.27/t/lib/Scope/Upper/TestThreads.pm
--- old/Scope-Upper-0.24/t/lib/Scope/Upper/TestThreads.pm       2013-06-03 
14:30:04.000000000 +0200
+++ new/Scope-Upper-0.27/t/lib/Scope/Upper/TestThreads.pm       1970-01-01 
01:00:00.000000000 +0100
@@ -1,68 +0,0 @@
-package Scope::Upper::TestThreads;
-
-use strict;
-use warnings;
-
-use Config qw<%Config>;
-
-use Scope::Upper qw<SU_THREADSAFE>;
-
-use VPIT::TestHelpers;
-
-sub diag {
- require Test::Leaner;
- Test::Leaner::diag(@_);
-}
-
-sub import {
- shift;
-
- skip_all 'This Scope::Upper isn\'t thread safe' unless SU_THREADSAFE;
-
- my $force = $ENV{PERL_SCOPE_UPPER_TEST_THREADS} ? 1 : !1;
- skip_all 'This perl wasn\'t built to support threads'
-                                                    unless 
$Config{useithreads};
- skip_all 'perl 5.13.4 required to test thread safety'
-                                             unless $force or "$]" >= 
5.013_004;
-
- load_or_skip_all('threads', $force ? '0' : '1.67', [ ]);
-
- my %exports = (
-  spawn => \&spawn,
- );
-
- my $usleep;
- if (do { local $@; eval { require Time::HiRes; 1 } }) {
-  defined and diag "Using Time::HiRes $_" for $Time::HiRes::VERSION;
-  $exports{usleep} = \&Time::HiRes::usleep;
- } else {
-  diag 'Using fallback usleep';
-  $exports{usleep} = sub {
-   my $s = int($_[0] / 2.5e5);
-   sleep $s if $s;
-  };
- }
-
- my $pkg = caller;
- while (my ($name, $code) = each %exports) {
-  no strict 'refs';
-  *{$pkg.'::'.$name} = $code;
- }
-}
-
-sub spawn {
- local $@;
- my @diag;
- my $thread = eval {
-  local $SIG{__WARN__} = sub { push @diag, "Thread creation warning: @_" };
-  threads->create(@_);
- };
- push @diag, "Thread creation error: $@" if $@;
- if (@diag) {
-  require Test::Leaner;
-  Test::Leaner::diag($_) for @diag;
- }
- return $thread ? $thread : ();
-}
-
-1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Scope-Upper-0.24/t/lib/VPIT/TestHelpers.pm 
new/Scope-Upper-0.27/t/lib/VPIT/TestHelpers.pm
--- old/Scope-Upper-0.24/t/lib/VPIT/TestHelpers.pm      2013-06-03 
14:30:04.000000000 +0200
+++ new/Scope-Upper-0.27/t/lib/VPIT/TestHelpers.pm      2015-03-24 
03:23:19.000000000 +0100
@@ -3,19 +3,58 @@
 use strict;
 use warnings;
 
-my %exports = (
+use Config ();
+
+sub export_to_pkg {
+ my ($subs, $pkg) = @_;
+
+ while (my ($name, $code) = each %$subs) {
+  no strict 'refs';
+  *{$pkg.'::'.$name} = $code;
+ }
+
+ return 1;
+}
+
+my %default_exports = (
  load_or_skip     => \&load_or_skip,
  load_or_skip_all => \&load_or_skip_all,
+ run_perl         => \&run_perl,
  skip_all         => \&skip_all,
 );
 
+my %features = (
+ threads => \&init_threads,
+ usleep  => \&init_usleep,
+);
+
 sub import {
- my $pkg = caller;
+ shift;
+ my @opts = @_;
 
- while (my ($name, $code) = each %exports) {
-  no strict 'refs';
-  *{$pkg.'::'.$name} = $code;
+ my %exports = %default_exports;
+
+ for (my $i = 0; $i <= $#opts; ++$i) {
+  my $feature = $opts[$i];
+  next unless defined $feature;
+
+  my $args;
+  if ($i < $#opts and defined $opts[$i+1] and ref $opts[$i+1] eq 'ARRAY') {
+   ++$i;
+   $args = $opts[$i];
+  } else {
+   $args = [ ];
+  }
+
+  my $handler = $features{$feature};
+  die "Unknown feature '$feature'" unless defined $handler;
+
+  my %syms = $handler->(@$args);
+
+  $exports{$_} = $syms{$_} for sort keys %syms;
  }
+
+ export_to_pkg \%exports => scalar caller;
 }
 
 my $test_sub = sub {
@@ -102,6 +141,91 @@
  return $loaded;
 }
 
+sub run_perl {
+ my $code = shift;
+
+ if ($code =~ /"/) {
+  die 'Double quotes in evaluated code are not portable';
+ }
+
+ my ($SystemRoot, $PATH) = @ENV{qw<SystemRoot PATH>};
+ my $ld_name  = $Config::Config{ldlibpthname};
+ my $ldlibpth = $ENV{$ld_name};
+
+ local %ENV;
+ $ENV{$ld_name}   = $ldlibpth   if                      defined $ldlibpth;
+ $ENV{SystemRoot} = $SystemRoot if $^O eq 'MSWin32' and defined $SystemRoot;
+ $ENV{PATH}       = $PATH       if $^O eq 'cygwin'  and defined $PATH;
+
+ my $perl = $^X;
+ unless (-e $perl and -x $perl) {
+  $perl = $Config::Config{perlpath};
+  unless (-e $perl and -x $perl) {
+   return undef;
+  }
+ }
+
+ system { $perl } $perl, '-T', map("-I$_", @INC), '-e', $code;
+}
+
+sub init_threads {
+ my ($pkg, $threadsafe, $force_var) = @_;
+
+ skip_all 'This perl wasn\'t built to support threads'
+                                            unless 
$Config::Config{useithreads};
+
+ $pkg = 'package' unless defined $pkg;
+ skip_all "This $pkg isn't thread safe" if defined $threadsafe and 
!$threadsafe;
+
+ $force_var = 'PERL_FORCE_TEST_THREADS' unless defined $force_var;
+ my $force  = $ENV{$force_var} ? 1 : !1;
+ skip_all 'perl 5.13.4 required to test thread safety'
+                                             unless $force or "$]" >= 
5.013_004;
+
+ if (($INC{'Test/More.pm'} || $INC{'Test/Leaner.pm'}) && !$INC{'threads.pm'}) {
+  die 'Test::More/Test::Leaner was loaded too soon';
+ }
+
+ load_or_skip_all 'threads',         $force ? '0' : '1.67', [ ];
+ load_or_skip_all 'threads::shared', $force ? '0' : '1.14', [ ];
+
+ require Test::Leaner;
+
+ diag "Threads testing forced by \$ENV{$force_var}" if $force;
+
+ return spawn => \&spawn;
+}
+
+sub init_usleep {
+ my $usleep;
+
+ if (do { local $@; eval { require Time::HiRes; 1 } }) {
+  defined and diag "Using usleep() from Time::HiRes $_"
+                                                      for 
$Time::HiRes::VERSION;
+  $usleep = \&Time::HiRes::usleep;
+ } else {
+  diag 'Using fallback usleep()';
+  $usleep = sub {
+   my $s = int($_[0] / 2.5e5);
+   sleep $s if $s;
+  };
+ }
+
+ return usleep => $usleep;
+}
+
+sub spawn {
+ local $@;
+ my @diag;
+ my $thread = eval {
+  local $SIG{__WARN__} = sub { push @diag, "Thread creation warning: @_" };
+  threads->create(@_);
+ };
+ push @diag, "Thread creation error: $@" if $@;
+ diag @diag;
+ return $thread ? $thread : ();
+}
+
 package VPIT::TestHelpers::Guard;
 
 sub new {


Reply via email to