]> git.vpit.fr Git - perl/modules/Variable-Magic.git/blob - t/40-threads.t
Update VPIT::TestHelpers to 3edc6d15
[perl/modules/Variable-Magic.git] / t / 40-threads.t
1 #!perl
2
3 use strict;
4 use warnings;
5
6 use Variable::Magic qw<
7  wizard cast dispell getdata
8  VMG_OP_INFO_NAME VMG_OP_INFO_OBJECT
9 >;
10
11 use lib 't/lib';
12 use VPIT::TestHelpers (
13  threads => [ 'Variable::Magic' => 'Variable::Magic::VMG_THREADSAFE()' ],
14 );
15
16 use Test::Leaner 'no_plan';
17
18 my $destroyed : shared = 0;
19
20 sub try {
21  my ($dispell, $op_info) = @_;
22  my $tid = threads->tid;
23
24  my $c = 0;
25  my $wiz;
26
27  {
28   local $@;
29   $wiz = eval {
30    wizard(
31     data    => sub { $_[1] + $tid },
32     get     => sub { ++$c; 0 },
33     set     => sub {
34      my $op = $_[-1];
35
36      if ($op_info == VMG_OP_INFO_OBJECT) {
37       is_deeply { class => ref($op),   name => $op->name },
38                 { class => 'B::BINOP', name => 'sassign' },
39                 "op object in thread $tid is correct";
40      } else {
41       is $op, 'sassign', "op name in thread $tid is correct";
42      }
43
44      return 0;
45     },
46     free    => sub { lock $destroyed; ++$destroyed; 0 },
47     op_info => $op_info,
48    );
49   };
50   is $@,     '',    "wizard in thread $tid doesn't croak";
51   isnt $wiz, undef, "wizard in thread $tid is defined";
52   is $c,     0,     "wizard in thread $tid doesn't trigger magic";
53  }
54
55  my $a = 3;
56
57  {
58   local $@;
59   my $res = eval { cast $a, $wiz, sub { 5 }->() };
60   is $@, '', "cast in thread $tid doesn't croak";
61   is $c, 0,  "cast in thread $tid doesn't trigger magic";
62  }
63
64  {
65   local $@;
66   my $b;
67   eval { $b = $a };
68   is $@, '', "get in thread $tid doesn't croak";
69   is $b, 3,  "get in thread $tid returns the right thing";
70   is $c, 1,  "get in thread $tid triggers magic";
71  }
72
73  {
74   local $@;
75   my $d = eval { getdata $a, $wiz };
76   is $@, '',       "getdata in thread $tid doesn't croak";
77   is $d, 5 + $tid, "getdata in thread $tid returns the right thing";
78   is $c, 1,        "getdata in thread $tid doesn't trigger magic";
79  }
80
81  {
82   local $@;
83   eval { $a = 9 };
84   is $@, '', "set in thread $tid (check opname) doesn't croak";
85  }
86
87  if ($dispell) {
88   {
89    local $@;
90    my $res = eval { dispell $a, $wiz };
91    is $@, '', "dispell in thread $tid doesn't croak";
92    is $c, 1,  "dispell in thread $tid doesn't trigger magic";
93   }
94
95   {
96    local $@;
97    my $b;
98    eval { $b = $a };
99    is $@, '', "get in thread $tid after dispell doesn't croak";
100    is $b, 9,  "get in thread $tid after dispell returns the right thing";
101    is $c, 1,  "get in thread $tid after dispell doesn't trigger magic";
102   }
103  }
104  return; # Ugly if not here
105 }
106
107 for my $dispell (1, 0) {
108  {
109   lock $destroyed;
110   $destroyed = 0;
111  }
112
113  my @threads = map spawn(\&try, $dispell, $_),
114                               (VMG_OP_INFO_NAME) x 2, (VMG_OP_INFO_OBJECT) x 2;
115  $_->join for @threads;
116
117  {
118   lock $destroyed;
119   is $destroyed, (1 - $dispell) * 4, 'destructors';
120  }
121 }