> > This is fine at the target language level (e.g. perl6, python, jako, > > whatever), but how do we throw catchable exceptions up through six or > > eight levels of C code? AFAICS, this is more of why perl5 uses the > > JMP_BUF stuff - so that XS and functions like sv_setsv() can > > Perl_croak() without caring about who's above them in the call stack. > > This is my point exactly.
This is the wrong assumption. If you don't care about the call stack, how can you expect the [sig]longjmp can successfully unwind stack? The caller may have a malloc memory block, or have entered a mutex, or acquire the file lock of Perl cvs directory. You probably have to call Dan or Simon for the last case. > The alternative is that _every_ function simply return a status, which > is fundamentally expensive (your real retval has to be an out > parameter, to start with). This is the only right solution generally. If you really really really know everything between setjmp and longjmp, you can use it. However, the chance is very low. > To answer my own question (at least, with regards to Solaris), the > attributes(5) man page says that 'Unsafe' is defined thus: > > > An Unsafe library contains global and static data that is not > > protected. It is not safe to use unless the application arranges for > > only one thread at time to execute within the library. Unsafe > > libraries may contain routines that are Safe; however, most of the > > library's routines are unsafe to call. > > This would imply that in the worst case (at least for Solaris) we could > just wrap calls to [sig]setjmp and [sig]longjmp in a mutex. 'croak' > happens relatively infrequently anyway. This is not the point. The [sig]setjmp and [sig]longjmp are generally safe outside signal handler. Even they are not safe, we can easily write our own thread-safe version using very small amount of assembly code. The problem is they can not be used inside signal handler under MT, and it is (almost) impossible to write a thread-safe version. Hong