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;
23 wizard data => sub { $_[1] + threads->tid() },
24 get => sub { lock $c; ++$c; 0 },
27 my $tid = threads->tid();
28 if ($op_info == VMG_OP_INFO_OBJECT) {
29 is_deeply { class => ref($op), name => $op->name },
30 { class => 'B::BINOP', name => 'sassign' },
31 "op object in thread $tid is correct";
33 is $op, 'sassign', "op name in thread $tid is correct";
37 free => sub { lock $destroyed; ++$destroyed; 0 },
40 is($@, '', "wizard with op_info $op_info in main thread doesn't croak");
41 isnt($wiz, undef, "wizard with op_info $op_info in main thread is defined");
42 is($c, 0, "wizard with op_info $op_info in main thread doesn't trigger magic");
48 my ($dispell, $wiz) = @_;
49 my $tid = threads->tid();
51 my $res = eval { cast $a, $wiz, sub { 5 }->() };
52 is($@, '', "cast in thread $tid doesn't croak");
55 is($@, '', "get in thread $tid doesn't croak");
56 is($b, 3, "get in thread $tid returns the right thing");
57 my $d = eval { getdata $a, $wiz };
58 is($@, '', "getdata in thread $tid doesn't croak");
59 is($d, 5 + $tid, "getdata in thread $tid returns the right thing");
61 is($@, '', "set in thread $tid (check opname) doesn't croak");
63 $res = eval { dispell $a, $wiz };
64 is($@, '', "dispell in thread $tid doesn't croak");
67 is($@, '', "get in thread $tid after dispell doesn't croak");
68 is($b, 9, "get in thread $tid after dispell returns the right thing");
70 return; # Ugly if not here
73 my $wiz_name = spawn_wiz VMG_OP_INFO_NAME;
74 my $wiz_obj = spawn_wiz VMG_OP_INFO_OBJECT;
76 for my $dispell (1, 0) {
77 for my $wiz ($wiz_name, $wiz_obj) {
87 my @threads = map spawn(\&try, $dispell, $wiz), 1 .. 2;
88 $_->join for @threads;
92 is $c, 2, "get triggered twice";
96 is $destroyed, (1 - $dispell) * 2, 'destructors';