summaryrefslogtreecommitdiffstats
path: root/sys/dev/bktr
diff options
context:
space:
mode:
authoralfred <alfred@FreeBSD.org>2002-03-14 01:32:30 +0000
committeralfred <alfred@FreeBSD.org>2002-03-14 01:32:30 +0000
commit2c16fbdd2a425c2dfbea6385b784ec483e79668c (patch)
tree9215eb853bc269c9e5e98e1cf9aeb77712af947d /sys/dev/bktr
parentebb034597acc5aa4fd82382f85036e5a1e2cb2fa (diff)
downloadFreeBSD-src-2c16fbdd2a425c2dfbea6385b784ec483e79668c.zip
FreeBSD-src-2c16fbdd2a425c2dfbea6385b784ec483e79668c.tar.gz
Fixes to make select/poll mpsafe.
Problem: selwakeup required calling pfind which would cause lock order reversals with the allproc_lock and the per-process filedesc lock. Solution: Instead of recording the pid of the select()'ing process into the selinfo structure, actually record a pointer to the thread. To avoid dereferencing a bad address all the selinfo structures that are in use by a thread are kept in a list hung off the thread (protected by sellock). When a selwakeup occurs the selinfo is removed from that threads list, it is also removed on the way out of select or poll where the thread will traverse its list removing all the selinfos from its own list. Problem: Previously the PROC_LOCK was used to provide the mutual exclusion needed to ensure proper locking, this couldn't work because there was a single condvar used for select and poll and condvars can only be used with a single mutex. Solution: Introduce a global mutex 'sellock' which is used to provide mutual exclusion when recording events to wait on as well as performing notification when an event occurs. Interesting note: schedlock is required to manipulate the per-thread TDF_SELECT flag, however if given its own field it would not need schedlock, also because TDF_SELECT is only manipulated under sellock one doesn't actually use schedlock for syncronization, only to protect against corruption. Proc locks are no longer used in select/poll. Portions contributed by: davidc
Diffstat (limited to 'sys/dev/bktr')
-rw-r--r--sys/dev/bktr/bktr_core.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/sys/dev/bktr/bktr_core.c b/sys/dev/bktr/bktr_core.c
index 528f09a..1a062dd 100644
--- a/sys/dev/bktr/bktr_core.c
+++ b/sys/dev/bktr/bktr_core.c
@@ -809,7 +809,7 @@ common_bktr_intr( void *arg )
}
/* If someone has a select() on /dev/vbi, inform them */
- if (bktr->vbi_select.si_pid) {
+ if (SEL_WAITING(&bktr->vbi_select)) {
selwakeup(&bktr->vbi_select);
}
OpenPOWER on IntegriCloud