summaryrefslogtreecommitdiff
path: root/lib/librthread/rthread.c
diff options
context:
space:
mode:
authorPhilip Guenther <guenther@cvs.openbsd.org>2015-05-10 18:33:16 +0000
committerPhilip Guenther <guenther@cvs.openbsd.org>2015-05-10 18:33:16 +0000
commit03c73ce152e59a9d1d99d4b789085554a316ebd7 (patch)
tree790454b40d8659ab68fbe5368cd6eb4e3e9f0a0a /lib/librthread/rthread.c
parente3a9fcebd8f4c8984b5b3bb6e016aadddd352a25 (diff)
In the child after fork, the dl lock has to be forced as its inner spinlock
may have been grabbed by another thread in the parent before the fork problem report from dcoppa@, ok kettenis@
Diffstat (limited to 'lib/librthread/rthread.c')
-rw-r--r--lib/librthread/rthread.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/lib/librthread/rthread.c b/lib/librthread/rthread.c
index 72babbf5032..5f9ca87471c 100644
--- a/lib/librthread/rthread.c
+++ b/lib/librthread/rthread.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rthread.c,v 1.81 2015/04/29 06:01:37 guenther Exp $ */
+/* $OpenBSD: rthread.c,v 1.82 2015/05/10 18:33:15 guenther Exp $ */
/*
* Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org>
* All Rights Reserved.
@@ -671,8 +671,7 @@ _rthread_dl_lock(int what)
static struct pthread_queue lockers = TAILQ_HEAD_INITIALIZER(lockers);
static int count = 0;
- if (what == 0)
- {
+ if (what == 0) {
pthread_t self = pthread_self();
/* lock, possibly recursive */
@@ -689,9 +688,7 @@ _rthread_dl_lock(int what)
}
count++;
_spinunlock(&lock);
- }
- else
- {
+ } else if (what == 1) {
/* unlock, possibly recursive */
if (--count == 0) {
pthread_t next;
@@ -704,6 +701,12 @@ _rthread_dl_lock(int what)
if (next != NULL)
__thrwakeup(next, 1);
}
+ } else {
+ /* reinit: used in child after fork to clear the queue */
+ lock = _SPINLOCK_UNLOCKED_ASSIGN;
+ if (--count == 0)
+ owner = NULL;
+ TAILQ_INIT(&lockers);
}
}