]> git.vpit.fr Git - perl/modules/Scope-Upper.git/blob - t/lib/Scope/Upper/TestThreads.pm
Release UID global memory at global teardown time
[perl/modules/Scope-Upper.git] / t / lib / Scope / Upper / TestThreads.pm
1 package Scope::Upper::TestThreads;
2
3 use strict;
4 use warnings;
5
6 use Config qw<%Config>;
7
8 use Scope::Upper qw<SU_THREADSAFE>;
9
10 use VPIT::TestHelpers;
11
12 sub diag {
13  require Test::Leaner;
14  Test::Leaner::diag(@_);
15 }
16
17 sub import {
18  shift;
19
20  skip_all 'This Scope::Upper isn\'t thread safe' unless SU_THREADSAFE;
21
22  my $force = $ENV{PERL_SCOPE_UPPER_TEST_THREADS} ? 1 : !1;
23  skip_all 'This perl wasn\'t built to support threads'
24                                                     unless $Config{useithreads};
25  skip_all 'perl 5.13.4 required to test thread safety'
26                                              unless $force or "$]" >= 5.013_004;
27
28  load_or_skip_all('threads', $force ? '0' : '1.67', [ ]);
29
30  my %exports = (
31   spawn => \&spawn,
32  );
33
34  my $usleep;
35  if (do { local $@; eval { require Time::HiRes; 1 } }) {
36   defined and diag "Using Time::HiRes $_" for $Time::HiRes::VERSION;
37   $exports{usleep} = \&Time::HiRes::usleep;
38  } else {
39   diag 'Using fallback usleep';
40   $exports{usleep} = sub {
41    my $s = int($_[0] / 2.5e5);
42    sleep $s if $s;
43   };
44  }
45
46  my $pkg = caller;
47  while (my ($name, $code) = each %exports) {
48   no strict 'refs';
49   *{$pkg.'::'.$name} = $code;
50  }
51 }
52
53 sub spawn {
54  local $@;
55  my @diag;
56  my $thread = eval {
57   local $SIG{__WARN__} = sub { push @diag, "Thread creation warning: @_" };
58   threads->create(@_);
59  };
60  push @diag, "Thread creation error: $@" if $@;
61  if (@diag) {
62   require Test::Leaner;
63   Test::Leaner::diag($_) for @diag;
64  }
65  return $thread ? $thread : ();
66 }
67
68 1;