Page MenuHomeFreeBSD

D40178.diff
No OneTemporary

D40178.diff

diff --git a/lib/libthr/thread/thr_fork.c b/lib/libthr/thread/thr_fork.c
--- a/lib/libthr/thread/thr_fork.c
+++ b/lib/libthr/thread/thr_fork.c
@@ -78,6 +78,8 @@
__weak_reference(_thr_atfork, _pthread_atfork);
__weak_reference(_thr_atfork, pthread_atfork);
+bool _thr_after_fork = false;
+
int
_thr_atfork(void (*prepare)(void), void (*parent)(void),
void (*child)(void))
@@ -243,7 +245,9 @@
_thr_signal_postfork_child();
if (was_threaded) {
+ _thr_after_fork = true;
_rtld_atfork_post(rtld_locks);
+ _thr_after_fork = false;
__thr_pshared_atfork_post();
}
_thr_setthreaded(0);
diff --git a/lib/libthr/thread/thr_private.h b/lib/libthr/thread/thr_private.h
--- a/lib/libthr/thread/thr_private.h
+++ b/lib/libthr/thread/thr_private.h
@@ -779,6 +779,8 @@
extern int _suspend_all_cycle __hidden;
extern struct pthread *_single_thread __hidden;
+extern bool _thr_after_fork __hidden;
+
/*
* Function prototype definitions.
*/
diff --git a/lib/libthr/thread/thr_rtld.c b/lib/libthr/thread/thr_rtld.c
--- a/lib/libthr/thread/thr_rtld.c
+++ b/lib/libthr/thread/thr_rtld.c
@@ -158,6 +158,17 @@
l = (struct rtld_lock *)lock;
state = l->lock.rw_state;
+ if (__predict_false(_thr_after_fork)) {
+ /*
+ * After fork, only this thread is running, there is no
+ * waiters. Keeping waiters recorded in rwlock breaks
+ * wake logic.
+ */
+ atomic_clear_int(&l->lock.rw_state,
+ URWLOCK_WRITE_WAITERS | URWLOCK_READ_WAITERS);
+ l->lock.rw_blocked_readers = 0;
+ l->lock.rw_blocked_writers = 0;
+ }
if (_thr_rwlock_unlock(&l->lock) == 0) {
if ((state & URWLOCK_WRITE_OWNER) == 0)
curthread->rdlock_count--;

File Metadata

Mime Type
text/plain
Expires
Wed, Nov 20, 12:43 PM (22 h, 18 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14738668
Default Alt Text
D40178.diff (1 KB)

Event Timeline