Nick Ing-Simmons wrote: > Apparently not. I cannot at present think what sigsetjmp() gains > us. Do you have an guidelines which say "use sigsetjmp() if your code does X?" You need to use it if you want the signal mask restored when you do the siglongjmp. The typical use would be if you are going to do a siglongjmp out of a signal handler. POSIX doesn't specify what happens to the signal mask if you use setjmp/longjmp in a signal handler - it could either be restored or left with the pending signal blocked. sigsetjmp/siglongmp have specified semantics - if the second parameter to sigsetjmp is non-zero, a subsequent siglongjmp will restore the signal mask. In perl terms, I think the only time this would happen is if you did a die inside a signal handler, and expected to go back to an enclosing eval() with the signal handler restored. You could also use it for timing out long operations, using SIGALRM and an alarm() call, but note the caveat in paragraph 3 below. Here are the appropriate bits of the sigsetjmp manpage: The sigsetjmp() function saves the calling process's regis- ters and stack environment (see sigaltstack(2)) in env for later use by siglongjmp(). If savemask is non-zero, the calling process's signal mask (see sigprocmask(2)) and scheduling parameters (see priocntl(2)) are also saved. The siglongjmp() function restores the environment saved by the last call of sigsetjmp() with the corresponding env argument. After siglongjmp() completes, program execution continues as if the corresponding call to sigsetjmp() had just returned the value val. The siglongjmp() function can- not cause sigsetjmp() to return the value 0. If siglongjmp() is invoked with a second argument of 0, sig- setjmp() will return 1. At the time of the second return from sigsetjmp(), all external and static variables have values as of the time siglongjmp() was called. If a signal-catching function interrupts sleep(3C) and calls siglongjmp() to restore an environment saved prior to the sleep() call, the action associated with SIGALRM and time it is scheduled to be generated are unspecified. It is also unspecified whether the SIGALRM signal is blocked, unless the process's signal mask is restored as part of the environment. The siglongjmp() function restores the saved signal mask if and only if the env argument was initialized by a call to the sigsetjmp() function with a non-zero savemask argument. Having the defined semantics provided by sigsetjmp/siglongjmp is nice, but because sigsetjmp is called so frequently, and because it requires a system call each time, the overhead is intolerable in performance terms - see Ilya's recent '[PATCH 5.7.0] speeding up object creation/destruction 4x times' thread (http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2000-12/msg00798.html), part of which was to revert back to using setjmp/longjmp instead of sigsetjmp/siglongjmp. As I recollect, the relevant bit of the perl documentation recommends that you explicitly re-establish signal disposition inside the handler - if this is done correctly, sigsetjmp doesn't actually achieve anything other than a significant slowdown of the entire interpreter. What I don't understand is why we must do a sigsetjmp for *every* block in the interpreter - I'm surmising here, but surely sigsetjmp is only required if a) the block is wrapped in an eval and b) there is an active signal handler when the block is entered? The current approach seems to be a bit of a blunderbuss, and I for one think the performance penalty of using sigsetjmp is just to heavy to bear. Don't forget that due to a long-standing breakage in sigsetjmp/siglongjmp on Solaris x86, sigsetjmp was disabled on that platform, and I can't recollect anyone reporting any bugs as a result. My vote is for us to revert back to setjmp, and as I indicated I may well just disable it regardless when I integrate 5.6.1 into Solaris. Alan BurlisonThread Previous | Thread Next