automake-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Automake-commit] [SCM] GNU Automake branch, master, updated. Release-1-


From: Ralf Wildenhues
Subject: [Automake-commit] [SCM] GNU Automake branch, master, updated. Release-1-10-201-gc15d9a8
Date: Sun, 19 Oct 2008 18:07:36 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Automake".

http://git.sv.gnu.org/gitweb/?p=automake.git;a=commitdiff;h=c15d9a8e130cd79e9d79a8ede5a8f431ead5216f

The branch, master has been updated
       via  c15d9a8e130cd79e9d79a8ede5a8f431ead5216f (commit)
      from  b6af214094ead458695113c17d7a2cade7c54dbc (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit c15d9a8e130cd79e9d79a8ede5a8f431ead5216f
Author: Ralf Wildenhues <address@hidden>
Date:   Sun Oct 19 19:54:12 2008 +0200

    Fix DisjConditions module to be thread-safe for perl >= 5.7.2.
    
    Self-hashes of blessed references are not correctly transported
    through thread creation.  This patch fixes that by recreating
    the hashes upon thread creation with a CLONE special subroutine,
    which is automatically invoked by new enough Perl versions.
    * lib/Automake/DisjConditions.pm (CLONE): New special
    subroutine to fix self hashes upon thread creation.
    * lib/Automake/tests/Condition-t.pl: New, sister test to
    Condition.pl, but spawns a new threads after each creation of a
    new condition; skip test if perl is too old or ithreads are not
    available.
    * lib/Automake/tests/DisjConditions-t.pl: Likewise.
    * lib/Automake/tests/Makefile.am (TESTS): Add them.
    
    Signed-off-by: Ralf Wildenhues <address@hidden>

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                                          |   16 ++
 lib/Automake/DisjConditions.pm                     |   20 ++
 .../tests/{Condition.pl => Condition-t.pl}         |  138 +++++++++-----
 .../{DisjConditions.pl => DisjConditions-t.pl}     |  198 ++++++++++++-------
 lib/Automake/tests/Makefile.am                     |    4 +-
 lib/Automake/tests/Makefile.in                     |    2 +
 6 files changed, 255 insertions(+), 123 deletions(-)
 copy lib/Automake/tests/{Condition.pl => Condition-t.pl} (74%)
 copy lib/Automake/tests/{DisjConditions.pl => DisjConditions-t.pl} (74%)

diff --git a/ChangeLog b/ChangeLog
index 6c90529..9edc057 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2008-10-19  Ralf Wildenhues  <address@hidden>
+
+       Fix DisjConditions module to be thread-safe for perl >= 5.7.2.
+       Self-hashes of blessed references are not correctly transported
+       through thread creation.  This patch fixes that by recreating
+       the hashes upon thread creation with a CLONE special subroutine,
+       which is automatically invoked by new enough Perl versions.
+       * lib/Automake/DisjConditions.pm (CLONE): New special
+       subroutine to fix self hashes upon thread creation.
+       * lib/Automake/tests/Condition-t.pl: New, sister test to
+       Condition.pl, but spawns a new threads after each creation of a
+       new condition; skip test if perl is too old or ithreads are not
+       available.
+       * lib/Automake/tests/DisjConditions-t.pl: Likewise.
+       * lib/Automake/tests/Makefile.am (TESTS): Add them.
+
 2008-10-18  Ralf Wildenhues  <address@hidden>
 
        Fix comment typos.
diff --git a/lib/Automake/DisjConditions.pm b/lib/Automake/DisjConditions.pm
index 1f09c0f..ae759e2 100644
--- a/lib/Automake/DisjConditions.pm
+++ b/lib/Automake/DisjConditions.pm
@@ -192,6 +192,26 @@ sub new ($;@)
   return $self;
 }
 
+
+=item C<CLONE>
+
+Internal special subroutine to fix up the self hashes in
+C<%_disjcondition_singletons> upon thread creation.  C<CLONE> is invoked
+automatically with ithreads from Perl 5.7.2 or later, so if you use this
+module with earlier versions of Perl, it is not thread-safe.
+
+=cut
+
+sub CLONE
+{
+  foreach my $self (values %_disjcondition_singletons)
+    {
+      my %h = map { $_ => $_ } @{$self->{'conds'}};
+      $self->{'hash'} = \%h;
+    }
+}
+
+
 =item C<@conds = $set-E<gt>conds>
 
 Return the list of C<Condition> objects involved in C<$set>.
diff --git a/lib/Automake/tests/Condition.pl b/lib/Automake/tests/Condition-t.pl
similarity index 74%
copy from lib/Automake/tests/Condition.pl
copy to lib/Automake/tests/Condition-t.pl
index 27a9067..8b632fa 100644
--- a/lib/Automake/tests/Condition.pl
+++ b/lib/Automake/tests/Condition-t.pl
@@ -1,4 +1,4 @@
-# Copyright (C) 2001, 2002, 2003  Free Software Foundation, Inc.
+# Copyright (C) 2001, 2002, 2003, 2008  Free Software Foundation, Inc.
 #
 # This file is part of GNU Automake.
 #
@@ -15,6 +15,18 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+BEGIN {
+  use Config;
+  if (eval { require 5.007_002; }      # for CLONE support
+      && $Config{useithreads})
+    {
+      use threads;
+    }
+  else
+    {
+      exit 77;
+    }
+}
 use Automake::Condition qw/TRUE FALSE/;
 
 sub test_basics ()
@@ -32,12 +44,15 @@ sub test_basics ()
   for (@tests)
     {
       my $a = new Automake::Condition @{$_->[0]};
-      return 1 if $_->[1] != $a->true;
-      return 1 if $_->[1] != ($a == TRUE);
-      return 1 if $_->[2] != $a->false;
-      return 1 if $_->[2] != ($a == FALSE);
-      return 1 if $_->[3] ne $a->string;
-      return 1 if $_->[4] ne $a->subst_string;
+      return 1
+        if threads->new(sub {
+         return 1 if $_->[1] != $a->true;
+         return 1 if $_->[1] != ($a == TRUE);
+         return 1 if $_->[2] != $a->false;
+         return 1 if $_->[2] != ($a == FALSE);
+         return 1 if $_->[3] ne $a->string;
+         return 1 if $_->[4] ne $a->subst_string;
+       })->join;
     }
   return 0;
 }
@@ -62,28 +77,37 @@ sub test_true_when ()
   for my $t (@tests)
     {
       my $a = new Automake::Condition @{$t->[0]};
-      for my $u (@{$t->[1]})
-       {
-         my $b = new Automake::Condition @$u;
-         if (! $b->true_when ($a))
+      return 1
+        if threads->new(sub {
+         for my $u (@{$t->[1]})
            {
-             print "`" . $b->string .
-               "' not implied by `" . $a->string . "'?\n";
-             $failed = 1;
+             my $b = new Automake::Condition @$u;
+             return threads->new(sub {
+               if (! $b->true_when ($a))
+                 {
+                   print "`" . $b->string .
+                     "' not implied by `" . $a->string . "'?\n";
+                   $failed = 1;
+                 }
+             })->join;
            }
-       }
-      for my $u (@{$t->[2]})
-       {
-         my $b = new Automake::Condition @$u;
-         if ($b->true_when ($a))
+         for my $u (@{$t->[2]})
            {
-             print "`" . $b->string .
-               "' implied by `" . $a->string . "'?\n";
-             $failed = 1;
-           }
+             my $b = new Automake::Condition @$u;
+             return threads->new(sub {
+               if ($b->true_when ($a))
+                 {
+                   print "`" . $b->string .
+                     "' implied by `" . $a->string . "'?\n";
+                   $failed = 1;
+                 }
 
-         return 1 if $b->true_when ($a);
-       }
+               return threads->new(sub {
+                 return 1 if $b->true_when ($a);
+               })->join;
+             })->join;
+           }
+        })->join;
     }
   return $failed;
 }
@@ -147,19 +171,27 @@ sub test_reduce_and ()
     {
       my ($inref, $outref) = @$_;
       my @inconds = map { new Automake::Condition $_ } @$inref;
-      my @outconds = map { (new Automake::Condition $_)->string } @$outref;
-      my @res =
-       map { $_->string } (Automake::Condition::reduce_and (@inconds));
-      my $result = join (",", sort @res);
-      my $exresult = join (",", @outconds);
+      return 1
+        if threads->new(sub {
+         my @outconds = map { (new Automake::Condition $_)->string } @$outref;
+         return threads->new(sub {
+           my @res =
+             map { $_->string } (Automake::Condition::reduce_and (@inconds));
+           return threads->new(sub {
+             my $result = join (",", sort @res);
+             my $exresult = join (",", @outconds);
 
-      if ($result ne $exresult)
-       {
-         print '"' . join(",", @$inref) . '" => "' .
-           $result . '" expected "' .
-             $exresult . '"' . "\n";
-         $failed = 1;
-       }
+             if ($result ne $exresult)
+               {
+                 print '"' . join(",", @$inref) . '" => "' .
+                   $result . '" expected "' .
+                     $exresult . '"' . "\n";
+                 $failed = 1;
+               }
+             return $failed;
+           })->join;
+         })->join;
+       })->join;
     }
   return $failed;
 }
@@ -223,19 +255,27 @@ sub test_reduce_or ()
     {
       my ($inref, $outref) = @$_;
       my @inconds = map { new Automake::Condition $_ } @$inref;
-      my @outconds = map { (new Automake::Condition $_)->string } @$outref;
-      my @res =
-       map { $_->string } (Automake::Condition::reduce_or (@inconds));
-      my $result = join (",", sort @res);
-      my $exresult = join (",", @outconds);
+      return 1
+        if threads->new(sub {
+         my @outconds = map { (new Automake::Condition $_)->string } @$outref;
+         return threads->new(sub {
+           my @res =
+             map { $_->string } (Automake::Condition::reduce_or (@inconds));
+           return threads->new(sub {
+             my $result = join (",", sort @res);
+             my $exresult = join (",", @outconds);
 
-      if ($result ne $exresult)
-       {
-         print '"' . join(",", @$inref) . '" => "' .
-           $result . '" expected "' .
-             $exresult . '"' . "\n";
-         $failed = 1;
-       }
+             if ($result ne $exresult)
+               {
+                 print '"' . join(",", @$inref) . '" => "' .
+                   $result . '" expected "' .
+                     $exresult . '"' . "\n";
+                 $failed = 1;
+               }
+             return $failed;
+           })->join;
+         })->join;
+       })->join;
     }
   return $failed;
 }
diff --git a/lib/Automake/tests/DisjConditions.pl 
b/lib/Automake/tests/DisjConditions-t.pl
similarity index 74%
copy from lib/Automake/tests/DisjConditions.pl
copy to lib/Automake/tests/DisjConditions-t.pl
index 6e18683..2b8ca3e 100644
--- a/lib/Automake/tests/DisjConditions.pl
+++ b/lib/Automake/tests/DisjConditions-t.pl
@@ -15,20 +15,38 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+BEGIN {
+  use Config;
+  if (eval { require 5.007_002; }      # for CLONE support
+      && $Config{useithreads})
+    {
+      use threads;
+    }
+  else
+    {
+      exit 77;
+    }
+}
 use Automake::Condition qw/TRUE FALSE/;
 use Automake::DisjConditions;
 
 sub test_basics ()
 {
   my $cond = new Automake::Condition "COND1_TRUE", "COND2_FALSE";
-  my $other = new Automake::Condition "COND3_FALSE";
-  my $set1 = new Automake::DisjConditions $cond, $other;
-  my $set2 = new Automake::DisjConditions $other, $cond;
-  return 1 unless $set1 == $set2;
-  return 1 if $set1->false;
-  return 1 if $set1->true;
-  return 1 unless (new Automake::DisjConditions)->false;
-  return 1 if (new Automake::DisjConditions)->true;
+  return threads->new (sub {
+    my $other = new Automake::Condition "COND3_FALSE";
+    return threads->new (sub {
+      my $set1 = new Automake::DisjConditions $cond, $other;
+      return threads->new (sub {
+       my $set2 = new Automake::DisjConditions $other, $cond;
+       return 1 unless $set1 == $set2;
+       return 1 if $set1->false;
+       return 1 if $set1->true;
+       return 1 unless (new Automake::DisjConditions)->false;
+       return 1 if (new Automake::DisjConditions)->true;
+      })->join;
+    })->join;
+  })->join;
 }
 
 sub build_set (@)
@@ -72,14 +90,18 @@ sub test_invert ()
   for my $t (@tests)
     {
       my $set = build_set @{$t->[0]};
-      my $res = build_set @{$t->[1]};
-      my $inv = $set->invert;
-      if ($inv != $res)
-       {
-         print " (I) " . $set->string . "\n\t"
-           . $inv->string . ' != ' . $res->string . "\n";
-         return 1;
-       }
+      return 1
+        if threads->new(sub {
+         my $res = build_set @{$t->[1]};
+         my $inv = $set->invert;
+         if ($inv != $res)
+           {
+             print " (I) " . $set->string . "\n\t"
+               . $inv->string . ' != ' . $res->string . "\n";
+             return 1;
+           }
+         return 0
+       })-> join;
     }
   return 0;
 }
@@ -215,36 +237,49 @@ sub test_simplify ()
   for my $t (@tests)
     {
       my $set = build_set @{$t->[0]};
-      my $res = build_set @{$t->[1]};
-
-      # Make sure simplify() yields the expected result.
-      my $sim = $set->simplify;
-      if ($sim != $res)
-       {
-         print " (S1) " . $set->string . "\n\t"
-           . $sim->string . ' != ' . $res->string . "\n";
-         return 1;
-       }
-
-      # Make sure simplify() is idempotent.
-      my $sim2 = $sim->simplify;
-      if ($sim2 != $sim)
-       {
-         print " (S2) " . $sim->string . "\n\t"
-           . $sim2->string . ' != ' . $sim->string . "\n";
-         return 1;
-       }
-
-      # Also exercise invert() while we are at it.
-
-      my $inv1 = $set->invert->simplify;
-      my $inv2 = $sim->invert->simplify;
-      if ($inv1 != $inv2)
-       {
-         print " (S3) " . $set->string . ", " . $sim->string . "\n\t"
-           . $inv1->string . ' != ' . $inv2->string . "\n";
-         return 1;
-       }
+      return 1
+       if threads->new(sub {
+         my $res = build_set @{$t->[1]};
+         return threads->new(sub {
+
+           # Make sure simplify() yields the expected result.
+           my $sim = $set->simplify;
+           return threads->new(sub {
+             if ($sim != $res)
+               {
+                 print " (S1) " . $set->string . "\n\t"
+                   . $sim->string . ' != ' . $res->string . "\n";
+                 return 1;
+               }
+
+             # Make sure simplify() is idempotent.
+             my $sim2 = $sim->simplify;
+             return threads->new(sub {
+               if ($sim2 != $sim)
+                 {
+                   print " (S2) " . $sim->string . "\n\t"
+                     . $sim2->string . ' != ' . $sim->string . "\n";
+                   return 1;
+                 }
+
+               # Also exercise invert() while we are at it.
+
+               my $inv1 = $set->invert->simplify;
+               return threads->new(sub {
+                 my $inv2 = $sim->invert->simplify;
+                 return threads->new(sub {
+                   if ($inv1 != $inv2)
+                     {
+                       print " (S3) " . $set->string . ", " . $sim->string . 
"\n\t"
+                         . $inv1->string . ' -= ' . $inv2->string . "\n";
+                       return 1;
+                     }
+                 })->join;
+               })->join;
+             })->join;
+           })->join;
+         })->join;
+       })->join;
     }
 
   return 0;
@@ -298,17 +333,26 @@ sub test_sub_conditions ()
   for my $t (@tests)
     {
       my $t1 = build_set @{$t->[0]};
-      my $t2 = new Automake::Condition @{$t->[1]};
-      my $t3 = build_set @{$t->[2]};
-
-      # Make sure sub_conditions() yields the expected result.
-      my $s = $t1->sub_conditions ($t2);
-      if ($s != $t3)
-       {
-         print " (SC) " . $t1->string . "\n\t"
-           . $s->string . ' != ' . $t3->string . "\n";
-         return 1;
-       }
+      return 1
+        if threads->new(sub {
+         my $t2 = new Automake::Condition @{$t->[1]};
+         return threads->new(sub {
+           my $t3 = build_set @{$t->[2]};
+           return threads->new(sub {
+
+             # Make sure sub_conditions() yields the expected result.
+             my $s = $t1->sub_conditions ($t2);
+             threads->new(sub {
+               if ($s != $t3)
+                 {
+                   print " (SC) " . $t1->string . "\n\t"
+                     . $s->string . ' != ' . $t3->string . "\n";
+                   return 1;
+                 }
+             })->join;
+           })->join;
+         })->join;
+       })->join;
     }
 }
 
@@ -337,26 +381,34 @@ sub test_ambig ()
                ["C1_FALSE", "C2_TRUE"],
                '']);
 
+  my $failed = 0;
   for my $t (@tests)
     {
       my $t1 = build_set @{$t->[0]};
-      my $t2 = new Automake::Condition @{$t->[1]};
-      my $t3 = $t->[2];
-      my ($ans, $cond) = $t1->ambiguous_p ("FOO", $t2);
-      if ($t3 && $ans !~ /FOO.*$t3/)
-       {
-         print " (A1) " . $t1->string . " vs. " . $t2->string . "\n\t"
-           . "Error message '$ans' does not match '$t3'\n";
-         return 1;
-       }
-      if (!$t3 && $ans ne '')
-       {
-         print " (A2) " . $t1->string . " vs. " . $t2->string . "\n\t"
-           . "Unexpected error message: $ans\n";
-         return 1;
-       }
+      $failed = 1
+        if threads->new(sub {
+         my $t2 = new Automake::Condition @{$t->[1]};
+         my $t3 = $t->[2];
+         return threads->new(sub {
+           my ($ans, $cond) = $t1->ambiguous_p ("FOO", $t2);
+           return threads->new(sub {
+             if ($t3 && $ans !~ /FOO.*$t3/)
+               {
+                 print " (A1) " . $t1->string . " vs. " . $t2->string . "\n\t"
+                   . "Error message '$ans' does not match '$t3'\n";
+                 return 1;
+               }
+             if (!$t3 && $ans ne '')
+               {
+                 print " (A2) " . $t1->string . " vs. " . $t2->string . "\n\t"
+                   . "Unexpected error message: $ans\n";
+                 return 1;
+               }
+           })->join;
+         })->join;
+       })->join;
     }
-  return 0;
+  return $failed;
 }
 
 exit (test_basics
diff --git a/lib/Automake/tests/Makefile.am b/lib/Automake/tests/Makefile.am
index 705f195..529a02f 100644
--- a/lib/Automake/tests/Makefile.am
+++ b/lib/Automake/tests/Makefile.am
@@ -1,6 +1,6 @@
 ## Process this file with automake to create Makefile.in
 
-## Copyright (C) 2002, 2003  Free Software Foundation, Inc.
+## Copyright (C) 2002, 2003, 2008  Free Software Foundation, Inc.
 
 ## This program is free software; you can redistribute it and/or modify
 ## it under the terms of the GNU General Public License as published by
@@ -18,7 +18,9 @@
 TESTS_ENVIRONMENT = $(PERL) -Mstrict -I $(top_srcdir)/lib -w
 TESTS = \
 Condition.pl \
+Condition-t.pl \
 DisjConditions.pl \
+DisjConditions-t.pl \
 Version.pl \
 Wrap.pl
 
diff --git a/lib/Automake/tests/Makefile.in b/lib/Automake/tests/Makefile.in
index 2c52e82..087301f 100644
--- a/lib/Automake/tests/Makefile.in
+++ b/lib/Automake/tests/Makefile.in
@@ -154,7 +154,9 @@ top_srcdir = @top_srcdir@
 TESTS_ENVIRONMENT = $(PERL) -Mstrict -I $(top_srcdir)/lib -w
 TESTS = \
 Condition.pl \
+Condition-t.pl \
 DisjConditions.pl \
+DisjConditions-t.pl \
 Version.pl \
 Wrap.pl
 


hooks/post-receive
--
GNU Automake




reply via email to

[Prev in Thread] Current Thread [Next in Thread]