warning instead of error on multithreaded fork
authorAndy Wingo <wingo@pobox.com>
Thu, 17 Jan 2013 11:18:22 +0000 (12:18 +0100)
committerAndy Wingo <wingo@pobox.com>
Thu, 17 Jan 2013 11:25:52 +0000 (12:25 +0100)
* libguile/posix.c (scm_fork): Issue a warning instead of an error on a
  multithreaded fork.
* doc/ref/posix.texi (Processes): Add note about multithreaded fork.

doc/ref/posix.texi
libguile/posix.c

index 0a688e9..a019f4e 100644 (file)
@@ -1,7 +1,7 @@
 @c -*-texinfo-*-
 @c This is part of the GNU Guile Reference Manual.
 @c Copyright (C)  1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2007,
-@c   2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+@c   2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
 @c See the file guile.texi for copying conditions.
 
 @node POSIX
@@ -1785,6 +1785,20 @@ Creates a new ``child'' process by duplicating the current ``parent'' process.
 In the child the return value is 0.  In the parent the return value is
 the integer process ID of the child.
 
+Note that it is unsafe to fork a process that has multiple threads
+running, as only the thread that calls @code{primitive-fork} will
+persist in the child.  Any resources that other threads held, such as
+locked mutexes or open file descriptors, are lost.  Indeed,
+@acronym{POSIX} specifies that only async-signal-safe procedures are
+safe to call after a multithreaded fork, which is a very limited set.
+Guile issues a warning if it detects a fork from a multi-threaded
+program.
+
+If you are going to @code{exec} soon after forking, the procedures in
+@code{(ice-9 popen)} may be useful to you, as they fork and exec within
+an async-signal-safe function carefully written to ensure robust program
+behavior, even in the presence of threads.  @xref{Pipes}, for more.
+
 This procedure has been renamed from @code{fork} to avoid a naming conflict
 with the scsh fork.
 @end deffn
index 7c87f3f..b9097d4 100644 (file)
@@ -1260,8 +1260,12 @@ SCM_DEFINE (scm_fork, "primitive-fork", 0, 0, 0,
        async-signal-safe.  We can't guarantee that in general.  The best
        we can do is to allow forking only very early, before any call to
        sigaction spawns the signal-handling thread.  */
-    SCM_MISC_ERROR ("attempt to fork while multiple threads are running",
-                    SCM_EOL);
+    scm_display
+      (scm_from_latin1_string
+       ("warning: call to primitive-fork while multiple threads are running;\n"
+        "         further behavior unspecified.  See \"Processes\" in the\n"
+        "         manual, for more information.\n"),
+       scm_current_warning_port ());
   pid = fork ();
   if (pid == -1)
     SCM_SYSERROR;