summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2007-03-24 16:01:23 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2007-03-24 16:01:23 +0000
commitb85e9ba20c14a428d67fc578018fd8a539c89f7b (patch)
treeb40dafa9a5122b8fb1353291f58602e22cbd30a1 /sys
parentbb009c4c0bea668c35c72a9601e752153bc19d8a (diff)
Kill the horrible hack of storing the pid in struct selinfo.
Instead, keep the proc pointer in it and put the selinfo on a list in struct proc in selrecord. Then clean up the list when leaving sys_select and sys_poll. miod@ ok, testing by many, including Bobs spamd boxes.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/bktr/bktr_core.c10
-rw-r--r--sys/dev/wscons/wsdisplay.c4
-rw-r--r--sys/kern/init_main.c4
-rw-r--r--sys/kern/kern_fork.c4
-rw-r--r--sys/kern/sys_generic.c56
-rw-r--r--sys/net/bpf.c4
-rw-r--r--sys/sys/proc.h4
-rw-r--r--sys/sys/selinfo.h9
8 files changed, 55 insertions, 40 deletions
diff --git a/sys/dev/pci/bktr/bktr_core.c b/sys/dev/pci/bktr/bktr_core.c
index c6eaa5bf9dc..23c4f680ebf 100644
--- a/sys/dev/pci/bktr/bktr_core.c
+++ b/sys/dev/pci/bktr/bktr_core.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bktr_core.c,v 1.21 2007/02/11 20:29:22 miod Exp $ */
+/* $OpenBSD: bktr_core.c,v 1.22 2007/03/24 16:01:21 art Exp $ */
/* $FreeBSD: src/sys/dev/bktr/bktr_core.c,v 1.114 2000/10/31 13:09:56 roger Exp $ */
/*
@@ -810,13 +810,7 @@ common_bktr_intr( void *arg )
}
/* If someone has a select() on /dev/vbi, inform them */
-#ifndef __OpenBSD__
- if (bktr->vbi_select.si_pid) {
-#else
- if (bktr->vbi_select.si_selpid) {
-#endif
- selwakeup(&bktr->vbi_select);
- }
+ selwakeup(&bktr->vbi_select);
}
diff --git a/sys/dev/wscons/wsdisplay.c b/sys/dev/wscons/wsdisplay.c
index 8b78a22f0a0..68a3e0fc352 100644
--- a/sys/dev/wscons/wsdisplay.c
+++ b/sys/dev/wscons/wsdisplay.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wsdisplay.c,v 1.77 2007/03/07 06:23:04 miod Exp $ */
+/* $OpenBSD: wsdisplay.c,v 1.78 2007/03/24 16:01:22 art Exp $ */
/* $NetBSD: wsdisplay.c,v 1.82 2005/02/27 00:27:52 perry Exp $ */
/*
@@ -1402,7 +1402,7 @@ wsdisplaystart(struct tty *tp)
splx(s);
return;
}
- if (tp->t_outq.c_cc == 0 && tp->t_wsel.si_selpid == 0)
+ if (tp->t_outq.c_cc == 0 && tp->t_wsel.si_selproc == NULL)
goto low;
if ((scr = sc->sc_scr[WSDISPLAYSCREEN(tp->t_dev)]) == NULL) {
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index e41810455d8..291aa2e5a6a 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: init_main.c,v 1.136 2007/03/19 14:33:28 dlg Exp $ */
+/* $OpenBSD: init_main.c,v 1.137 2007/03/24 16:01:22 art Exp $ */
/* $NetBSD: init_main.c,v 1.84.4.1 1996/06/02 09:08:06 mrg Exp $ */
/*
@@ -296,6 +296,8 @@ main(void *framep)
/* Create the file descriptor table. */
p->p_fd = fdinit(NULL);
+ TAILQ_INIT(&p->p_selects);
+
/* Create the limits structures. */
p->p_limit = &limit0;
for (i = 0; i < sizeof(p->p_rlimit)/sizeof(p->p_rlimit[0]); i++)
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index d19608d9cbc..da8d0df31c4 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_fork.c,v 1.87 2007/03/15 10:22:30 art Exp $ */
+/* $OpenBSD: kern_fork.c,v 1.88 2007/03/24 16:01:22 art Exp $ */
/* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */
/*
@@ -246,6 +246,8 @@ fork1(struct proc *p1, int exitsig, int flags, void *stack, size_t stacksize,
p2->p_cred->p_refcnt = 1;
crhold(p1->p_ucred);
+ TAILQ_INIT(&p2->p_selects);
+
/* bump references to the text vnode (for procfs) */
p2->p_textvp = p1->p_textvp;
if (p2->p_textvp)
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
index 31cbafefff7..a79c121c00c 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sys_generic.c,v 1.55 2007/03/15 10:22:30 art Exp $ */
+/* $OpenBSD: sys_generic.c,v 1.56 2007/03/24 16:01:22 art Exp $ */
/* $NetBSD: sys_generic.c,v 1.24 1996/03/29 00:25:32 cgd Exp $ */
/*
@@ -66,6 +66,8 @@ int selscan(struct proc *, fd_set *, fd_set *, int, int, register_t *);
int seltrue(dev_t, int, struct proc *);
void pollscan(struct proc *, struct pollfd *, u_int, register_t *);
+void sel_clean_proclist(struct proc *);
+
/*
* Read system call.
*/
@@ -708,6 +710,7 @@ retry:
if (error == 0)
goto retry;
done:
+ sel_clean_proclist(p);
atomic_clearbits_int(&p->p_flag, P_SELECT);
/* select is not restarted after signals... */
if (error == ERESTART)
@@ -781,17 +784,12 @@ seltrue(dev_t dev, int events, struct proc *p)
void
selrecord(struct proc *selector, struct selinfo *sip)
{
- struct proc *p;
- pid_t mypid;
-
- mypid = selector->p_pid;
- if (sip->si_selpid == mypid)
- return;
- if (sip->si_selpid && (p = pfind(sip->si_selpid)) &&
- p->p_wchan == (caddr_t)&selwait)
+ if (sip->si_selproc == NULL) {
+ sip->si_selproc = selector;
+ TAILQ_INSERT_TAIL(&selector->p_selects, sip, si_list);
+ } else if (sip->si_selproc != selector) {
sip->si_flags |= SI_COLL;
- else
- sip->si_selpid = mypid;
+ }
}
/*
@@ -803,25 +801,42 @@ selwakeup(struct selinfo *sip)
struct proc *p;
int s;
- if (sip->si_selpid == 0)
- return;
if (sip->si_flags & SI_COLL) {
nselcoll++;
sip->si_flags &= ~SI_COLL;
wakeup(&selwait);
}
- p = pfind(sip->si_selpid);
- sip->si_selpid = 0;
- if (p != NULL) {
- SCHED_LOCK(s);
- if (p->p_wchan == (caddr_t)&selwait) {
+
+ /*
+ * We check the process once before locking.
+ * Then we wake the process and clean up its
+ * selects list.
+ */
+ if (sip->si_selproc == NULL)
+ return;
+
+ SCHED_LOCK(s);
+ if ((p = sip->si_selproc) != NULL) {
+ if (p->p_wchan != NULL) {
if (p->p_stat == SSLEEP)
setrunnable(p);
else
unsleep(p);
- } else if (p->p_flag & P_SELECT)
+ } else {
atomic_clearbits_int(&p->p_flag, P_SELECT);
- SCHED_UNLOCK(s);
+ }
+ }
+ SCHED_UNLOCK(s);
+}
+
+void
+sel_clean_proclist(struct proc *p)
+{
+ struct selinfo *sip;
+
+ while ((sip = TAILQ_FIRST(&p->p_selects)) != NULL) {
+ sip->si_selproc = NULL;
+ TAILQ_REMOVE(&p->p_selects, sip, si_list);
}
}
@@ -932,6 +947,7 @@ retry:
goto retry;
done:
+ sel_clean_proclist(p);
atomic_clearbits_int(&p->p_flag, P_SELECT);
/*
* NOTE: poll(2) is not restarted after a signal and EWOULDBLOCK is
diff --git a/sys/net/bpf.c b/sys/net/bpf.c
index 4c18bec6b24..0b3e79cd67e 100644
--- a/sys/net/bpf.c
+++ b/sys/net/bpf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bpf.c,v 1.64 2007/03/04 23:36:34 canacar Exp $ */
+/* $OpenBSD: bpf.c,v 1.65 2007/03/24 16:01:22 art Exp $ */
/* $NetBSD: bpf.c,v 1.33 1997/02/21 23:59:35 thorpej Exp $ */
/*
@@ -496,8 +496,6 @@ bpf_wakeup(struct bpf_d *d)
d->bd_siguid, d->bd_sigeuid);
selwakeup(&d->bd_sel);
- /* XXX */
- d->bd_sel.si_selpid = 0;
KNOTE(&d->bd_sel.si_note, 0);
}
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 7fb12a40c21..f956d2be875 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: proc.h,v 1.91 2007/03/21 09:09:52 art Exp $ */
+/* $OpenBSD: proc.h,v 1.92 2007/03/24 16:01:22 art Exp $ */
/* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */
/*-
@@ -211,6 +211,8 @@ struct proc {
sigset_t p_sigdivert; /* Signals to be diverted to thread. */
+ TAILQ_HEAD(,selinfo) p_selects; /* selinfos we're selecting on */
+
/* End area that is zeroed on creation. */
#define p_endzero p_startcopy
diff --git a/sys/sys/selinfo.h b/sys/sys/selinfo.h
index 497c2da9d19..535b48deb42 100644
--- a/sys/sys/selinfo.h
+++ b/sys/sys/selinfo.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: selinfo.h,v 1.1 2005/11/21 18:16:46 millert Exp $ */
+/* $OpenBSD: selinfo.h,v 1.2 2007/03/24 16:01:22 art Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -41,9 +41,10 @@
* notified when I/O becomes possible.
*/
struct selinfo {
- pid_t si_selpid; /* process to be notified */
- struct klist si_note; /* kernel note list */
- short si_flags; /* see below */
+ struct proc *si_selproc;
+ TAILQ_ENTRY(selinfo) si_list; /* list of selinfo for a process */
+ struct klist si_note; /* kernel note list */
+ short si_flags; /* see below */
};
#define SI_COLL 0x0001 /* collision occurred */