guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: wip-threads-and-fork


From: Andy Wingo
Subject: Re: wip-threads-and-fork
Date: Mon, 27 Feb 2012 10:39:11 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3 (gnu/linux)

Hi,

On Sun 26 Feb 2012 23:00, address@hidden (Ludovic Courtès) writes:

>> 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.

Don't shoot the messenger ;)  I tried hard to make it work, but there's
no getting around POSIX here.

> When the only threads are the main thread
> and the signal thread, everything’s alright.  For example, this works
> fine on GNU/Linux:
>
> (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))))
>
> It works because the signal thread is stuck in a read(2) with no lock
> taken.

"Works" ;-) It mostly works on GNU/Linux.  But not all the time!  Other
processes can send your thread signals -- indeed, one would expect that
it's for that reason that you installed a signal handler.  If the
signal-handling thread wakes up and queues an async, it could be in the
middle of allocation, hold the alloc lock, and thereby prevent the child
from allocating anything.  Or it could have the async mutex.

I really doubt that we can build a stable system on top of such shaky
guarantees.

I 

> Things that don’t work include this:
>
> (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))))
>
> Here the child waits forever because it has only one thread.

Or because some other thread has the allocation lock, or some other
lock, including even the gconv lock deep in libc, etc.

> As for popen, that’s a bug (or undocumented limitation) of (ice-9
> futures) itself, more than anything else.

Popen now works with threads.

Andy
-- 
http://wingolog.org/



reply via email to

[Prev in Thread] Current Thread [Next in Thread]