=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