=head1 TITLE

Safe Signals

=head1 VERSION

    Maintainer: Uri Guttman <[EMAIL PROTECTED]>
    Date: 07 Aug 2000
    Version: 1
    Mailing List: perl6-language-flow
    Number: TBD

=head1 ABSTRACT

This RFC describes how Perl6 can support safe signals with multiple
techniques.

=head1 DESCRIPTION

Perl5 suffers from its well know unsafe signal handling. It is due to
the asynchronous way signals are triggered at the level of C
code. A signal could be delivered in Perl while some critical operation
(e.g. malloc) is happening and all hell breaks loose. Signals have to be
delivered synchronously with respect Perl op code dispatching.

=head1 IMPLEMENTATION

There are multiple ways to support safe signals and they can all easily
be supported. Here are the most common ways and various techniques which
make handling signals easier.

=head2 In-line Code

If you have only a single linear thread of code and want safe signals,
you have to pay the penalty of checking for them in between Perl op
codes. This requires the Perl compiler to insert signal checking op at
regular intervals in the op tree.  This can be done every N ops with N
being some special global value. The code to do the test can be done
in-line in the main dispatch loop and be very fast. The actual C handlers
will just be like the ones in the event loop and just bump counters and
set flags.

Enabling in-line testing for signals can also be a compile time option
so a selected section of of a thread could be where the test are
inserted.

Here is a possible pragma to enable this:

use signal in-line => 10 ;

Then you can just create callbacks for any signal as shown below.

=head2 Mailboxes

A mailbox is a combination of a semaphore and a queue/pipe. It is a
clean way to send messages between threads. A special mailbox for
signals can be created which can be tested and blocked upon. The data
read from the mailbox will be the signal name and any other info
attached to the signal. Any thread (including a single thread) can
synchornously test for signals under program control. This is how a
progrom would poll for signals.

=head2 Event Loops

Event loops support safe signals by delivering them synchronously with
the dispatch of other callbacks. Then the signal callback cannot collide
with any others. This is currently being done in Event.pm (and i think
Perl/Tk's event loop is similar here).

=head2 Threads

Threads can work with signals in two ways. First, one or more threads
can run event loops and their signal handlers are safe and can do work
or communicate with other threads. Second, any thread can block on the
special signal mailbox. When the signal is delivered, the blocked thread
can continue safely and can then do the work for that signal.

=head2 Callbacks

This pragma would use the same callback interface as all the new I/O
objects would. This consistancy of callback style in the language is a
major win here.  Since someone mentioned any default Perl callback names
be in caps, will go with that here.  Again the default method names
would be carefully chosen to be easy to remember and use,
e.g. SIGHUP_RECEIVED and SIGHUP_TIMEOUT would be the ones for the above
example if the callback value was an object or a class.

=head2 Timeouts

By using the general callback API, signals now can have builtin
timeouts. This simplifies some tasks which need to do work on a schedule
and also when you need it, e.g. checkpointing. If this were
triggered by SIGHUP, then it could be set to timeout every minute and
the callback would execute if there hasn't seen any HUPs in that period.

=head2 use signal pragma

I propose a pragma which would make creating signal callback more of a
top level operation and remove the need for the %SIG hash. The pragma
would be stackable so you could override a handler inside a code block.

It would be something like this:

# Here is a main line code callback with a sub ref and timeout
# the timeout will call the sub SIGHUP_TIMEOUT in this current package.

use signal name => 'SIGHUP', cb => \&hup_handler, timeout => 3600 ;
sub hup_handler { print "They hupped me! Bastards!!" }

# Here is a class level callback with the default callback name

use signal name => 'SIGINT', cb => __PACKAGE__ ;
sub SIGINT_HANDLER { print "They killed me! Bastards!!" }

# Here is a object callback with the a custom callback name

my $foo = Bar->new() ;
use signal name => 'SIGCANCEL', cb => $foo, method = 'cancel_handler' ;
sub Bar::cancel_handler { print "They cancelled me! Bastards!!" }

=head1 IMPACT

People will stop bitching about perl not having safe signals.

=head1 UNKNOWNS

=head1 REFERENCES

Event.pm                - XS based event loop module.

RFC #1                  - Implementation of Threads in Perl

RFC #47                 - Universal Asynch I/O (the moby one)

%SIG                    - perlvar

-- 
Uri Guttman  ---------  [EMAIL PROTECTED]  ----------  http://www.sysarch.com
SYStems ARCHitecture, Software Engineering, Perl, Internet, UNIX Consulting
The Perl Books Page  -----------  http://www.sysarch.com/cgi-bin/perl_books
The Best Search Engine on the Net  ----------  http://www.northernlight.com

Reply via email to