1b39c5158Smillertuse strict; 2b39c5158Smillertuse warnings; 3b39c5158Smillert 4b39c5158SmillertBEGIN { 5b39c5158Smillert use Config; 6b39c5158Smillert if (! $Config{'useithreads'}) { 7b39c5158Smillert print("1..0 # SKIP Perl not compiled with 'useithreads'\n"); 8b39c5158Smillert exit(0); 9b39c5158Smillert } 10b39c5158Smillert if ($] < 5.010) { 11b39c5158Smillert print("1..0 # SKIP Needs Perl 5.10.0 or later\n"); 12b39c5158Smillert exit(0); 13b39c5158Smillert } 14b39c5158Smillert} 15b39c5158Smillert 16b39c5158Smillertuse ExtUtils::testlib; 17b39c5158Smillert 18b39c5158SmillertBEGIN { 19b39c5158Smillert $| = 1; 20b39c5158Smillert print("1..28\n"); ### Number of tests that will be run ### 21b39c5158Smillert}; 22b39c5158Smillert 23b39c5158Smillertuse threads; 24b39c5158Smillertuse threads::shared; 25b39c5158Smillert 26b39c5158Smillertmy $TEST; 27b39c5158SmillertBEGIN { 28b39c5158Smillert share($TEST); 29b39c5158Smillert $TEST = 1; 30b39c5158Smillert} 31b39c5158Smillert 32b39c5158Smillertsub ok { 33b39c5158Smillert my ($ok, $name) = @_; 34b39c5158Smillert 35b39c5158Smillert lock($TEST); 36b39c5158Smillert my $id = $TEST++; 37b39c5158Smillert 38b39c5158Smillert # You have to do it this way or VMS will get confused. 39b39c5158Smillert if ($ok) { 40b39c5158Smillert print("ok $id - $name\n"); 41b39c5158Smillert } else { 42b39c5158Smillert print("not ok $id - $name\n"); 43b39c5158Smillert printf("# Failed test at line %d\n", (caller)[2]); 44b39c5158Smillert } 45b39c5158Smillert 46b39c5158Smillert return ($ok); 47b39c5158Smillert} 48b39c5158Smillert 49b39c5158Smillertok(1, 'Loaded'); 50b39c5158Smillert 51b39c5158Smillert### Start of Testing ### 52b39c5158Smillert 53b39c5158Smillert{ package Jar; 54b39c5158Smillert my @jar :shared; 55b39c5158Smillert 56b39c5158Smillert sub new 57b39c5158Smillert { 58b39c5158Smillert bless(&threads::shared::share({}), shift); 59b39c5158Smillert } 60b39c5158Smillert 61b39c5158Smillert sub store 62b39c5158Smillert { 63b39c5158Smillert my ($self, $cookie) = @_; 64b39c5158Smillert push(@jar, $cookie); 65b39c5158Smillert return $jar[-1]; # Results in destruction of proxy object 66b39c5158Smillert } 67b39c5158Smillert 68b39c5158Smillert sub peek 69b39c5158Smillert { 70b39c5158Smillert return $jar[-1]; 71b39c5158Smillert } 72b39c5158Smillert 73b39c5158Smillert sub fetch 74b39c5158Smillert { 75b39c5158Smillert pop(@jar); 76b39c5158Smillert } 77b39c5158Smillert} 78b39c5158Smillert 79b39c5158Smillert{ package Cookie; 80b39c5158Smillert 81b39c5158Smillert sub new 82b39c5158Smillert { 83b39c5158Smillert my $self = bless(&threads::shared::share({}), shift); 84b39c5158Smillert $self->{'type'} = shift; 85b39c5158Smillert return $self; 86b39c5158Smillert } 87b39c5158Smillert 88b39c5158Smillert sub DESTROY 89b39c5158Smillert { 90b39c5158Smillert delete(shift->{'type'}); 91b39c5158Smillert } 92b39c5158Smillert} 93b39c5158Smillert 94b39c5158Smillertmy $C1 = 'chocolate chip'; 95b39c5158Smillertmy $C2 = 'oatmeal raisin'; 96b39c5158Smillertmy $C3 = 'vanilla wafer'; 97b39c5158Smillert 98b39c5158Smillertmy $cookie = Cookie->new($C1); 99b39c5158Smillertok($cookie->{'type'} eq $C1, 'Have cookie'); 100b39c5158Smillert 101b39c5158Smillertmy $jar = Jar->new(); 102b39c5158Smillert$jar->store($cookie); 103b39c5158Smillert 104b39c5158Smillertok($cookie->{'type'} eq $C1, 'Still have cookie'); 105b39c5158Smillertok($jar->peek()->{'type'} eq $C1, 'Still have cookie'); 106b39c5158Smillertok($cookie->{'type'} eq $C1, 'Still have cookie'); 107b39c5158Smillert 108b39c5158Smillertthreads->create(sub { 109b39c5158Smillert ok($cookie->{'type'} eq $C1, 'Have cookie in thread'); 110b39c5158Smillert ok($jar->peek()->{'type'} eq $C1, 'Still have cookie in thread'); 111b39c5158Smillert ok($cookie->{'type'} eq $C1, 'Still have cookie in thread'); 112b39c5158Smillert 113b39c5158Smillert $jar->store(Cookie->new($C2)); 114b39c5158Smillert ok($jar->peek()->{'type'} eq $C2, 'Added cookie in thread'); 115b39c5158Smillert})->join(); 116b39c5158Smillert 117b39c5158Smillertok($cookie->{'type'} eq $C1, 'Still have original cookie after thread'); 118b39c5158Smillertok($jar->peek()->{'type'} eq $C2, 'Still have added cookie after thread'); 119b39c5158Smillert 120b39c5158Smillert$cookie = $jar->fetch(); 121b39c5158Smillertok($cookie->{'type'} eq $C2, 'Fetched cookie from jar'); 122b39c5158Smillertok($jar->peek()->{'type'} eq $C1, 'Cookie still in jar'); 123b39c5158Smillert 124b39c5158Smillert$cookie = $jar->fetch(); 125b39c5158Smillertok($cookie->{'type'} eq $C1, 'Fetched cookie from jar'); 126b39c5158Smillertundef($cookie); 127b39c5158Smillert 128b39c5158Smillertshare($cookie); 129b39c5158Smillert$cookie = $jar->store(Cookie->new($C3)); 130b39c5158Smillertok($jar->peek()->{'type'} eq $C3, 'New cookie in jar'); 131b39c5158Smillertok($cookie->{'type'} eq $C3, 'Have cookie'); 132b39c5158Smillert 133b39c5158Smillertthreads->create(sub { 134b39c5158Smillert ok($cookie->{'type'} eq $C3, 'Have cookie in thread'); 135b39c5158Smillert $cookie = Cookie->new($C1); 136b39c5158Smillert ok($cookie->{'type'} eq $C1, 'Change cookie in thread'); 137b39c5158Smillert ok($jar->peek()->{'type'} eq $C3, 'Still have cookie in jar'); 138b39c5158Smillert})->join(); 139b39c5158Smillert 140b39c5158Smillertok($cookie->{'type'} eq $C1, 'Have changed cookie after thread'); 141b39c5158Smillertok($jar->peek()->{'type'} eq $C3, 'Still have cookie in jar'); 142b39c5158Smillertundef($cookie); 143b39c5158Smillertok($jar->peek()->{'type'} eq $C3, 'Still have cookie in jar'); 144b39c5158Smillert$cookie = $jar->fetch(); 145b39c5158Smillertok($cookie->{'type'} eq $C3, 'Fetched cookie from jar'); 146b39c5158Smillert 147b39c5158Smillert{ package Foo; 148b39c5158Smillert 149b39c5158Smillert my $ID = 1; 150b39c5158Smillert threads::shared::share($ID); 151b39c5158Smillert 152b39c5158Smillert sub new 153b39c5158Smillert { 154b39c5158Smillert # Anonymous scalar with an internal ID 155b39c5158Smillert my $obj = \do{ my $scalar = $ID++; }; 156b39c5158Smillert threads::shared::share($obj); # Make it shared 157b39c5158Smillert return (bless($obj, 'Foo')); # Make it an object 158b39c5158Smillert } 159b39c5158Smillert} 160b39c5158Smillert 161b39c5158Smillertmy $obj :shared; 162b39c5158Smillert$obj = Foo->new(); 163b39c5158Smillertok($$obj == 1, "Main: Object ID $$obj"); 164b39c5158Smillert 165b39c5158Smillertthreads->create( sub { 166b39c5158Smillert ok($$obj == 1, "Thread: Object ID $$obj"); 167b39c5158Smillert 168b39c5158Smillert $$obj = 10; 169b39c5158Smillert ok($$obj == 10, "Thread: Changed object ID $$obj"); 170b39c5158Smillert 171b39c5158Smillert $obj = Foo->new(); 172b39c5158Smillert ok($$obj == 2, "Thread: New object ID $$obj"); 173b39c5158Smillert } )->join(); 174b39c5158Smillert 175*898184e3Ssthen# Fixed by commit bb1bc619ea68d9703fbd3fe5bc65ae000f90151f 176*898184e3Ssthenmy $todo = ($] <= 5.013001) ? " # TODO - should be 2" : ""; 177*898184e3Ssthenok($$obj == 2, "Main: New object ID $$obj".$todo); 178b39c5158Smillert 179b39c5158Smillertexit(0); 180b39c5158Smillert 181b39c5158Smillert# EOF 182