]> git.vpit.fr Git - perl/modules/Variable-Magic.git/blob - t/40-threads.t
3b850e3c89236c7eb4e8db9a359421d7fcc14b5b
[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  my $c   = 0;
22  my $wiz = eval {
23   wizard data    => sub { $_[1] + $tid },
24          get     => sub { ++$c; 0 },
25          set     => sub {
26                      my $op = $_[-1];
27                      if ($op_info == VMG_OP_INFO_OBJECT) {
28                       is_deeply { class => ref($op),   name => $op->name },
29                                 { class => 'B::BINOP', name => 'sassign' },
30                                 "op object in thread $tid is correct";
31                      } else {
32                       is $op, 'sassign', "op name in thread $tid is correct";
33                      }
34                      0
35                     },
36          free    => sub { lock $destroyed; ++$destroyed; 0 },
37          op_info => $op_info
38  };
39  is($@,     '',    "wizard in thread $tid doesn't croak");
40  isnt($wiz, undef, "wizard in thread $tid is defined");
41  is($c,     0,     "wizard in thread $tid doesn't trigger magic");
42  my $a = 3;
43  my $res = eval { cast $a, $wiz, sub { 5 }->() };
44  is($@, '', "cast in thread $tid doesn't croak");
45  is($c, 0,  "cast in thread $tid doesn't trigger magic");
46  my $b;
47  eval { $b = $a };
48  is($@, '', "get in thread $tid doesn't croak");
49  is($b, 3,  "get in thread $tid returns the right thing");
50  is($c, 1,  "get in thread $tid triggers magic");
51  my $d = eval { getdata $a, $wiz };
52  is($@, '',       "getdata in thread $tid doesn't croak");
53  is($d, 5 + $tid, "getdata in thread $tid returns the right thing");
54  is($c, 1,        "getdata in thread $tid doesn't trigger magic");
55  eval { $a = 9 };
56  is($@, '', "set in thread $tid (check opname) doesn't croak");
57  if ($dispell) {
58   $res = eval { dispell $a, $wiz };
59   is($@, '', "dispell in thread $tid doesn't croak");
60   is($c, 1,  "dispell in thread $tid doesn't trigger magic");
61   undef $b;
62   eval { $b = $a };
63   is($@, '', "get in thread $tid after dispell doesn't croak");
64   is($b, 9,  "get in thread $tid after dispell returns the right thing");
65   is($c, 1,  "get in thread $tid after dispell doesn't trigger magic");
66  }
67  return; # Ugly if not here
68 }
69
70 for my $dispell (1, 0) {
71  {
72   lock $destroyed;
73   $destroyed = 0;
74  }
75
76  my @threads = map spawn(\&try, $dispell, $_),
77                               (VMG_OP_INFO_NAME) x 2, (VMG_OP_INFO_OBJECT) x 2;
78  $_->join for @threads;
79
80  {
81   lock $destroyed;
82   is $destroyed, (1 - $dispell) * 4, 'destructors';
83  }
84 }