Messages in this thread |  | | | From | "Stephen D. Williams" <> | | Subject | Re: Timer, sigprocmask, etc. as memory mapped regions for performance | | Date | Mon, 9 Feb 1998 09:29:27 -0500 (EST) |
| |
I need to reread the Posix specs on this, but I'll try to answer now anyway.
> On Mon, 2 Feb 1998, Stephen D. Williams wrote: > > > sigprocmask is more difficult, but no less doable. This one actually > > I found a way to do completely in the libc library, but haven't had > > time to actually implement. I'll describe it here since I want it > > done so badly: > > ... I don't think it's possible to implement POSIX semantics in userland. > > > First you 'wrap' all the signal functions so that a libc signal > > handler was the Real signal handler for all signals and that signal > > handlers that the application registered were noted in vectors. Calls > > to sigprocmask (and family) just modify flags in the library. When a > > signal is triggered, the library function looks at the mask, calls the > > real handler if unmasked, or calls the Real sigprocmask to block the > > signal and records the pending signal. When the application unmasks > > the signal, the library calls the real handler and upon return makes > > the system call to Really unmask the signal. > > How do you deal with SA_RESTART and EINTR? If you take the signal then > you've caused EINTR, and the application may not be expecting (or want) > EINTR. If you use SA_RESTART for all of your handlers then as far as I > can tell from looking at the Single Unix spec you can't choose to > interrupt a syscall from within a signal handler... you essentially need > to set/unset the SA_RESTART bit in the kernel for each signal.
The environment that I normally work in assumes that every system call is either a 'fast' system call or used in async mode. Even select() is used with a small timeout to allow for efficient polling. (Note polling of IO, but things triggered by IO, watchdogs, etc.) We don't use SA_RESTART. It sounds like I'd either have to settle for only having this available in a restricted mode OR supporting this with kernel modifications, my original plan.
> Which is great if you don't need to twiddle it fast. Unfortunately I need > to twiddle it fast... because I need to get EINTR in some situations and > not get it in other situations. (The application is Apache, and there's a > critical region around accept() where I have to see EINTR, but everywhere > else in the code I don't want to get any EINTR.)
Seems like an odd requirement, but I haven't looked at the Apache source much yet. I can understand not wanting to handle EINTR everywhere, but why do you need it around accept? Why not use the async mode?
> Note that I've been able to interrupt some syscalls, but not all of them > using a technique like this: > > set up SIGUSR1 with SA_RESTART and add SIGUSR2 to its sa_mask > > set up SIGUSR2 without SA_RESTART > > when a SIGUSR1 is received, raise(SIGUSR2) > > SIGUSR2 handler is a nop > > Since SIGUSR2 is blocked during the SIGUSR1 handler the SIGUSR2 isn't > delivered until after the SIGUSR1 handler completes. Then SIGUSR2 is > delivered and causes an EINTR... or it should. And it does for some > syscalls (such as whatever pause() wraps), but doesn't for accept()... and > I happen to really need it to work for accept() :) > > But since it appears to have similar problems on Solaris I'm just dropping > this approach.
> Dean
Maybe there is a different way to get the effect you want that is portable. I do need to find what's not doable in userland with my plan. Could you detail what you think is a problem, beyond the abov3 (or possibly restating the above).
Thanks! sdw
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu
|  |