/* * Wakeup processes waiting on a socket buffer. * Do asynchronous notification via SIGIO * if the socket buffer has the SB_ASYNC flag set. */ void sowakeup(struct socket *so, struct sockbuf *sb, int code) { int band; KASSERT(solocked(so)); KASSERT(sb->sb_so == so); if (code == POLL_IN) band = POLLIN|POLLRDNORM; else band = POLLOUT|POLLWRNORM; #if 0 /* VADIM */ sb->sb_flags &= ~SB_NOTIFY; selnotify(&sb->sb_sel, band, NOTE_SUBMIT); cv_broadcast(&sb->sb_cv); if (sb->sb_flags & SB_ASYNC) fownsignal(so->so_pgid, SIGIO, code, band, so); #endif if(so->so_upcall2) (*so->so_upcall2)(so, so->so_upcallarg2, band, M_DONTWAIT); if (sb->sb_flags & SB_UPCALL) (*so->so_upcall)(so, so->so_upcallarg, band, M_DONTWAIT); }
static int tun_clone_destroy(struct ifnet *ifp) { struct tun_softc *tp = (void *)ifp; int s, zombie = 0; IF_PURGE(&ifp->if_snd); ifp->if_flags &= ~IFF_RUNNING; s = splnet(); simple_lock(&tun_softc_lock); mutex_enter(&tp->tun_lock); LIST_REMOVE(tp, tun_list); if (tp->tun_flags & TUN_OPEN) { /* Hang on to storage until last close */ zombie = 1; tp->tun_flags &= ~TUN_INITED; LIST_INSERT_HEAD(&tunz_softc_list, tp, tun_list); } simple_unlock(&tun_softc_lock); if (tp->tun_flags & TUN_RWAIT) { tp->tun_flags &= ~TUN_RWAIT; wakeup((void *)tp); } selnotify(&tp->tun_rsel, 0, 0); mutex_exit(&tp->tun_lock); splx(s); if (tp->tun_flags & TUN_ASYNC && tp->tun_pgid) fownsignal(tp->tun_pgid, SIGIO, POLL_HUP, 0, NULL); bpf_detach(ifp); if_detach(ifp); if (!zombie) { seldestroy(&tp->tun_rsel); seldestroy(&tp->tun_wsel); softint_disestablish(tp->tun_osih); softint_disestablish(tp->tun_isih); mutex_destroy(&tp->tun_lock); free(tp, M_DEVBUF); } return (0); }
static void tap_softintr(void *cookie) { struct tap_softc *sc; struct ifnet *ifp; int a, b; sc = cookie; if (sc->sc_flags & TAP_ASYNCIO) { ifp = &sc->sc_ec.ec_if; if (ifp->if_flags & IFF_RUNNING) { a = POLL_IN; b = POLLIN|POLLRDNORM; } else { a = POLL_HUP; b = 0; } fownsignal(sc->sc_pgid, SIGIO, a, b, NULL); } }