]> git.vpit.fr Git - perl/modules/indirect.git/commitdiff
Test asymetrical thread termination
authorVincent Pit <vince@profvince.com>
Mon, 6 Apr 2015 18:46:40 +0000 (15:46 -0300)
committerVincent Pit <vince@profvince.com>
Mon, 6 Apr 2015 18:46:40 +0000 (15:46 -0300)
t/09-load-threads.t

index 673f5cf0691641632100ae2e44aa8cadc4ffc905..0d474d58d449b74a52468af90f470aee14c7fbc0 100644 (file)
@@ -58,7 +58,7 @@ BEGIN {
 
 my $could_not_create_thread = 'Could not create thread';
 
-use Test::Leaner tests => 1 + (2 + 2 * 2) + 6 + (2 * 4) + 2;
+use Test::Leaner tests => 1 + (2 + 2 * 2) + 6 + (2 * 4 + 1) * 2 + 1;
 
 sub is_loaded {
  my ($affirmative, $desc) = @_;
@@ -185,14 +185,18 @@ is_loaded 0, 'main body, after nested loadings';
 use threads;
 use threads::shared;
 
-my @locks_down = (1) x 6;
-my @locks_up   = (0) x scalar @locks_down;
+my $sync_points = 7;
+
+my @locks_down = (1) x $sync_points;
+my @locks_up   = (0) x $sync_points;
 share($_) for @locks_down, @locks_up;
 
-my $peers = 2;
+my $default_peers = 2;
 
 sub sync_master {
- my ($id) = @_;
+ my ($id, $peers) = @_;
+
+ $peers = $default_peers unless defined $peers;
 
  {
   lock $locks_down[$id];
@@ -221,67 +225,103 @@ sub sync_slave {
  }
 }
 
-SKIP: {
- my $thr1 = spawn(sub {
-  my $here = 'first simultaneous thread';
-  sync_slave 0;
+for my $first_thread_ends_first (0, 1) {
+ for my $id (0 .. $sync_points - 1) {
+  {
+   lock $locks_down[$id];
+   $locks_down[$id] = 1;
+  }
+  {
+   lock $locks_up[$id];
+   $locks_up[$id] = 0;
+  }
+ }
 
 is_loaded 0, "$here, beginning";
 sync_slave 1;
my $thr1_end = 'finishes first';
my $thr2_end = 'finishes last';
 
-  do_load;
-  is_loaded 1, "$here, after loading";
-  sync_slave 2;
-  sync_slave 3;
+ ($thr1_end, $thr2_end) = ($thr2_end, $thr1_end)
+                                                unless $first_thread_ends_first;
 
-  sync_slave 4;
-  is_loaded 1, "$here, still loaded while also loaded in the other thread";
-  sync_slave 5;
+ SKIP: {
+  my $thr1 = spawn(sub {
+   my $here = "first simultaneous thread ($thr1_end)";
+   sync_slave 0;
 
-  is_loaded 1, "$here, end";
+   is_loaded 0, "$here, beginning";
+   sync_slave 1;
 
-  return;
- });
+   do_load;
+   is_loaded 1, "$here, after loading";
+   sync_slave 2;
+   sync_slave 3;
 
- skip "$could_not_create_thread (parallel 1)" => (4 * 2) unless defined $thr1;
+   sync_slave 4;
+   is_loaded 1, "$here, still loaded while also loaded in the other thread";
+   sync_slave 5;
 
- my $thr2 = spawn(sub {
-  my $here = 'second simultaneous thread';
-  sync_slave 0;
+   sync_slave 6 unless $first_thread_ends_first;
 
-  is_loaded 0, "$here, beginning";
-  sync_slave 1;
+   is_loaded 1, "$here, end";
 
-  sync_slave 2;
-  sync_slave 3;
-  is_loaded 0, "$here, loaded in other thread but not here";
+   return;
+  });
 
-  do_load;
-  is_loaded 1, "$here, after loading";
-  sync_slave 4;
-  sync_slave 5;
+  skip "$could_not_create_thread (parallel 1)" => (4 * 2) unless defined $thr1;
 
-  is_loaded 1, "$here, end";
+  my $thr2 = spawn(sub {
+   my $here = "second simultaneous thread ($thr2_end)";
+   sync_slave 0;
 
-  return;
});
+   is_loaded 0, "$here, beginning";
  sync_slave 1;
 
- sync_master($_) for 0 .. $#locks_down;
+   sync_slave 2;
+   sync_slave 3;
+   is_loaded 0, "$here, loaded in other thread but not here";
 
$thr1->join;
- if (my $err = $thr1->error) {
-  die $err;
- }
  do_load;
+   is_loaded 1, "$here, after loading";
+   sync_slave 4;
+   sync_slave 5;
 
skip "$could_not_create_thread (parallel 2)" => (4 * 1) unless defined $thr2;
  sync_slave 6 if $first_thread_ends_first;
 
- $thr2->join;
- if (my $err = $thr2->error) {
-  die $err;
+   is_loaded 1, "$here, end";
+
+   return;
+  });
+
+  sync_master($_) for 0 .. 5;
+
+  if (defined $thr2) {
+   ($thr2, $thr1) = ($thr1, $thr2) unless $first_thread_ends_first;
+
+   $thr1->join;
+   if (my $err = $thr1->error) {
+    die $err;
+   }
+
+   sync_master(6, 1);
+
+   $thr2->join;
+   if (my $err = $thr1->error) {
+    die $err;
+   }
+  } else {
+   sync_master(6, 1) unless $first_thread_ends_first;
+
+   $thr1->join;
+   if (my $err = $thr1->error) {
+    die $err;
+   }
+
+   skip "$could_not_create_thread (parallel 2)" => (4 * 1);
+  }
  }
-}
 
-is_loaded 0, 'main body, after simultaneous threads';
+ is_loaded 0, 'main body, after simultaneous threads';
+}
 
 do_load;
 is_loaded 1, 'main body, loaded at end';