9 my ($module, $thread_safe_var);
11 $module = 'Scope::Upper';
12 $thread_safe_var = 'Scope::Upper::SU_THREADSAFE()';
19 if (defined &Scope::Upper::reap) {
20 &Scope::Upper::reap(sub { $var *= 2 });
34 # Keep the rest of the file untouched
39 if (defined $thread_safe_var) {
40 my $stat = run_perl "require POSIX; require $module; exit($thread_safe_var ? POSIX::EXIT_SUCCESS() : POSIX::EXIT_FAILURE())";
43 if ($res == POSIX::EXIT_SUCCESS()) {
45 } elsif ($res == POSIX::EXIT_FAILURE()) {
48 if (not defined $is_threadsafe) {
49 skip_all "Could not detect if $module is thread safe or not";
53 VPIT::TestHelpers->import(
54 threads => [ $module => $is_threadsafe ],
58 use Test::Leaner tests => 1 + (2 + 2 * 2) + 6 + (1 + 2 * 4);
61 my ($affirmative, $desc) = @_;
63 my $res = load_test();
66 is $res, 1, "$desc: module loaded";
68 is $res, 0, "$desc: module not loaded";
74 my $code = eval "sub { require $module }";
79 is_loaded 0, 'main body, beginning';
81 # Test serial loadings
84 my $here = "first serial thread";
85 is_loaded 0, "$here, beginning";
88 is_loaded 1, "$here, after loading";
94 if (my $err = $thr->error) {
98 is_loaded 0, 'main body, in between serial loadings';
101 my $here = "second serial thread";
102 is_loaded 0, "$here, beginning";
105 is_loaded 1, "$here, after loading";
111 if (my $err = $thr->error) {
115 is_loaded 0, 'main body, after serial loadings';
117 # Test nested loadings
120 my $here = 'parent thread';
121 is_loaded 0, "$here, beginning";
123 my $kid = spawn(sub {
124 my $here = 'child thread';
125 is_loaded 0, "$here, beginning";
128 is_loaded 1, "$here, after loading";
134 if (my $err = $kid->error) {
135 die "in child thread: $err\n";
138 is_loaded 0, "$here, after child terminated";
141 is_loaded 1, "$here, after loading";
147 if (my $err = $thr->error) {
151 is_loaded 0, 'main body, after nested loadings';
153 # Test parallel loadings
159 share($_) for @locks;
167 cond_broadcast $locks[$id];
176 cond_wait $locks[$id] until $locks[$id] == 0;
180 my $thr1 = spawn(sub {
181 my $here = 'first simultaneous thread';
182 is_loaded 0, "$here, beginning";
186 is_loaded 1, "$here, after loading";
191 is_loaded 1, "$here, still loaded while also loaded in the other thread";
194 is_loaded 1, "$here, end";
199 my $thr2 = spawn(sub {
200 my $here = 'second simultaneous thread';
201 is_loaded 0, "$here, beginning";
205 is_loaded 0, "$here, loaded in other thread but not here";
209 is_loaded 1, "$here, after loading";
213 is_loaded 1, "$here, end";
218 sync_master($_) for 0 .. $#locks;
221 if (my $err = $thr1->error) {
226 if (my $err = $thr2->error) {
230 is_loaded 0, 'main body, after simultaneous threads';