Subj : Re: A pity that there is no forkall() which clones threads To : comp.programming.threads From : Marcin 'Qrczak' Kowalczyk Date : Sun Mar 06 2005 01:28 pm David Hopwood writes: > ForkProcess can work with sensible semantics if foreign code is > uninterruptible by default. In that case only foreign code that has > explicitly asked to be interruptible will be killed. Indeed it is uninterruptible. When it invokes the C function which gives it access to the runtime again after a foreign call or before a callback, and this thread had Kogut signals unblocked, then any signals sent to this thread in the meantime are processed. This is unfortunate if the foreign code blocks for long, because there is no good way to interrupt it. If this thread was designed to handle Unix signals, then they are unblocked in this thread (and blocked in others) and thus they can interrupt syscalls (though the actual Kogut signal handler will be run when the thread goes back to the Kogut runtime). This is not enough for ForkProcess - the suspending signal is plain Kogut signal, not a Unix signal. Note that plain blocking I/O and timeouts don't make the thread bound and just cause my scheduler to do epoll/poll/select, and thus they pose no problems for processing Kogut signals. The issue is with functions like waitpid and getaddrinfo which don't have asynchronous equivalents in Unix API and the only way to support them without blocking all threads is to make the current thread bound to a pthread (and spawn a worker for the rest if it's needed and if there is no idle worker). Maybe I should introduce something which says "when you want to interrupt me while I'm making this foreign call, send me SIGUSR1". This setting would be consulted when sending a Kogut signal, after realising that the target thread is inside a foreign call. This would help in case of WaitForProcess. It would not be completely robust: there is a time window when such signal would collide with a real signal sent from another process and the information about the real signal would be lost, and it's possible that this thread would steal a signal sent to the process and thus prevent interruption of some syscall in the rest of the program - but it's probably impossible to implement better... > Add a function that foreign code can use to set the interruptible > flag for the current thread. The flag is always unset (i.e. > uninterruptible) on entry to a foreign function, and setting it only > lasts only until the code returns or next makes a call into the Kogut > runtime. (This ensures that there can be no problems with forgetting > to reset the flag or failing to do so because of a C++ exception.) Hmm. An interesting idea. This would be specific to ForkProcess: "don't wait for me, I agree to be evaporated at fork". > Note that foreign code only has to set the interruptible flag when it > does blocking I/O or a lengthy computation that does not call back > into the runtime. If it calls back to the runtime, it must use a C function which among other things processes pending signals. This flag would be used before lengthy computations which don't cause effects on the world, only read its state, like getaddrinfo. The implementation would be very ugly though. I'm not sure whether it's doable at all without rewriting the whole forking logic. -- __("< Marcin Kowalczyk \__/ qrczak@knm.org.pl ^^ http://qrnik.knm.org.pl/~qrczak/ .