Thread::Queue 2.07
[p5sagit/p5-mst-13.2.git] / lib / Thread / Queue / t / 02_refs.t
CommitLineData
54c7876f 1use strict;
2use warnings;
3
4BEGIN {
5 if ($ENV{'PERL_CORE'}){
6 chdir('t');
7 unshift(@INC, '../lib');
8 }
9 use Config;
10 if (! $Config{'useithreads'}) {
11 print("1..0 # Skip: Perl not compiled with 'useithreads'\n");
12 exit(0);
13 }
14}
15
16use threads;
17use threads::shared;
18use Thread::Queue;
19
20if ($] == 5.008) {
21 require 't/test.pl'; # Test::More work-alike for Perl 5.8.0
22} else {
23 require Test::More;
24}
25Test::More->import();
ac9d3a9d 26plan('tests' => 45);
54c7876f 27
28# Regular array
29my @ary1 = qw/foo bar baz/;
30push(@ary1, [ 1..3 ], { 'qux' => 99 });
31
32# Shared array
33my @ary2 :shared = (99, 21, 86);
34
35# Regular hash-based object
36my $obj1 = {
37 'foo' => 'bar',
38 'qux' => 99,
39 'biff' => [ qw/fee fi fo/ ],
40 'boff' => { 'bork' => 'true' },
41};
42bless($obj1, 'Foo');
43
44# Shared hash-based object
45my $obj2 = &share({});
46$$obj2{'bar'} = 86;
47$$obj2{'key'} = 'foo';
48bless($obj2, 'Bar');
49
50# Scalar ref
51my $sref1 = \do{ my $scalar = 'foo'; };
52
53# Shared scalar ref object
54my $sref2 = \do{ my $scalar = 69; };
55share($sref2);
56bless($sref2, 'Baz');
57
58# Ref of ref
59my $foo = [ 5, 'bork', { 'now' => 123 } ];
60my $bar = \$foo;
61my $baz = \$bar;
62my $qux = \$baz;
63is_deeply($$$$qux, $foo, 'Ref of ref');
64
ac9d3a9d 65# Circular refs
66my $cir1;
67$cir1 = \$cir1;
68
69my $cir1s : shared;
70$cir1s = \$cir1s;
71
72my $cir2;
73$cir2 = [ \$cir2, { 'ref' => \$cir2 } ];
74
75my $cir3 :shared = &share({});
76$cir3->{'self'} = \$cir3;
77bless($cir3, 'Circular');
78
54c7876f 79# Queue up items
80my $q = Thread::Queue->new(\@ary1, \@ary2);
81ok($q, 'New queue');
82is($q->pending(), 2, 'Queue count');
83$q->enqueue($obj1, $obj2);
84is($q->pending(), 4, 'Queue count');
85$q->enqueue($sref1, $sref2, $qux);
86is($q->pending(), 7, 'Queue count');
ac9d3a9d 87$q->enqueue($cir1, $cir1s, $cir2, $cir3);
88is($q->pending(), 11, 'Queue count');
54c7876f 89
90# Process items in thread
91threads->create(sub {
ac9d3a9d 92 is($q->pending(), 11, 'Queue count in thread');
54c7876f 93
94 my $tary1 = $q->dequeue();
95 ok($tary1, 'Thread got item');
96 is(ref($tary1), 'ARRAY', 'Item is array ref');
97 is_deeply($tary1, \@ary1, 'Complex array');
98 $$tary1[1] = 123;
99
100 my $tary2 = $q->dequeue();
101 ok($tary2, 'Thread got item');
102 is(ref($tary2), 'ARRAY', 'Item is array ref');
103 for (my $ii=0; $ii < @ary2; $ii++) {
104 is($$tary2[$ii], $ary2[$ii], 'Shared array element check');
105 }
106 $$tary2[1] = 444;
107
108 my $tobj1 = $q->dequeue();
109 ok($tobj1, 'Thread got item');
110 is(ref($tobj1), 'Foo', 'Item is object');
111 is_deeply($tobj1, $obj1, 'Object comparison');
112 $$tobj1{'foo'} = '.|.';
113 $$tobj1{'smiley'} = ':)';
114
115 my $tobj2 = $q->dequeue();
116 ok($tobj2, 'Thread got item');
117 is(ref($tobj2), 'Bar', 'Item is object');
118 is($$tobj2{'bar'}, 86, 'Shared object element check');
119 is($$tobj2{'key'}, 'foo', 'Shared object element check');
120 $$tobj2{'tick'} = 'tock';
121 $$tobj2{'frowny'} = ':(';
122
123 my $tsref1 = $q->dequeue();
124 ok($tsref1, 'Thread got item');
125 is(ref($tsref1), 'SCALAR', 'Item is scalar ref');
126 is($$tsref1, 'foo', 'Scalar ref contents');
127 $$tsref1 = 0;
128
129 my $tsref2 = $q->dequeue();
130 ok($tsref2, 'Thread got item');
131 is(ref($tsref2), 'Baz', 'Item is object');
132 is($$tsref2, 69, 'Shared scalar ref contents');
133 $$tsref2 = 'zzz';
134
135 my $qux = $q->dequeue();
136 is_deeply($$$$qux, $foo, 'Ref of ref');
137
ac9d3a9d 138 my ($c1, $c1s, $c2, $c3) = $q->dequeue(4);
139 SKIP: {
140 skip("Needs threads::shared >= 1.19", 5)
141 if ($threads::shared::VERSION < 1.19);
142
143 is(threads::shared::_id($$c1),
144 threads::shared::_id($c1),
145 'Circular ref - scalar');
146
147 is(threads::shared::_id($$c1s),
148 threads::shared::_id($c1s),
149 'Circular ref - shared scalar');
150
151 is(threads::shared::_id(${$c2->[0]}),
152 threads::shared::_id($c2),
153 'Circular ref - array');
154
155 is(threads::shared::_id(${$c2->[1]->{'ref'}}),
156 threads::shared::_id($c2),
157 'Circular ref - mixed');
158
159 is(threads::shared::_id(${$c3->{'self'}}),
160 threads::shared::_id($c3),
161 'Circular ref - hash');
162 }
163
54c7876f 164 is($q->pending(), 0, 'Empty queue');
165 my $nothing = $q->dequeue_nb();
166 ok(! defined($nothing), 'Nothing on queue');
167})->join();
168
169# Check results of thread's activities
170is($q->pending(), 0, 'Empty queue');
171
172is($ary1[1], 'bar', 'Array unchanged');
173is($ary2[1], 444, 'Shared array changed');
174
175is($$obj1{'foo'}, 'bar', 'Object unchanged');
176ok(! exists($$obj1{'smiley'}), 'Object unchanged');
177
178is($$obj2{'tick'}, 'tock', 'Shared object changed');
179is($$obj2{'frowny'}, ':(', 'Shared object changed');
180
181is($$sref1, 'foo', 'Scalar ref unchanged');
182is($$sref2, 'zzz', 'Shared scalar ref changed');
183
184# EOF