diff options
author | Ted Unangst <tedu@cvs.openbsd.org> | 2004-01-12 04:48:26 +0000 |
---|---|---|
committer | Ted Unangst <tedu@cvs.openbsd.org> | 2004-01-12 04:48:26 +0000 |
commit | 9e2c9c2926e1ec0c28762795978e7023947823bb (patch) | |
tree | 853c9cc3e2449776639220f4db8893b20d63eabd /sys/net/if_tun.c | |
parent | de9dd8527c35d730c294c117984ff69e78290635 (diff) |
use klist_invalidate to permit destroy while kqueued. ok mpf@
Diffstat (limited to 'sys/net/if_tun.c')
-rw-r--r-- | sys/net/if_tun.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/sys/net/if_tun.c b/sys/net/if_tun.c index 9b497b3c9b9..91e1d4e3723 100644 --- a/sys/net/if_tun.c +++ b/sys/net/if_tun.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_tun.c,v 1.56 2004/01/05 23:53:24 mpf Exp $ */ +/* $OpenBSD: if_tun.c,v 1.57 2004/01/12 04:48:25 tedu Exp $ */ /* $NetBSD: if_tun.c,v 1.24 1996/05/07 02:40:48 thorpej Exp $ */ /* @@ -221,9 +221,10 @@ tun_clone_destroy(ifp) struct tun_softc *tp = ifp->if_softc; int s; - if (!SLIST_EMPTY(&tp->tun_rsel.si_note) || - !SLIST_EMPTY(&tp->tun_wsel.si_note)) - return(EBUSY); + s = splhigh(); + klist_invalidate(&tp->tun_rsel.si_note); + klist_invalidate(&tp->tun_wsel.si_note); + splx(s); s = splimp(); LIST_REMOVE(tp, tun_list); @@ -912,7 +913,8 @@ filt_tunrdetach(struct knote *kn) struct tun_softc *tp = (struct tun_softc *)kn->kn_hook; s = splhigh(); - SLIST_REMOVE(&tp->tun_rsel.si_note, kn, knote, kn_selnext); + if (!(kn->kn_status & KN_DETACHED)) + SLIST_REMOVE(&tp->tun_rsel.si_note, kn, knote, kn_selnext); splx(s); } @@ -924,6 +926,11 @@ filt_tunread(struct knote *kn, long hint) struct ifnet *ifp; struct mbuf *m; + if (kn->kn_status & KN_DETACHED) { + kn->kn_data = 0; + return 1; + } + tp = (struct tun_softc *)kn->kn_hook; ifp = &tp->tun_if; @@ -949,7 +956,8 @@ filt_tunwdetach(struct knote *kn) struct tun_softc *tp = (struct tun_softc *)kn->kn_hook; s = splhigh(); - SLIST_REMOVE(&tp->tun_wsel.si_note, kn, knote, kn_selnext); + if (!(kn->kn_status & KN_DETACHED)) + SLIST_REMOVE(&tp->tun_wsel.si_note, kn, knote, kn_selnext); splx(s); } @@ -959,6 +967,11 @@ filt_tunwrite(struct knote *kn, long hint) struct tun_softc *tp; struct ifnet *ifp; + if (kn->kn_status & KN_DETACHED) { + kn->kn_data = 0; + return 1; + } + tp = (struct tun_softc *)kn->kn_hook; ifp = &tp->tun_if; |