1 # cond_wait and cond_timedwait extended tests
9 require Config; import Config;
10 unless ($Config{'useithreads'}) {
11 print "1..0 # Skip: no threads\n";
21 use ExtUtils::testlib;
26 my ($offset, $bool, $text) = @_;
28 $not = "not " unless $bool;
29 print "${not}ok " . ($Base + $offset) . " - $text\n";
32 # The two skips later on in these tests refer to this quote from the
33 # pod/perl583delta.pod:
35 # =head1 Platform Specific Problems
37 # The regression test ext/threads/shared/t/wait.t fails on early RedHat 9
38 # and HP-UX 10.20 due to bugs in their threading implementations.
39 # RedHat users should see https://rhn.redhat.com/errata/RHBA-2003-136.html
40 # and consider upgrading their glibc.
42 sub forko (&$$); # To prevent deadlock from underlying pthread_* bugs (as in
43 # stock RH9 glibc/NPTL) or from our own errors, we run tests
44 # in separately forked and alarmed processes.
46 *forko = ($^O =~ /^dos|os2|mswin32|netware|vms$/i)
47 ? sub (&$$) { my $code = shift; goto &$code; }
49 my ($code, $expected, $patience) = @_;
57 unless (defined($pid = open(CHLD, "-|"))) {
60 if (! $pid) { # Child -- run the test
68 $expected--, $test_num=$1 if /^(?:not )?ok (\d+)/;
69 #print "#forko: ($expected, $1) $_";
77 print "not ok $test_num - child status $?\n";
86 ok(1, defined &cond_wait, "cond_wait() present");
87 ok(2, (prototype(\&cond_wait) eq '\[$@%];\[$@%]'),
88 q|cond_wait() prototype '\[$@%];\[$@%]'|);
89 ok(3, defined &cond_timedwait, "cond_timedwait() present");
90 ok(4, (prototype(\&cond_timedwait) eq '\[$@%]$;\[$@%]'),
91 q|cond_timedwait() prototype '\[$@%]$;\[$@%]'|);
96 "simple", # cond var == lock var; implicit lock; e.g.: cond_wait($c)
97 "repeat", # cond var == lock var; explicit lock; e.g.: cond_wait($c, $c)
98 "twain" # cond var != lock var; explicit lock; e.g.: cond_wait($c, $l)
102 my $test : shared; # simple|repeat|twain
106 print "# testing my \$var : shared\n";
107 ok(1, 1, "Shared synchronization tests preparation");
111 ok(2,1,"$test: child before lock");
112 $test =~ /twain/ ? lock($lock) : lock($cond);
113 ok(3,1,"$test: child obtained lock");
114 if ($test =~ 'twain') {
115 no warnings 'threads'; # lock var != cond var, so disable warnings
120 ok(4,1,"$test: child signalled condition");
125 foreach (@wait_how) {
126 $test = "cond_wait [$_]";
127 threads->create(\&cw)->join;
135 { # -- begin lock scope; which lock to obtain?
136 $test =~ /twain/ ? lock($lock) : lock($cond);
137 ok(1,1, "$test: obtained initial lock");
139 $thr = threads->create(\&signaller);
141 cond_wait($cond), last if /simple/;
142 cond_wait($cond, $cond), last if /repeat/;
143 cond_wait($cond, $lock), last if /twain/;
144 die "$test: unknown test\n";
146 ok(5,1, "$test: condition obtained");
147 } # -- end lock scope
150 ok(6,1, "$test: join completed");
153 # - TEST cond_timedwait success
156 foreach (@wait_how) {
157 $test = "cond_timedwait [$_]";
158 threads->create(\&ctw, 5)->join;
167 { # -- begin lock scope; which lock to obtain?
168 $test =~ /twain/ ? lock($lock) : lock($cond);
169 ok(1,1, "$test: obtained initial lock");
171 $thr = threads->create(\&signaller);
174 $ok=cond_timedwait($cond, time() + $to), last if /simple/;
175 $ok=cond_timedwait($cond, time() + $to, $cond), last if /repeat/;
176 $ok=cond_timedwait($cond, time() + $to, $lock), last if /twain/;
177 die "$test: unknown test\n";
179 ok(5,$ok, "$test: condition obtained");
180 } # -- end lock scope
183 ok(6,1, "$test: join completed");
186 # - TEST cond_timedwait timeout
189 foreach (@wait_how) {
190 $test = "cond_timedwait pause, timeout [$_]";
191 threads->create(\&ctw_fail, 3)->join;
197 foreach (@wait_how) {
198 $test = "cond_timedwait instant timeout [$_]";
199 threads->create(\&ctw_fail, -60)->join;
204 # cond_timedwait timeout (relative timeout)
208 if ($^O eq "hpux" && $Config{osvers} <= 10.20) {
209 # The lock obtaining would pass, but the wait will not.
210 ok(1,1, "$test: obtained initial lock");
211 ok(2,0, "# SKIP see perl583delta");
214 $test =~ /twain/ ? lock($lock) : lock($cond);
215 ok(1,1, "$test: obtained initial lock");
218 $ok=cond_timedwait($cond, time() + $to), last if /simple/;
219 $ok=cond_timedwait($cond, time() + $to, $cond), last if /repeat/;
220 $ok=cond_timedwait($cond, time() + $to, $lock), last if /twain/;
221 die "$test: unknown test\n";
223 ok(2,!defined($ok), "$test: timeout");
227 } # -- SYNCH_SHARED block
230 # same as above, but with references to lock and cond vars
233 my $test : shared; # simple|repeat|twain
235 my $true_cond; share($true_cond);
236 my $true_lock; share($true_lock);
238 my $cond = \$true_cond;
239 my $lock = \$true_lock;
241 print "# testing reference to shared(\$var)\n";
242 ok(1, 1, "Synchronization reference tests preparation");
246 ok(2,1,"$test: child before lock");
247 $test =~ /twain/ ? lock($lock) : lock($cond);
248 ok(3,1,"$test: child obtained lock");
249 if ($test =~ 'twain') {
250 no warnings 'threads'; # lock var != cond var, so disable warnings
255 ok(4,1,"$test: child signalled condition");
260 foreach (@wait_how) {
261 $test = "cond_wait [$_]";
262 threads->create(\&cw2)->join;
270 { # -- begin lock scope; which lock to obtain?
271 $test =~ /twain/ ? lock($lock) : lock($cond);
272 ok(1,1, "$test: obtained initial lock");
274 $thr = threads->create(\&signaller2);
276 cond_wait($cond), last if /simple/;
277 cond_wait($cond, $cond), last if /repeat/;
278 cond_wait($cond, $lock), last if /twain/;
279 die "$test: unknown test\n";
281 ok(5,1, "$test: condition obtained");
282 } # -- end lock scope
285 ok(6,1, "$test: join completed");
288 # - TEST cond_timedwait success
291 foreach (@wait_how) {
292 $test = "cond_timedwait [$_]";
293 threads->create(\&ctw2, 5)->join;
302 { # -- begin lock scope; which lock to obtain?
303 $test =~ /twain/ ? lock($lock) : lock($cond);
304 ok(1,1, "$test: obtained initial lock");
306 $thr = threads->create(\&signaller2);
309 $ok=cond_timedwait($cond, time() + $to), last if /simple/;
310 $ok=cond_timedwait($cond, time() + $to, $cond), last if /repeat/;
311 $ok=cond_timedwait($cond, time() + $to, $lock), last if /twain/;
312 die "$test: unknown test\n";
314 ok(5,$ok, "$test: condition obtained");
315 } # -- end lock scope
318 ok(6,1, "$test: join completed");
321 # - TEST cond_timedwait timeout
324 foreach (@wait_how) {
325 $test = "cond_timedwait pause, timeout [$_]";
326 threads->create(\&ctw_fail2, 3)->join;
332 foreach (@wait_how) {
333 $test = "cond_timedwait instant timeout [$_]";
334 threads->create(\&ctw_fail2, -60)->join;
342 if ($^O eq "hpux" && $Config{osvers} <= 10.20) {
343 # The lock obtaining would pass, but the wait will not.
344 ok(1,1, "$test: obtained initial lock");
345 ok(2,0, "# SKIP see perl583delta");
348 $test =~ /twain/ ? lock($lock) : lock($cond);
349 ok(1,1, "$test: obtained initial lock");
352 $ok=cond_timedwait($cond, time() + $to), last if /simple/;
353 $ok=cond_timedwait($cond, time() + $to, $cond), last if /repeat/;
354 $ok=cond_timedwait($cond, time() + $to, $lock), last if /twain/;
355 die "$test: unknown test\n";
357 ok(2,!$ok, "$test: timeout");
361 } # -- SYNCH_REFS block