Home > Archive > PERL POE > March 2006 > Emulating signal catching behaviour on Win32?
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Emulating signal catching behaviour on Win32?
|
|
| Steven Mackenzie 2006-03-21, 10:14 pm |
| Hello,
I'm working on a Perl app that will run mainly on Windows.
It is a console app that crawls file shares and the net, populating a DB
with URLs to the documents that it finds, and updates the console with
endless scrolling text describing its progress.
Sometimes a user will get bored waiting for the crawl to terminate, and
in the previous version of the app (C++ native code), they could send
Ctrl-C from the command line, which would be caught and cause a graceful
shut down.
I had problems getting this to work using ActiveState Perl build 815 (
5.8.7) and the ActiveState POE ppm (POE 0.29). When I set a POE handler
for the SIGINT, POE would crash, reporting an "internal inconsistency"
after the signal was sent.
I tried to upgrade to POE 0.3301 from CPAN, but the "make tests" stage
hung, so I took the opportunity to upgrade to the latest Perl from
ActiveState (5.8.8, build 816).
POE compiled, tested and installed fine, but it seems that the latest
Win32 Perl no-longer sends signals from the console to the running
process, as neither my perl signal handlers or my poe signal handlers
are run if I hit Ctrl-C. (I can shut down the process using Ctrl-break,
which sends SIGBREAK, which I don't seem to be able to catch.)
The handler I want to run is simple -- just set a flag to tell the
internals to stop following links. POE is a big event loop, so how would
I keep an eye on the console to spot the user trying to tell the app to
give up?
Thanks for any clues,
Steven
| |
| Rocco Caputo 2006-03-21, 10:14 pm |
| On Mar 21, 2006, at 13:16, Steven Mackenzie wrote:
> POE compiled, tested and installed fine, but it seems that the latest
> Win32 Perl no-longer sends signals from the console to the running
> process, as neither my perl signal handlers or my poe signal handlers
> are run if I hit Ctrl-C. (I can shut down the process using Ctrl-
> break,
> which sends SIGBREAK, which I don't seem to be able to catch.)
>
> The handler I want to run is simple -- just set a flag to tell the
> internals to stop following links. POE is a big event loop, so how
> would
> I keep an eye on the console to spot the user trying to tell the
> app to
> give up?
This is a tough one.
ActivePerl's select() can't watch STDIN because it's based on
Winsock's select(), which only works with sockets. So passively
watching the console for regular input is out.
Perl doesn't catch your SIGINT attempts, and SIGBREAK seems to be
uncatchable. This rules out terminal signals, unless you can find
another one that works.
So the problem description rules out console input. Is a very small
Tk interface viable? Perhaps just one button: Stop, with the
messages still appearing on the related console.
Someone with more Windows experience should chime in.
--
Rocco Caputo - rcaputo@pobox.com
| |
| Steven Mackenzie 2006-03-22, 7:12 pm |
|
Rocco Caputo wrote:
>
> ActivePerl's select() can't watch STDIN because it's based on
> Winsock's select(), which only works with sockets. So passively
> watching the console for regular input is out.
How insightfuly worded!
I'm happy to *actively* watch the console, for instance using
Term::ReadKey <http://search.cpan.org/~jstowe/Term...2.30/ReadKey.pm>.
I've put the code to do this in my _stop handler, but I'd like a bit
more responsiveness, as sessions might be long running.
I'd like a console watcher session with a "check_console" event to fire
every second or so while there are still active worker sessions, but I
don't know how to code that ...
Also I'd like my shutdown sequence to be Ctrl-C, but it looks like
Term::Readline can't read that on Windows. I'll have to retrain the
users, which they hate.
> Perl doesn't catch your SIGINT attempts, and SIGBREAK seems to be
> uncatchable. This rules out terminal signals, unless you can find
> another one that works.
That's a curious thing - ActivePerl will catch signals if I am not
trying to handle them -- for instance, SIGINT will stop my process, but
if I write handlers, then the signals are silently ignored.
> Is a very small Tk interface viable? Perhaps just one button: Stop,
> with the messages still appearing on the related console.
A couple of months ago I made a very brief attempt to to set up a test
POE/Tk interface, but there seemed to be different ways to set it up,
and although I got a Linux version working, Windows/ActiveState did not
want to play.
Any pointers to Win32 aware documentation on this gratefully received!
I would like to dress the functionality in a simple UI, but my
perception is that that would get complicated ...
| |
| Rocco Caputo 2006-03-22, 7:12 pm |
| On Mar 22, 2006, at 09:26, Steven Mackenzie wrote:
> Rocco Caputo wrote:
>
>
> How insightfuly worded!
>
> I'm happy to *actively* watch the console, for instance using
> Term::ReadKey <http://search.cpan.org/~jstowe/TermReadKey-2.30/
> ReadKey.pm>.
>
> I've put the code to do this in my _stop handler, but I'd like a bit
> more responsiveness, as sessions might be long running.
>
> I'd like a console watcher session with a "check_console" event to
> fire
> every second or so while there are still active worker sessions, but I
> don't know how to code that ...
This is untested code, and you'll need to customize it.
Assuming the rest of the program is cooperative, it will check the
console once a second and shut down the entire application if the
user requests it.
POE::Session->create(
inline_states => {
_start => sub {
$_[KERNEL]->delay(ping => 1);
},
ping => sub {
my $user_stop = check_console_here();
if ($user_stop) {
# Or some other shutdown procedure.
$_[KERNEL]->signal( UIDESTROY => $_[KERNEL] );
}
else {
$_[KERNEL]->delay( ping => 1 );
}
},
},
);
> Also I'd like my shutdown sequence to be Ctrl-C, but it looks like
> Term::Readline can't read that on Windows. I'll have to retrain the
> users, which they hate.
Can Term::ReadKey catch Ctrl-C if you drop POE's signal handler and
set $SIG{INT} = "IGNORE" manually?
>
> That's a curious thing - ActivePerl will catch signals if I am not
> trying to handle them -- for instance, SIGINT will stop my process,
> but
> if I write handlers, then the signals are silently ignored.
It smells like a bug in ActivePerl. If you have a small plain-Perl
test case, you should submit it to them.
>
> A couple of months ago I made a very brief attempt to to set up a
> test
> POE/Tk interface, but there seemed to be different ways to set it up,
> and although I got a Linux version working, Windows/ActiveState did
> not
> want to play.
>
> Any pointers to Win32 aware documentation on this gratefully received!
>
> I would like to dress the functionality in a simple UI, but my
> perception is that that would get complicated ...
The first example at http://poe.perl.org/?POE_Cookbook/Tk_Interfaces
works for me, using POE 0.33 and ActivePerl 5.8.7.815.
--
Rocco Caputo - rcaputo@pobox.com
| |
| Steven Mackenzie 2006-03-22, 7:12 pm |
|
Rocco Caputo wrote:
>
>
> This is untested code, and you'll need to customize it.
>
> Assuming the rest of the program is cooperative, it will check the
> console once a second and shut down the entire application if the
> user requests it.
>
> POE::Session->create(
> inline_states => {
> _start => sub {
> $_[KERNEL]->delay(ping => 1);
> },
> ping => sub {
> my $user_stop = check_console_here();
> if ($user_stop) {
> # Or some other shutdown procedure.
> $_[KERNEL]->signal( UIDESTROY => $_[KERNEL] );
> }
> else {
> $_[KERNEL]->delay( ping => 1 );
> }
> },
> },
> );
Thank you for that -- but that would not stop if the main worker
sessions finish all their work? However, hopefully I'm not going to need
the workaround ...
> Can Term::ReadKey catch Ctrl-C if you drop POE's signal handler and
> set $SIG{INT} = "IGNORE" manually?
It can read it in a blocking read, but it seems Ctrl-C doesn't hang
around to be read if I try do do a non-blocking read.
So in this handler:
sub handler_read_term
{
my ($kernel, $heap, $session) = @_[KERNEL, HEAP, SESSION];
ReadMode 4; # Turn off controls keys
my $key = ReadKey(-1);
if(not defined ($key ) )
{
print STDERR "------ press q to quit!\n";
}
else
{
print "====== you pressed $key.\n";
if( $key eq "q" )
{
print "Please wait for shutdown\n";
_stop_when_convenient();
}
elsif( 3 == ord( $key ) )
{
print "====== ctrl-C pressed.\n";
print "Please wait for shutdown\n";
_stop_when_convenient();
}
}
ReadMode 0; # Reset tty mode before exiting
$kernel->delay('increment' => 0.5) if $heap->{count} < 10;
}
I can cause a shutdown by pressing q, but not by pressing Ctrl-C
>
>
> It smells like a bug in ActivePerl. If you have a small plain-Perl
> test case, you should submit it to them.
>
I just received a reply from support@activestate, and they said:
"We have identified this and a number of other issues with 5.8.8, and will be
releasing a new build with fixes within a w or so ( we are testing these
fixes now ). In the meantime, my best advice would be to use 815 instead."
> The first example at http://poe.perl.org/?POE_Cookbook/Tk_Interfaces
> works for me, using POE 0.33 and ActivePerl 5.8.7.815.
>
Erm, yes it does, even with 5.8.7.813 and POE 0.29 (current version in
the PPM repository). I didn't keep a record of my previous struggles,
but I'm sure I tried that sample. Time to try again perhaps ...
Final question; I usually prefer to stick to PPMs from ActiveState,
which would peg me at POE 0.29 at the moment. I don't know what your
release stratergy is -- is 0.3301 a production version? Would you
recommend it over 0.29?
Thanks for your help,
Steven
| |
| Rocco Caputo 2006-03-22, 7:12 pm |
| On Mar 22, 2006, at 16:26, Steven Mackenzie wrote:
> Rocco Caputo wrote:
>
$_[KERNEL]->signal( $_[KERNEL] => "UIDESTROY" );[color=darkred]
>
> Thank you for that -- but that would not stop if the main worker
> sessions finish all their work? However, hopefully I'm not going to
> need
> the workaround ...
You're right. The main worker sessions would somehow need to stop this.
>
> I just received a reply from support@activestate, and they said:
>
> "We have identified this and a number of other issues with 5.8.8,
> and will be
> releasing a new build with fixes within a w or so ( we are
> testing these
> fixes now ). In the meantime, my best advice would be to use 815
> instead."
Cool! I'm glad there's a fix forthcoming.
>
> Final question; I usually prefer to stick to PPMs from ActiveState,
> which would peg me at POE 0.29 at the moment. I don't know what your
> release stratergy is -- is 0.3301 a production version? Would you
> recommend it over 0.29?
0.29 is a couple years old. I don't recommend using it at all.
Version 0.34 will have installer changes that should work around
issues in ActiveState's PPD build system. No release date is
currently set, but you can grab a copy from the subversion repository
at SourceForge.
0.3301 is the current "production" release, inasmuch as it's the only
version officially released to CPAN right now.
--
Rocco Caputo - rcaputo@pobox.com
|
|
|
|
|