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