Commit | Line | Data |
05b59262 |
1 | use strict; |
2 | use warnings; |
3 | |
4 | BEGIN { |
5 | if ($ENV{'PERL_CORE'}){ |
6 | chdir 't'; |
7 | unshift @INC, '../lib'; |
8 | } |
9 | use Config; |
10 | if (! $Config{'useithreads'}) { |
6c791b15 |
11 | print("1..0 # SKIP Perl not compiled with 'useithreads'\n"); |
05b59262 |
12 | exit(0); |
13 | } |
eebceeb0 |
14 | if ($^O eq 'hpux' && $Config{osvers} <= 10.20) { |
6c791b15 |
15 | print("1..0 # SKIP Broken under HP-UX 10.20\n"); |
eebceeb0 |
16 | exit(0); |
17 | } |
05b59262 |
18 | } |
19 | |
20 | use ExtUtils::testlib; |
21 | |
05b59262 |
22 | BEGIN { |
23 | $| = 1; |
3b29be8d |
24 | print("1..1\n"); ### Number of tests that will be run ### |
05b59262 |
25 | }; |
26 | |
27 | use threads; |
28 | use threads::shared; |
29 | |
30 | ### Start of Testing ### |
31 | |
32 | ##### |
33 | # |
34 | # Launches a bunch of threads which are then |
35 | # restricted to finishing in numerical order |
36 | # |
05b59262 |
37 | ##### |
38 | { |
39 | my $cnt = 50; |
40 | |
a469502f |
41 | my $TIMEOUT = 60; |
05b59262 |
42 | |
43 | my $mutex = 1; |
44 | share($mutex); |
45 | |
46 | my @threads; |
a469502f |
47 | for (reverse(1..$cnt)) { |
05b59262 |
48 | $threads[$_] = threads->create(sub { |
49 | my $tnum = shift; |
50 | my $timeout = time() + $TIMEOUT; |
a469502f |
51 | threads->yield(); |
05b59262 |
52 | |
53 | # Randomize the amount of work the thread does |
54 | my $sum; |
55 | for (0..(500000+int(rand(500000)))) { |
56 | $sum++ |
57 | } |
58 | |
59 | # Lock the mutex |
60 | lock($mutex); |
61 | |
62 | # Wait for my turn to finish |
63 | while ($mutex != $tnum) { |
64 | if (! cond_timedwait($mutex, $timeout)) { |
65 | if ($mutex == $tnum) { |
66 | return ('timed out - cond_broadcast not received'); |
67 | } else { |
68 | return ('timed out'); |
69 | } |
70 | } |
71 | } |
72 | |
73 | # Finish up |
74 | $mutex++; |
75 | cond_broadcast($mutex); |
76 | return ('okay'); |
77 | }, $_); |
78 | } |
79 | |
80 | # Gather thread results |
3b29be8d |
81 | my ($okay, $failures, $timeouts, $unknown) = (0, 0, 0, 0); |
05b59262 |
82 | for (1..$cnt) { |
f6d55995 |
83 | if (! $threads[$_]) { |
3b29be8d |
84 | $failures++; |
3b29be8d |
85 | } else { |
f6d55995 |
86 | my $rc = $threads[$_]->join(); |
87 | if (! $rc) { |
88 | $failures++; |
89 | } elsif ($rc =~ /^timed out/) { |
90 | $timeouts++; |
91 | } elsif ($rc eq 'okay') { |
92 | $okay++; |
93 | } else { |
94 | $unknown++; |
95 | print(STDERR "# Unknown error: $rc\n"); |
96 | } |
3b29be8d |
97 | } |
05b59262 |
98 | } |
f6d55995 |
99 | if ($failures) { |
100 | # Most likely due to running out of memory |
101 | print(STDERR "# Warning: $failures threads failed\n"); |
102 | print(STDERR "# Note: errno 12 = ENOMEM\n"); |
103 | $cnt -= $failures; |
104 | } |
05b59262 |
105 | |
f6d55995 |
106 | if ($unknown || (($okay + $timeouts) != $cnt)) { |
291f766e |
107 | print("not ok 1\n"); |
f6d55995 |
108 | my $too_few = $cnt - ($okay + $timeouts + $unknown); |
291f766e |
109 | print(STDERR "# Test failed:\n"); |
110 | print(STDERR "#\t$too_few too few threads reported\n") if $too_few; |
291f766e |
111 | print(STDERR "#\t$unknown unknown errors\n") if $unknown; |
112 | print(STDERR "#\t$timeouts threads timed out\n") if $timeouts; |
3b29be8d |
113 | |
114 | } elsif ($timeouts) { |
115 | # Frequently fails under MSWin32 due to deadlocking bug in Windows |
116 | # hence test is TODO under MSWin32 |
117 | # http://rt.perl.org/rt3/Public/Bug/Display.html?id=41574 |
118 | # http://support.microsoft.com/kb/175332 |
291f766e |
119 | if ($^O eq 'MSWin32') { |
120 | print("not ok 1 # TODO - not reliable under MSWin32\n") |
121 | } else { |
122 | print("not ok 1\n"); |
123 | print(STDERR "# Test failed: $timeouts threads timed out\n"); |
124 | } |
3b29be8d |
125 | |
126 | } else { |
a469502f |
127 | print("ok 1\n"); |
3b29be8d |
128 | } |
05b59262 |
129 | } |
130 | |
6c791b15 |
131 | exit(0); |
132 | |
05b59262 |
133 | # EOF |