From 070039b1c8ca03061ac4202b16fd7b3e290f5c02 Mon Sep 17 00:00:00 2001 From: Artur Grabowski Date: Wed, 25 Jul 2007 23:11:54 +0000 Subject: Back out the tracking of procs in struct selinfo. There's one serious bug in the code, but as soon as I try to fix it, it seems to trigger some other bugs. Instead of trying to figure out what's going on while everyone suffers, it's better to back out and figure out the bugs outside the tree. --- sys/kern/sys_generic.c | 56 ++++++++++++++++++-------------------------------- 1 file changed, 20 insertions(+), 36 deletions(-) (limited to 'sys/kern/sys_generic.c') diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index a79c121c00c..f68f5251a7d 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sys_generic.c,v 1.56 2007/03/24 16:01:22 art Exp $ */ +/* $OpenBSD: sys_generic.c,v 1.57 2007/07/25 23:11:52 art Exp $ */ /* $NetBSD: sys_generic.c,v 1.24 1996/03/29 00:25:32 cgd Exp $ */ /* @@ -66,8 +66,6 @@ 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. */ @@ -710,7 +708,6 @@ 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) @@ -784,12 +781,17 @@ seltrue(dev_t dev, int events, struct proc *p) void selrecord(struct proc *selector, struct selinfo *sip) { - if (sip->si_selproc == NULL) { - sip->si_selproc = selector; - TAILQ_INSERT_TAIL(&selector->p_selects, sip, si_list); - } else if (sip->si_selproc != selector) { + 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) sip->si_flags |= SI_COLL; - } + else + sip->si_selpid = mypid; } /* @@ -801,42 +803,25 @@ 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); } - - /* - * 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) { + p = pfind(sip->si_selpid); + sip->si_selpid = 0; + if (p != NULL) { + SCHED_LOCK(s); + if (p->p_wchan == (caddr_t)&selwait) { if (p->p_stat == SSLEEP) setrunnable(p); else unsleep(p); - } else { + } else if (p->p_flag & P_SELECT) atomic_clearbits_int(&p->p_flag, P_SELECT); - } - } - 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); + SCHED_UNLOCK(s); } } @@ -947,7 +932,6 @@ 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 -- cgit v1.2.3