summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2013-01-17 12:38:56 +0100
committerAndy Wingo <wingo@pobox.com>2013-01-17 12:38:56 +0100
commita796d0a95442b379a9ff2cdf9e0eb6efccc5dc08 (patch)
tree05142a024acdb1691f7617293cf1da92ddfd3ae3
parent36c210d14e8572939901b9251492a3f4bf94988c (diff)
downloadguile-a796d0a95442b379a9ff2cdf9e0eb6efccc5dc08.tar.gz
warn on multithreaded fork
* libguile/posix.c (scm_fork): Issue a warning on a multithreaded fork. * doc/ref/posix.texi (Processes): Add note about multithreaded fork. * test-suite/tests/00-socket.test: Moved here, from socket.test, so as to run before any threads are created. * test-suite/Makefile.am: Adapt.
-rw-r--r--doc/ref/posix.texi15
-rw-r--r--libguile/posix.c16
-rw-r--r--test-suite/Makefile.am2
-rw-r--r--test-suite/tests/00-socket.test (renamed from test-suite/tests/socket.test)0
4 files changed, 31 insertions, 2 deletions
diff --git a/doc/ref/posix.texi b/doc/ref/posix.texi
index 0a688e92d..18aadca85 100644
--- a/doc/ref/posix.texi
+++ b/doc/ref/posix.texi
@@ -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,19 @@ 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
diff --git a/libguile/posix.c b/libguile/posix.c
index 4d5fdcf96..324f21b78 100644
--- a/libguile/posix.c
+++ b/libguile/posix.c
@@ -1249,6 +1249,22 @@ SCM_DEFINE (scm_fork, "primitive-fork", 0, 0, 0,
#define FUNC_NAME s_scm_fork
{
int pid;
+ if (scm_ilength (scm_all_threads ()) != 1)
+ /* Other threads may be holding on to resources that Guile needs --
+ it is not safe to permit one thread to fork while others are
+ running.
+
+ In addition, POSIX clearly specifies that if a multi-threaded
+ program forks, the child must only call functions that are
+ 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_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;
diff --git a/test-suite/Makefile.am b/test-suite/Makefile.am
index 880e1e2cf..9fba7b8b3 100644
--- a/test-suite/Makefile.am
+++ b/test-suite/Makefile.am
@@ -23,6 +23,7 @@
SUBDIRS = standalone vm
SCM_TESTS = tests/00-initial-env.test \
+ tests/00-socket.test \
tests/alist.test \
tests/and-let-star.test \
tests/arbiters.test \
@@ -114,7 +115,6 @@ SCM_TESTS = tests/00-initial-env.test \
tests/regexp.test \
tests/session.test \
tests/signals.test \
- tests/socket.test \
tests/srcprop.test \
tests/srfi-1.test \
tests/srfi-6.test \
diff --git a/test-suite/tests/socket.test b/test-suite/tests/00-socket.test
index 6deb28542..6deb28542 100644
--- a/test-suite/tests/socket.test
+++ b/test-suite/tests/00-socket.test