diff options
author | Philip Guenther <guenther@cvs.openbsd.org> | 2015-05-10 18:33:16 +0000 |
---|---|---|
committer | Philip Guenther <guenther@cvs.openbsd.org> | 2015-05-10 18:33:16 +0000 |
commit | 03c73ce152e59a9d1d99d4b789085554a316ebd7 (patch) | |
tree | 790454b40d8659ab68fbe5368cd6eb4e3e9f0a0a /lib/librthread/rthread.c | |
parent | e3a9fcebd8f4c8984b5b3bb6e016aadddd352a25 (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.c | 15 |
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); } } |