develooper Front page | perl.perl5.porters | Postings from April 2010

[BUG] Safe signals changes causing hangs with threads (was RE: [perl.git] branch blead, updated. v5.12.0-80-gda76b85)

Thread Next
From:
Jerry D. Hedden
Date:
April 21, 2010 10:15
Subject:
[BUG] Safe signals changes causing hangs with threads (was RE: [perl.git] branch blead, updated. v5.12.0-80-gda76b85)
Message ID:
m2q1ff86f511004211014v9563aa61zbf2fa7585384e576@mail.gmail.com
Attached is a self-contained script that reproduces the problem.
Mostly it hangs
at line 47 (before the 'Debug: not hung' message).  However, it
occasionally hangs
at other places (e.g., trying to lock %SUSPEND).  Frequently, the script runs to
completion, but it does hang after a few runs.

I think there is some nasty interplay between threads::shared locks and the
PERL_ASYNC_CHECK() calls.  If I change the thread subroutine to change the
delete() to something else, I don't get the hangs.

On Tue, Apr 20, 2010 at 14:55, Jerry D. Hedden <jdhedden@cpan.org> wrote:
>> +Signal dispatch has been moved from the runloop into control ops. This should
>> +give a few percent speed increase, and eliminates almost all of the speed
>> +penalty caused by the introduction of "safe signals" in 5.8.0. Signals should
>> +still be dispatched within the same statement as they were previously - if
>> +this is not the case, or it is possible to create uninterruptable loops, this
>> +is a bug, and reports are encouraged of how to recreate such issues.
>
> Since the PERL_ASYNC_CHECK() changes were made to blead, my module
> Thread::Suspend has been hanging during 'make test'.  I found that it
> hangs in a most peculiar spot:  Right after an 'if' statement inside a
> a 'for loop'.  When I put debug statements in, my code looks like this:
>
> sub threads::suspend
> {
>    my ($thing, @threads) = @_;
>
>    if ($thing eq 'threads') {
>        if (@threads) {
>            # Suspend specified list of threads
>            @threads = grep { $_ }
>                       map  { (ref($_) eq 'threads')
>                                    ? $_
>                                    : threads->object($_) }
>                            @threads;
>        } else {
>            # Suspend all non-detached threads
>            push(@threads, threads->list(threads::running));
>        }
>    } else {
>        # Suspend a single thread
>        push(@threads, $thing);
>    }
>
>    # Suspend threads
>    lock(%SUSPEND);
>    foreach my $thr (@threads) {
>        my $tid = $thr->tid();
>        # Increment suspension count
>        if (! $SUSPEND{$tid}++) {
>            # Send suspend signal if not currently suspended
>            $thr->kill($SIGNAL);
>            if (! $thr->is_running()) {
>                # Thread terminated before it could be suspended
>                delete($SUSPEND{$tid});
>            }
> print("Debug: sent signal\n");
>        }
> print("Debug: not hung\n");
>    }
>
>    # Return list of affected threads
>    return ($thing eq 'threads')
>                    ? grep { $_->is_running() } @threads
>                    : $thing;
> }
>
>
> When I run the test, I get:
>
>> perl -Ilib t/00_basic.t
> 1..57
> ok 1 - use Thread::Suspend;
> # Testing Thread::Suspend 1.19
> ok 2 - threads->can(...)
> ok 3 - Threads created
> ok 4 - No threads suspended
> ok 5 - Thread 1 not suspended
> ok 6 - Thread 1 running (line 48)
> Debug: sent signal
> Debug: not hung
> ok 7 - One thread suspended
> ok 8 - Thread 1 suspended
> ok 9 - Thread 1 suspended
> ok 10 - Thread 1 stopped (line 54)
> Debug: not hung
> ok 11 - One thread suspended
> ok 12 - Thread 1 suspended
> ok 13 - Thread 1 suspended twice
> ok 14 - Thread 1 stopped (line 60)
> ok 15 - One thread suspended
> ok 16 - Thread 1 suspended
> ok 17 - Thread 1 still suspended
> ok 18 - Thread 1 stopped (line 66)
> ok 19 - No threads suspended
> ok 20 - Thread 1 not suspended
> ok 21 - Thread 1 running (line 71)
> ok 22 - No threads suspended
> ok 23 - Thread 2 not suspended
> ok 24 - Thread 2 running (line 48)
> Debug: sent signal
>
>
> The test is now hung and I have to hit ^C.  This is
> very repeatable for me.

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About