Re: 5.8.3-RC1, ext/threads/shared/t/wait still hanging
Mike Pomraning [Sun, 11 Jan 2004 16:24:18 +0000 (10:24 -0600)]
Message-ID: <Pine.LNX.4.58.0401111548010.6679@localhost.localdomain>
Date: Sun, 11 Jan 2004 16:24:18 -0600 (CST)

p4raw-id: //depot/perl@22115

ext/threads/shared/t/wait.t

index fe74c68..0389514 100644 (file)
@@ -13,7 +13,7 @@ BEGIN {
     }
 }
 $|++;
-print "1..90\n";
+print "1..102\n";
 use strict;
 
 use threads;
@@ -51,6 +51,7 @@ SYNC_SHARED: {
   my $cond : shared;
   my $lock : shared;
 
+  print "# testing my \$var : shared\n";
   ok(1, 1, "Shared synchronization tests preparation");
   $Base += 1;
 
@@ -71,23 +72,28 @@ SYNC_SHARED: {
   foreach (@wait_how) {
     $test = "cond_wait [$_]";
     threads->create(\&cw)->join;
-    $Base += 5;
+    $Base += 6;
   }
 
   sub cw {
-    ## which lock to obtain in this scope?
-    $test =~ /twain/ ? lock($lock) : lock($cond);
-    ok(1,1, "$test: obtained initial lock");
+    my $thr;
+
+    { # -- begin lock scope; which lock to obtain?
+      $test =~ /twain/ ? lock($lock) : lock($cond);
+      ok(1,1, "$test: obtained initial lock");
+
+      $thr = threads->create(\&signaller);
+      for ($test) {
+        cond_wait($cond), last        if    /simple/;
+        cond_wait($cond, $cond), last if    /repeat/;
+        cond_wait($cond, $lock), last if    /twain/;
+        die "$test: unknown test\n"; 
+      }
+      ok(5,1, "$test: condition obtained");
+    } # -- end lock scope
 
-    my $thr = threads->create(\&signaller);
-    for ($test) {
-      cond_wait($cond), last        if    /simple/;
-      cond_wait($cond, $cond), last if    /repeat/;
-      cond_wait($cond, $lock), last if    /twain/;
-      die "$test: unknown test\n"; 
-    }
     $thr->join;
-    ok(5,1, "$test: condition obtained");
+    ok(6,1, "$test: join completed");
   }
 
   # - TEST cond_timedwait success
@@ -95,32 +101,30 @@ SYNC_SHARED: {
   foreach (@wait_how) {
     $test = "cond_timedwait [$_]";
     threads->create(\&ctw, 5)->join;
-    $Base += 5;
+    $Base += 6;
   }
 
   sub ctw($) {
     my $to = shift;
+    my $thr;
+
+    { # -- begin lock scope;  which lock to obtain?
+      $test =~ /twain/ ? lock($lock) : lock($cond);
+      ok(1,1, "$test: obtained initial lock");
+
+      $thr = threads->create(\&signaller);
+      my $ok = 0;
+      for ($test) {
+        $ok=cond_timedwait($cond, time() + $to), last        if    /simple/;
+        $ok=cond_timedwait($cond, time() + $to, $cond), last if    /repeat/;
+        $ok=cond_timedwait($cond, time() + $to, $lock), last if    /twain/;
+        die "$test: unknown test\n"; 
+      }
+      ok(5,$ok, "$test: condition obtained");
+    } # -- end lock scope
 
-    ## which lock to obtain in this scope?
-    $test =~ /twain/ ? lock($lock) : lock($cond);
-    ok(1,1, "$test: obtained initial lock");
-
-    my $thr = threads->create(\&signaller);
-    ### N.B.: RACE!  If $timeout is very soon and/or we are unlucky, we
-    ###       might timeout on the cond_timedwait before the signaller
-    ###       thread even attempts lock()ing.
-    ###       Upshot:  $thr->join() never completes, because signaller is
-    ###       stuck attempting to lock the mutex we regained after waiting.
-    my $ok = 0;
-    for ($test) {
-      $ok=cond_timedwait($cond, time() + $to), last        if    /simple/;
-      $ok=cond_timedwait($cond, time() + $to, $cond), last if    /repeat/;
-      $ok=cond_timedwait($cond, time() + $to, $lock), last if    /twain/;
-      die "$test: unknown test\n"; 
-    }
-    print "# back from cond_timedwait; join()ing\n";
     $thr->join;
-    ok(5,$ok, "$test: condition obtained");
+    ok(6,1, "$test: join completed");
   }
 
   # - TEST cond_timedwait timeout
@@ -167,6 +171,7 @@ SYNCH_REFS: {
   my $cond = \$true_cond;
   my $lock = \$true_lock;
 
+  print "# testing reference to shared(\$var)\n";
   ok(1, 1, "Synchronization reference tests preparation");
   $Base += 1;
 
@@ -187,23 +192,28 @@ SYNCH_REFS: {
   foreach (@wait_how) {
     $test = "cond_wait [$_]";
     threads->create(\&cw2)->join;
-    $Base += 5;
+    $Base += 6;
   }
 
   sub cw2 {
-    ## which lock to obtain in this scope?
-    $test =~ /twain/ ? lock($lock) : lock($cond);
-    ok(1,1, "$test: obtained initial lock");
+    my $thr;
+
+    { # -- begin lock scope; which lock to obtain?
+      $test =~ /twain/ ? lock($lock) : lock($cond);
+      ok(1,1, "$test: obtained initial lock");
+
+      $thr = threads->create(\&signaller2);
+      for ($test) {
+        cond_wait($cond), last        if    /simple/;
+        cond_wait($cond, $cond), last if    /repeat/;
+        cond_wait($cond, $lock), last if    /twain/;
+        die "$test: unknown test\n"; 
+      }
+      ok(5,1, "$test: condition obtained");
+    } # -- end lock scope
 
-    my $thr = threads->create(\&signaller2);
-    for ($test) {
-      cond_wait($cond), last        if    /simple/;
-      cond_wait($cond, $cond), last if    /repeat/;
-      cond_wait($cond, $lock), last if    /twain/;
-      die "$test: unknown test\n"; 
-    }
     $thr->join;
-    ok(5,1, "$test: condition obtained");
+    ok(6,1, "$test: join completed");
   }
 
   # - TEST cond_timedwait success
@@ -211,27 +221,30 @@ SYNCH_REFS: {
   foreach (@wait_how) {
     $test = "cond_timedwait [$_]";
     threads->create(\&ctw2, 5)->join;
-    $Base += 5;
+    $Base += 6;
   }
 
   sub ctw2($) {
     my $to = shift;
+    my $thr;
+
+    { # -- begin lock scope;  which lock to obtain?
+      $test =~ /twain/ ? lock($lock) : lock($cond);
+      ok(1,1, "$test: obtained initial lock");
+
+      $thr = threads->create(\&signaller2);
+      my $ok = 0;
+      for ($test) {
+        $ok=cond_timedwait($cond, time() + $to), last        if    /simple/;
+        $ok=cond_timedwait($cond, time() + $to, $cond), last if    /repeat/;
+        $ok=cond_timedwait($cond, time() + $to, $lock), last if    /twain/;
+        die "$test: unknown test\n"; 
+      }
+      ok(5,$ok, "$test: condition obtained");
+    } # -- end lock scope
 
-    ## which lock to obtain in this scope?
-    $test =~ /twain/ ? lock($lock) : lock($cond);
-    ok(1,1, "$test: obtained initial lock");
-
-    my $thr = threads->create(\&signaller2);
-    ###  N.B.:  RACE!  as above, with ctw()
-    my $ok = 0;
-    for ($test) {
-      $ok=cond_timedwait($cond, time() + $to), last        if    /simple/;
-      $ok=cond_timedwait($cond, time() + $to, $cond), last if    /repeat/;
-      $ok=cond_timedwait($cond, time() + $to, $lock), last if    /twain/;
-      die "$test: unknown test\n"; 
-    }
     $thr->join;
-    ok(5,$ok, "$test: condition obtained");
+    ok(6,1, "$test: join completed");
   }
 
   # - TEST cond_timedwait timeout