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