summaryrefslogtreecommitdiff
path: root/sys/net/if_tun.c
diff options
context:
space:
mode:
authorTed Unangst <tedu@cvs.openbsd.org>2004-01-12 04:48:26 +0000
committerTed Unangst <tedu@cvs.openbsd.org>2004-01-12 04:48:26 +0000
commit9e2c9c2926e1ec0c28762795978e7023947823bb (patch)
tree853c9cc3e2449776639220f4db8893b20d63eabd /sys/net/if_tun.c
parentde9dd8527c35d730c294c117984ff69e78290635 (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.c25
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;