Front page | perl.perl5.porters |
Postings from January 2008
Re: YATSB (yet another threads::shared bug)
Thread Previous
From:
Jerry D. Hedden
Date:
January 30, 2008 06:14
Subject:
Re: YATSB (yet another threads::shared bug)
Message ID:
1ff86f510801300614h4cbc8eb3qaf080c5b045e0395@mail.gmail.com
Adding this bug as a TODO test in the threads::shared test suite
> Dave, if you have the time, would you give some thought to
> the bug below? It seems that all the other threads::shared
> bugs I had previously found have been fixed, but this one
> still persists.
>
> It starts with a shared object that is attached to a shared
> scalar. Inside a thread, the object is first modified, and
> then replaced with a new one. When the thread terminates,
> however, the original object seems to still be in place.
> Then the bug just goes away.
>
> Here's the code (it's attached as well):
>
> #!/usr/bin/perl
>
> use strict;
> use warnings;
>
> package Foo; {
> use threads;
> use threads::shared;
>
> my $ID : shared = 1; # Incremented with each new object
>
> sub new
> {
> # Anonymous scalar with an internal ID
> my $obj = \do{ my $scalar = $ID++; };
> # Make it shared
> share($obj);
> # Make it an object
> return (bless($obj, 'Foo'));
> }
> }
>
> package main;
>
> use threads;
> use threads::shared;
>
> use Test::More 'no_plan';
>
> MAIN:
> {
> my $obj : shared;
> $obj = Foo->new();
>
> # Check the object - this part is okay
> print(" Main: Object ID $$obj\n");
> is($$obj, 1, "Main: Object ID $$obj");
> print("\n");
>
> # Now play with the shared object inside a thread
> threads->create( sub {
> # Check the object inside the thread - this part is okay
> print(" Thread: Object ID $$obj\n");
> is($$obj, 1, "Thread: Object ID $$obj");
> print("\n");
>
> # Modify object's 'ID' - this works
> $$obj = 10;
> print(" Thread: Object ID $$obj\n");
> is($$obj, 10, "Thread: Object ID $$obj");
> print("\n");
>
> # Replace the object with a new one - this works
> $obj = Foo->new();
> print(" Thread: Object ID $$obj\n");
> is($$obj, 2, "Thread: Object ID $$obj");
> print("\n");
>
> } )->join();
>
> # Check the object - it should be the new one from the thread,
> # but it isn't!
> print("BUG! Main: Object ID $$obj (should be 2)\n");
>
> # Wait a minute - suddenly the object reverts!
> # What's going on here?
> is($$obj, 2, "Main: Object ID $$obj");
> print(" Main: Object ID $$obj\n");
> }
> exit(0);
>
> It produces:
>
> Main: Object ID 1
> ok 1 - Main: Object ID 1
>
> Thread: Object ID 1
> ok 2 - Thread: Object ID 1
>
> Thread: Object ID 10
> ok 3 - Thread: Object ID 10
>
> Thread: Object ID 2
> ok 4 - Thread: Object ID 2
>
> BUG! Main: Object ID 10 (should be 2)
> ok 5 - Main: Object ID 2
> Main: Object ID 2
> 1..5
>
> As you can see, after the thread ends, $$obj has the value
> from the original object. Then in the is() call, $$obj
> becomes the 'correct' value.
>
> I thought maybe Test::More might be a factor, but commenting
> out all the is() calls doesn't fix $$obj after the thread exits.
> Further, replacing the final is() call with a dummy() no-op
> call does the same thing - it reverts $$obj to the correct
> value.
Thread Previous