1#!perl
2use strict;
3use warnings;
4
5require './test.pl';
6skip_all_without_config('useithreads');
7skip_all_if_miniperl("no dynamic loading on miniperl, no threads");
8
9plan(3);
10
11require threads;
12
13{
14    fresh_perl_is('
15        use threads;
16        use strict;
17        use warnings;
18
19        sub main::IsA {
20            use feature "state";
21
22            state $upper_char = ord "A";
23            state $lower_char = ord "a";
24
25            return sprintf "%x", $lower_char++ if shift;
26            return sprintf "%x", $upper_char++;
27        }
28
29        my @threads = map +threads->create(sub {
30            sleep 0.1;
31
32            for (1..2500) {
33                return 0 unless eval "qq(A) =~ qr/\\\p{main::IsA}/";
34                return 0 unless eval "qq(a) =~ qr/\\\p{main::IsA}/i";
35            }
36
37            return 1;
38        }), (0..1);
39        my $success  = $threads[0]->join;
40           $success += $threads[1]->join;
41        print $success;',
42    2,
43    {},
44    "Simultaneous threads worked");
45
46}
47
48{
49    fresh_perl_is('
50        use threads;
51        use strict;
52        use warnings;
53
54        sub InLongSleep {
55            use feature "state";
56
57            state $which = 0;
58
59            sleep(60) unless $which++;
60            return "0042";
61        }
62
63        sub InQuick {
64            return sprintf "%x", ord("C");
65        }
66
67        my $thread0 = threads->create(sub {
68
69            my $a = \'\p{InLongSleep}\';
70            qr/$a/;
71
72            return 1;
73        });
74        my $thread1 = threads->create(sub {
75            sleep 1;
76
77            my $c = \'\p{InQuick}\';
78            return "C" =~ /$c/;
79        });
80        print $thread1->join;
81        $thread0->detach();',
82    1,
83    {},
84    "One thread hung on a defn doesn't impinge on other's other defns");
85}
86
87{
88    fresh_perl_like('
89        use threads;
90        use strict;
91        use warnings;
92
93        sub InLongSleep {
94            use feature "state";
95
96            state $which = 0;
97
98            sleep(25) unless $which++;
99            return "0042";
100        }
101
102        my @threads = map +threads->create(sub {
103            sleep 1;
104
105            my $a = \'\p{InLongSleep}\';
106            qr/$a/;
107
108            return 1;
109        }), (0..1);
110        $threads[1]->join;
111        $threads[0]->detach();',
112    qr/Thread \d+ terminated abnormally: Timeout waiting for another thread to define "InLongSleep" in regex/,
113    {},
114    "One thread hung on a definition doesn't delay another indefinitely");
115}
116
1171;
118