Nicholas Clark wrote: > Currently it's cheap to sigsetjmp (I'm assuming compared with setting up a > whole thread) but expensive to keep checking > Setting up a thread would be expensive, but there's not cost involved in > checking that the thread you're running in is still running! > [can we attach enough things to thread exit to tidy up what needs tidying?] setjmp/sigsetjmp are NOT thread safe and CANNOT be used in a threaded program. Period. Perl5 uses setjmp even when built threaded, and is therefore irretrievably broken. If perl6 uses setjmp and also uses threads, it too will be irretrievably broken. Here is what our threads guru has to say on the subject: > They are designed to work as advertised, but they are MT-usafe in > principle. > > They are MT-unsafe because if you use siglongjmp(), say, from a signal > handler, then you have no idea where the application was executing when > the signal occurred. It may have been holding a mutex or it may have > been asleep in a cond_wait(). The siglongjmp leaves the state of the > application undefined with respect to the locks that are held. > > The short answer is *never use them* in a multithreaded application. As far as I recollect perls use of setjmp isn't just triggered by eval - other things such as entering a scope can do it too - is that correct? I'm not sure that starting a thread per eval context is a sensible thing to do. Threads are cheap, but not that cheap. Basically there is no free lunch here - if we want to use threads and do exception handling in perl6 we will have to roll our own. If perl6 has something akin to the perl5 stack, eval/die will have to be implemented so that that it rolls back up the stack on die, rather than the current longjmp hack. Note that even if we used C++ it wouldn't help us in this case, because although C++ does exceptions, it knows nothing about threads, mutexes or CVs. I suspect the perl6 interpreter loop will look something like: while (! end of script) { if (at cancellation point) { if (signal detected) call script signal handler; if (something died) rollback stack; } else { do next OP; } } In other words the C level signal handler will have to do no more than setting a flag, as will the implementation of die(). By cancellation point I mean somewhere that is defined as 'safe', i.e. not holding any mutexes or waiting on any CVs etc. I suspect a reasonable thing might be to have a special 'Now it is safe' opcode that is put out by the compiler at the appropriate places. It would be nice if this corresponded to a syntactic boundary such as an entire statement, so that for example my $a = $b * $c / $d; was guaranteed to either to be fully evaluated or not at all. Alan BurlisonThread Previous | Thread Next