Release commit for 0.13
[p5sagit/Devel-GlobalDestruction.git] / t / 05_thread_clone.t
1 use strict;
2 use warnings;
3
4 use Config;
5 BEGIN {
6   unless ($Config{useithreads}) {
7     print "1..0 # SKIP your perl does not support ithreads\n";
8     exit 0;
9   }
10 }
11
12 BEGIN {
13   unless (eval { require threads }) {
14     print "1..0 # SKIP threads.pm not installed\n";
15     exit 0;
16   }
17 }
18
19 BEGIN {
20   if ($ENV{DEVEL_GLOBALDESTRUCTION_PP_TEST}) {
21     unshift @INC, sub {
22       die 'no XS' if $_[1] eq 'Devel/GlobalDestruction/XS.pm';
23     };
24   }
25 }
26
27 BEGIN {
28   package Test::Scope::Guard;
29   sub new { my ($class, $code) = @_; bless [$code], $class; }
30   sub DESTROY { my $self = shift; $self->[0]->() }
31 }
32 BEGIN {
33   package Test::Thread::Clone;
34   my @code;
35   sub new { my ($class, $code) = @_; push @code, $code; bless [$code], $class; }
36   sub CLONE { $_->() for @code }
37 }
38
39 use threads;
40 use threads::shared;
41
42 print "1..4\n";
43
44 our $had_error :shared;
45 END { $? = $had_error||0 }
46
47 sub ok ($$) {
48   $had_error++, print "not " if !$_[0];
49   print "ok";
50   print " - $_[1]" if defined $_[1];
51   print "\n";
52 }
53
54 # load it before spawning a thread, that's the whole point
55 use Devel::GlobalDestruction;
56
57 our $cloner = Test::Thread::Clone->new(sub {
58     ok( ! in_global_destruction(), "CLONE is not GD" );
59     my $guard = Test::Scope::Guard->new(sub {
60         ok( ! in_global_destruction(), "DESTROY during CLONE is not GD");
61     });
62 });
63 our $global = Test::Scope::Guard->new(sub {
64     ok( in_global_destruction(), "Final cleanup object destruction properly in GD in " . (threads->tid ? 'thread' : 'main program') );
65 });
66
67 sub do_test {
68   # just die so we don't need to deal with testcount skew
69   unless ( ($_[0]||'') eq 'arg' ) {
70     $had_error++;
71     die "Argument passing failed!";
72   }
73   # nothing really to do in here
74   1;
75 }
76
77 threads->create('do_test', 'arg')->join
78   or $had_error++;