On Sun, 21 Jan 2001 17:28:49 -0500, Dan Sugalski wrote: >The issue of 'which thread' comes in with signals. We can tell with real >async events, since they'll have thread ownership tags on them if we care, >but we can't do that with signals, and then we have the issue of "which >thread" to deal with? Here's how I've dealt with signals in a cooperatively threaded Perl library. This design probably is too simple for Perl6, but it might be useful to consider. The library maintains threads' parent/child relationships. Each thread is something of a session leader for the threads beneath it, at least where signals are concerned. Signal events arriving at a thread are first propagated to its children, and this repeats recursively down to the leaf nodes on the family tree. In essence, signal delivery happens from the leaf threads back up to the ancestors they were originally destined for. Operating system signals are posted to the library's "kernel", which is the ultimate ancestor of every thread. This effectively (although perhaps not efficiently) broadcasts OS signals to every thread. The library's kernel decides which signals are fatal. It can do this because it's also the event dispatcher. Threads that don't handle fatal signals are stopped. Each thread has a destructor, so everything gets a chance to clean up, even after fatal signals. The library has an extra signal class: nonmaskable. Every thread that receives a nonmaskable signal is stopped regardless whether it handled the signal. Nonmaskable signals tend to be fictitious. They are generated by the library itself, and they're usually meant to signal a global shutdown. Two examples: UIDESTROY is broadcast when a GUI's main window is closed. The user wants this program to stop, and so it shall. ZOMBIE is broadcast when every thread has stopped running, and nothing is available to restart them. Imagine two threads playing ping-pong with an event. If one drops the ball, both threads' callbacks keep them alive. A program can detect when it has no more balls in play (the queued-event counter is 0) and shut itself down. (It's a little more involved than this: Watched filehandles are significant, for example, so there's a counter for those, too.) Here are two things Perl6 can do that my library doesn't, but I'm going to recommend against them in a moment. Perl6 will know which thread forked which process; it can track this information to send SIGCH?LD to appropriate threads. The system's SIGPIPE can be ignored altogether. Wherever a PerlIO function returns EPIPE, it can also post SIGPIPE to the same thread. I haven't implemented thess is my library because they preclude the ability to set global SIGCHLD or SIGPIPE handlers in some totally unrelated thread. Someone out there will want to do this, and it might just be me. It helps that these tend to be "survivable" signals; only the interested threads will ever notice them even when they're broadcast everywhere. Apropos of Perl 5: I've experimented long and hard on the language level in perl 5, and I have a test case for detect them without using handlers. It's unreliable though. That is, it may miss duplicate signals between checks. When is this an issue, though? -- Rocco Caputo / [EMAIL PROTECTED] / poe.perl.org / poe.sourceforge.net