Hi,

Andy Wingo <wi...@pobox.com> 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’.


Reply via email to