Dan Sugalski <[EMAIL PROTECTED]> wrote:At 9:41 AM +0200 5/12/04, Leopold Toetsch wrote:
$SIG{CHLD} = sub { 1; };
This could probably create the event PMC, associate the user callback with it, enable SIGCHLD and be done with it. It's the same as with a timer event.
Which is swell, except.... the problem you run into here is persistent signal handlers.
A persistent signal handler is some storage in the interpreter, that associates the interrrupt number with a Sub PMC (or a chain of these). The signal internally is a signal event. On delivery of the event (and here we are already again in user mode) a PMC is created that holds the event information. This PMC is then passed on to the users callback.
Which doesn't address the problem. You can't create a PMC inside the signal handler. Nor can you create anything *else* in the signal handler. All you can do is use something that already exists. Allocating a single structure to the signal handler doesn't help since if a second signal comes in before the first is done (or potentially even started) you'll lose it.
> ... This goes for GUI event handlers too. You canpre-allocate a PMC, but then you need to make sure the
[ sentence not finished but ... ] ... that you don't run out of pre-allocated PMCs. Which is likely when you start tracking mouse move events or such. This doesn't work. You are gonna loosing events. GUI events are coming from the GUI thread. You can malloc an internal event structure holding the mouse coordinates, but you can't create a PMC there. Then the event gets put into Parrot's event system, then see below... Signals or GUI events aren't really differing.
The GUI thread, if its in a position to malloc, is in a position to allocate a PMC from the destination interpreter. That's not the problem. The problem comes in when you're in interrupt mode and can't allocate anything.
>>*But* the first question is: do we really want PMCs in the inyards ofthe event system (except callback sub PMCs)?
We need something. Not having a PMC doesn't make things any better, since the problems persist regardless of what we might want to do. If something can fire more than once it needs to have something to inject into the event queue, and that something can't be allocated from the OS generally (memory allocation's not callable from interrupt level)
I know that. The current scheme is safe WRT these problems. A signal originates from the signal handler, incrementing a sig_atomic_t variable per signal.
That doesn't work. Besides requiring an aligned atomic word per interrupt source, it requires something to scan those words
But the io_thread (which is the only one that has the signal unblocked) gets interrupted with EINTR. Here the (malloc) allocation of the event structure is safe, and all needed stuff is put into the event structure. The event is now posted to the global event thread which waits on the queue condition.
That's pretty horribly platform-dependent. As schemes go... it can't work most places. This is going to break badly on quite a few platforms, especially once we start spawning more threads off.
> Very good questions. We have to do it, there's no choice. I left theunderlying mechanism open for discussion.
There's always a choice. Please have a look at the current code.
I have. It's fundamentally broken pretty much everywhere. We just don't trigger off the broken behaviour yet.
--
Dan
--------------------------------------"it's like this"------------------- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk