/*
 * 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);
}
Example #3
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);
	}
}