Hi,
Andy Wingo <[email protected]> skribis:
> A guile built without
> threads may fork to its heart's content. However a guile built with
> threads -- the default, recommended configuration -- should not call
> primitive-fork.
That’s a strong statement. When the only threads are the main thread
and the signal thread, everything’s alright. For example, this works
fine on GNU/Linux:
--8<---------------cut here---------------start------------->8---
(let ((p (primitive-fork)))
(case p
((0)
(sigaction SIGINT (lambda args
(format #t "kid ~a got ~a~%" (getpid) args)
(exit 0)))
(let loop () (loop))
(exit 1))
(else
(sleep 2)
(kill p SIGINT)
(format #t "killed ~a~%" p)
(waitpid p))))
--8<---------------cut here---------------end--------------->8---
It works because the signal thread is stuck in a read(2) with no lock
taken.
Things that don’t work include this:
--8<---------------cut here---------------start------------->8---
(use-modules (ice-9 futures))
(let* ((f (future (begin (sleep 4) (getpid))))
(p (primitive-fork)))
(case p
((0)
(format #t "kid -> ~a~%" (touch f)))
(else
(format #t "parent -> ~a~%" (touch f))
(waitpid p))))
--8<---------------cut here---------------end--------------->8---
Here the child waits forever because it has only one thread. As for
popen, that’s a bug (or undocumented limitation) of (ice-9 futures)
itself, more than anything else.
Ludo’.