7 use Variable::Magic::TestThreads;
9 use Test::More 'no_plan';
11 use Variable::Magic qw<
12 wizard cast dispell getdata
13 VMG_OP_INFO_NAME VMG_OP_INFO_OBJECT
16 my $destroyed : shared = 0;
19 my ($dispell, $op_info) = @_;
20 my $tid = threads->tid();
23 wizard data => sub { $_[1] + $tid },
24 get => sub { ++$c; 0 },
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";
32 is $op, 'sassign', "op name in thread $tid is correct";
36 free => sub { lock $destroyed; ++$destroyed; 0 },
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");
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");
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");
56 is($@, '', "set in thread $tid (check opname) doesn't croak");
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");
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");
67 return; # Ugly if not here
70 for my $dispell (1, 0) {
76 my @threads = map spawn(\&try, $dispell, $_),
77 (VMG_OP_INFO_NAME) x 2, (VMG_OP_INFO_OBJECT) x 2;
78 $_->join for @threads;
82 is $destroyed, (1 - $dispell) * 4, 'destructors';