Subj : Re: A pity that there is no forkall() which clones threads To : comp.programming.threads From : David Hopwood Date : Tue Mar 08 2005 02:37 am Giancarlo Niccolai wrote: > Marcin 'Qrczak' Kowalczyk wrote: >> >>Maybe I should introduce something which says "when you want to >>interrupt me while I'm making this foreign call, send me SIGUSR1". > > This would be the nicest way to do it; however, this is not portable to i.e. > windows... pthread_cancel is portable to pthreads-win32, and that's another reason to use it instead of signals. Unfortunately pthread_cancel can only be used to kill a pthread, not to send it an asynchronous signal. However it's still possible to implement a completely general asynchronous signal mechanism on top of pthread_cancel and user-level threads (just annoyingly complex). > Oh well but fork is not portable to windows too, AFAIK ... Interrupting or sending Kogut signals to threads needs to work even on platforms where ForkProcess doesn't. >>>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". > > That's right, but be careful: the space between the flag setting in the > foreign api and the return to the VM (or the call to something inside the > VM) must be async-cancel-safe too. Not for fork, but yes if this flag is also used to enable pthread_cancel with type PTHREAD_CANCEL_ASYNCHRONOUS. > And that's a problem: > > mutex_lock(); > can_cancel_me = false; > mutex_unlock(); > > would not do as you can get cancelled before releasing the lock. An > atomic operation, or preventing cancellation right after the calls/ > returns (with pthread_set_cancel_state), is in order. That's not the problem. Just acquire the lock outside the PTHREAD_CANCEL_ENABLED block (or don't lock accesses to the flag at all, and use memory barriers instead). The tricky thing is that when interrupting a Kogut (user-level) thread that is bound to a pthread, you need to both call pthread_cancel, *and* send a Kogut signal to it. The pthread_cancel may not work because the thread has just left the interruptible block (by calling pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, ...)), but in that case the Kogut signal will. >>>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. > > It's doable, but it's actually quite ugly. IMHO, you should just say "if you > use FORK with the kogut VM being in MT, the state of the child is > undefined. Either stop every thread before calling fork() or call it before > starting threads". That wouldn't be consistent with the 'philosophy' of the language as Marcin has described it. Kogut is not C; it's a concurrent language with defined behaviour for concurrent constructs unless absolutely necessary. *If* there were a restriction that ForkProcess should only be called when one thread is running, it would be trivial for the VM to check that and throw an exception if not. There is no justification for this to be undefined behaviour. -- David Hopwood .