aboutsummaryrefslogtreecommitdiff
path: root/src/libthread
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2005-07-27 20:25:34 +0000
committerrsc <devnull@localhost>2005-07-27 20:25:34 +0000
commit9689b580bdb168b87a20a5e466864337d591acfa (patch)
tree973ea1fb43cf9559b4a0a98b7e08d718e1fff876 /src/libthread
parent5f4529e351e77e4ab61d258ca3dea69852a1e0ba (diff)
downloadplan9port-9689b580bdb168b87a20a5e466864337d591acfa.tar.gz
plan9port-9689b580bdb168b87a20a5e466864337d591acfa.tar.bz2
plan9port-9689b580bdb168b87a20a5e466864337d591acfa.zip
Try to avoid races in underlying C library
during threadexitsall.
Diffstat (limited to 'src/libthread')
-rw-r--r--src/libthread/BSD.c14
-rw-r--r--src/libthread/Linux.c14
2 files changed, 28 insertions, 0 deletions
diff --git a/src/libthread/BSD.c b/src/libthread/BSD.c
index 0bc19057..8090ea59 100644
--- a/src/libthread/BSD.c
+++ b/src/libthread/BSD.c
@@ -285,6 +285,20 @@ threadexitsall(char *msg)
int i, npid, mypid;
Proc *p;
+ /*
+ * Only one guy, ever, gets to run this.
+ * If two guys do it, inevitably they end up
+ * tripping over each other in the underlying
+ * C library exit() implementation, which is
+ * trying to run the atexit handlers and apparently
+ * not thread safe. This has been observed on
+ * both Linux and OpenBSD. Sigh.
+ */
+ {
+ static Lock onelock;
+ lock(&onelock);
+ }
+
if(msg == nil)
msg = "";
mypid = getpid();
diff --git a/src/libthread/Linux.c b/src/libthread/Linux.c
index f741a03d..14698856 100644
--- a/src/libthread/Linux.c
+++ b/src/libthread/Linux.c
@@ -311,6 +311,20 @@ threadexitsall(char *msg)
int i, npid, mypid;
Proc *p;
+ /*
+ * Only one guy, ever, gets to run this.
+ * If two guys do it, inevitably they end up
+ * tripping over each other in the underlying
+ * C library exit() implementation, which is
+ * trying to run the atexit handlers and apparently
+ * not thread safe. This has been observed on
+ * both Linux and OpenBSD. Sigh.
+ */
+ {
+ static Lock onelock;
+ lock(&onelock);
+ }
+
if(msg == nil)
msg = "";
mypid = getpid();