Redo the sigio locking.

Turn the sigio sx into a mutex.

Sigio lock is really only needed to protect interrupts from dereferencing
the sigio pointer in an object when the sigio itself is being destroyed.

In order to do this in the most unintrusive manner change pgsigio's
sigio * argument into a **, that way we can lock internally to the
function.
This commit is contained in:
Alfred Perlstein 2002-05-01 20:44:46 +00:00
parent 3498b5ed09
commit f132072368
19 changed files with 42 additions and 115 deletions

View File

@ -63,6 +63,7 @@
#include <sys/event.h>
#include <sys/sx.h>
#include <sys/socketvar.h>
#include <sys/signalvar.h>
#include <machine/limits.h>
@ -113,7 +114,7 @@ struct filelist filehead; /* head of list of open files */
int nfiles; /* actual number of open files */
extern int cmask;
struct sx filelist_lock; /* sx to protect filelist */
struct sx sigio_lock; /* sx to protect pointers to sigio */
struct mtx sigio_lock; /* mtx to protect pointers to sigio */
/*
* System calls on descriptors.
@ -536,14 +537,14 @@ void
funsetown(sigio)
struct sigio *sigio;
{
int s;
if (sigio == NULL)
SIGIO_LOCK();
if (sigio == NULL) {
SIGIO_UNLOCK();
return;
s = splhigh();
}
*(sigio->sio_myref) = NULL;
splx(s);
SIGIO_UNLOCK();
if ((sigio)->sio_pgid < 0) {
struct pgrp *pg = (sigio)->sio_pgrp;
PGRP_LOCK(pg);
@ -566,7 +567,6 @@ void
funsetownlst(sigiolst)
struct sigiolst *sigiolst;
{
int s;
struct sigio *sigio;
struct proc *p;
struct pgrp *pg;
@ -591,9 +591,9 @@ funsetownlst(sigiolst)
}
while ((sigio = SLIST_FIRST(sigiolst)) != NULL) {
s = splhigh();
SIGIO_LOCK();
*(sigio->sio_myref) = NULL;
splx(s);
SIGIO_UNLOCK();
if (pg != NULL) {
KASSERT(sigio->sio_pgid < 0, ("Proc sigio in pgrp sigio list"));
KASSERT(sigio->sio_pgrp == pg, ("Bogus pgrp in sigio list"));
@ -632,7 +632,7 @@ fsetown(pgid, sigiop)
struct proc *proc;
struct pgrp *pgrp;
struct sigio *sigio;
int s, ret;
int ret;
if (pgid == 0) {
funsetown(*sigiop);
@ -706,9 +706,9 @@ fsetown(pgid, sigiop)
PGRP_UNLOCK(pgrp);
}
sx_sunlock(&proctree_lock);
s = splhigh();
SIGIO_LOCK();
*sigiop = sigio;
splx(s);
SIGIO_UNLOCK();
return (0);
fail:
@ -2187,5 +2187,5 @@ filelistinit(dummy)
NULL, NULL, UMA_ALIGN_PTR, 0);
sx_init(&filelist_lock, "filelist lock");
sx_init(&sigio_lock, "sigio lock");
mtx_init(&sigio_lock, "sigio lock", NULL, MTX_DEF);
}

View File

@ -2087,13 +2087,18 @@ nosys(td, args)
* stored credentials rather than those of the current process.
*/
void
pgsigio(sigio, sig, checkctty)
struct sigio *sigio;
pgsigio(sigiop, sig, checkctty)
struct sigio **sigiop;
int sig, checkctty;
{
if (sigio == NULL)
return;
struct sigio *sigio;
SIGIO_LOCK();
sigio = *sigiop;
if (sigio == NULL) {
SIGIO_UNLOCK();
return;
}
if (sigio->sio_pgid > 0) {
PROC_LOCK(sigio->sio_proc);
if (CANSIGIO(sigio->sio_ucred, sigio->sio_proc->p_ucred))
@ -2112,6 +2117,7 @@ pgsigio(sigio, sig, checkctty)
}
PGRP_UNLOCK(sigio->sio_pgrp);
}
SIGIO_UNLOCK();
}
static int

View File

@ -198,7 +198,7 @@ logtimeout(void *arg)
msgbuftrigger = 0;
selwakeup(&logsoftc.sc_selp);
if ((logsoftc.sc_state & LOG_ASYNC) && logsoftc.sc_sigio != NULL)
pgsigio(logsoftc.sc_sigio, SIGIO, 0);
pgsigio(&logsoftc.sc_sigio, SIGIO, 0);
if (logsoftc.sc_state & LOG_RDWAIT) {
wakeup((caddr_t)msgbufp);
logsoftc.sc_state &= ~LOG_RDWAIT;

View File

@ -429,7 +429,7 @@ pipeselwakeup(cpipe)
selwakeup(&cpipe->pipe_sel);
}
if ((cpipe->pipe_state & PIPE_ASYNC) && cpipe->pipe_sigio)
pgsigio(cpipe->pipe_sigio, SIGIO, 0);
pgsigio(&cpipe->pipe_sigio, SIGIO, 0);
KNOTE(&cpipe->pipe_sel.si_note, 0);
}

View File

@ -2289,7 +2289,7 @@ ttwakeup(tp)
if (SEL_WAITING(&tp->t_rsel))
selwakeup(&tp->t_rsel);
if (ISSET(tp->t_state, TS_ASYNC) && tp->t_sigio != NULL)
pgsigio(tp->t_sigio, SIGIO, (tp->t_session != NULL));
pgsigio(&tp->t_sigio, SIGIO, (tp->t_session != NULL));
wakeup(TSA_HUP_OR_INPUT(tp));
KNOTE(&tp->t_rsel.si_note, 0);
}
@ -2305,7 +2305,7 @@ ttwwakeup(tp)
if (SEL_WAITING(&tp->t_wsel) && tp->t_outq.c_cc <= tp->t_olowat)
selwakeup(&tp->t_wsel);
if (ISSET(tp->t_state, TS_ASYNC) && tp->t_sigio != NULL)
pgsigio(tp->t_sigio, SIGIO, (tp->t_session != NULL));
pgsigio(&tp->t_sigio, SIGIO, (tp->t_session != NULL));
if (ISSET(tp->t_state, TS_BUSY | TS_SO_OCOMPLETE) ==
TS_SO_OCOMPLETE && tp->t_outq.c_cc == 0) {
CLR(tp->t_state, TS_SO_OCOMPLETE);

View File

@ -52,7 +52,6 @@
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/stat.h>
#include <sys/sx.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
@ -113,7 +112,6 @@ soisconnected_locked(so)
{
struct socket *head = so->so_head;
SIGIO_ASSERT(SX_SLOCKED); /* XXX */
so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING|SS_ISCONFIRMING);
so->so_state |= SS_ISCONNECTED;
if (head && (so->so_state & SS_INCOMP)) {
@ -122,9 +120,7 @@ soisconnected_locked(so)
so->so_upcallarg = head->so_accf->so_accept_filter_arg;
so->so_rcv.sb_flags |= SB_UPCALL;
so->so_options &= ~SO_ACCEPTFILTER;
SIGIO_SUNLOCK(); /* XXX */
so->so_upcall(so, so->so_upcallarg, 0);
SIGIO_SLOCK();
return;
}
TAILQ_REMOVE(&head->so_incomp, so, so_list);
@ -147,7 +143,6 @@ soisconnected(so)
{
struct socket *head = so->so_head;
SIGIO_SLOCK();
so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING|SS_ISCONFIRMING);
so->so_state |= SS_ISCONNECTED;
if (head && (so->so_state & SS_INCOMP)) {
@ -156,7 +151,6 @@ soisconnected(so)
so->so_upcallarg = head->so_accf->so_accept_filter_arg;
so->so_rcv.sb_flags |= SB_UPCALL;
so->so_options &= ~SO_ACCEPTFILTER;
SIGIO_SUNLOCK();
so->so_upcall(so, so->so_upcallarg, 0);
return;
}
@ -173,7 +167,6 @@ soisconnected(so)
sorwakeup_locked(so);
sowwakeup_locked(so);
}
SIGIO_SUNLOCK();
}
void
@ -181,13 +174,11 @@ soisdisconnecting(so)
register struct socket *so;
{
SIGIO_SLOCK();
so->so_state &= ~SS_ISCONNECTING;
so->so_state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE);
wakeup((caddr_t)&so->so_timeo);
sowwakeup_locked(so);
sorwakeup_locked(so);
SIGIO_SUNLOCK();
}
void
@ -195,7 +186,6 @@ soisdisconnected_locked(so)
register struct socket *so;
{
SIGIO_ASSERT(SX_LOCKED);
so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE|SS_ISDISCONNECTED);
wakeup((caddr_t)&so->so_timeo);
@ -208,9 +198,7 @@ soisdisconnected(so)
register struct socket *so;
{
SIGIO_SLOCK();
soisdisconnected_locked(so);
SIGIO_SUNLOCK();
}
/*
@ -266,9 +254,7 @@ sonewconn(head, connstatus)
head->so_incqlen++;
}
if (connstatus) {
SIGIO_SLOCK();
sorwakeup_locked(head);
SIGIO_SUNLOCK();
wakeup((caddr_t)&head->so_timeo);
so->so_state |= connstatus;
}
@ -290,10 +276,8 @@ socantsendmore(so)
struct socket *so;
{
SIGIO_SLOCK();
so->so_state |= SS_CANTSENDMORE;
sowwakeup_locked(so);
SIGIO_SUNLOCK();
}
void
@ -301,10 +285,8 @@ socantrcvmore(so)
struct socket *so;
{
SIGIO_SLOCK();
so->so_state |= SS_CANTRCVMORE;
sorwakeup_locked(so);
SIGIO_SUNLOCK();
}
/*
@ -353,7 +335,6 @@ sowakeup(so, sb)
register struct socket *so;
register struct sockbuf *sb;
{
SIGIO_ASSERT(SX_LOCKED);
selwakeup(&sb->sb_sel);
sb->sb_flags &= ~SB_SEL;
@ -362,7 +343,7 @@ sowakeup(so, sb)
wakeup((caddr_t)&sb->sb_cc);
}
if ((so->so_state & SS_ASYNC) && so->so_sigio != NULL)
pgsigio(so->so_sigio, SIGIO, 0);
pgsigio(&so->so_sigio, SIGIO, 0);
if (sb->sb_flags & SB_UPCALL)
(*so->so_upcall)(so, so->so_upcallarg, M_DONTWAIT);
if (sb->sb_flags & SB_AIO)

View File

@ -1527,7 +1527,7 @@ sohasoutofband(so)
register struct socket *so;
{
if (so->so_sigio != NULL)
pgsigio(so->so_sigio, SIGURG, 0);
pgsigio(&so->so_sigio, SIGURG, 0);
selwakeup(&so->so_rcv.sb_sel);
}

View File

@ -52,7 +52,6 @@
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/stat.h>
#include <sys/sx.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
@ -113,7 +112,6 @@ soisconnected_locked(so)
{
struct socket *head = so->so_head;
SIGIO_ASSERT(SX_SLOCKED); /* XXX */
so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING|SS_ISCONFIRMING);
so->so_state |= SS_ISCONNECTED;
if (head && (so->so_state & SS_INCOMP)) {
@ -122,9 +120,7 @@ soisconnected_locked(so)
so->so_upcallarg = head->so_accf->so_accept_filter_arg;
so->so_rcv.sb_flags |= SB_UPCALL;
so->so_options &= ~SO_ACCEPTFILTER;
SIGIO_SUNLOCK(); /* XXX */
so->so_upcall(so, so->so_upcallarg, 0);
SIGIO_SLOCK();
return;
}
TAILQ_REMOVE(&head->so_incomp, so, so_list);
@ -147,7 +143,6 @@ soisconnected(so)
{
struct socket *head = so->so_head;
SIGIO_SLOCK();
so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING|SS_ISCONFIRMING);
so->so_state |= SS_ISCONNECTED;
if (head && (so->so_state & SS_INCOMP)) {
@ -156,7 +151,6 @@ soisconnected(so)
so->so_upcallarg = head->so_accf->so_accept_filter_arg;
so->so_rcv.sb_flags |= SB_UPCALL;
so->so_options &= ~SO_ACCEPTFILTER;
SIGIO_SUNLOCK();
so->so_upcall(so, so->so_upcallarg, 0);
return;
}
@ -173,7 +167,6 @@ soisconnected(so)
sorwakeup_locked(so);
sowwakeup_locked(so);
}
SIGIO_SUNLOCK();
}
void
@ -181,13 +174,11 @@ soisdisconnecting(so)
register struct socket *so;
{
SIGIO_SLOCK();
so->so_state &= ~SS_ISCONNECTING;
so->so_state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE);
wakeup((caddr_t)&so->so_timeo);
sowwakeup_locked(so);
sorwakeup_locked(so);
SIGIO_SUNLOCK();
}
void
@ -195,7 +186,6 @@ soisdisconnected_locked(so)
register struct socket *so;
{
SIGIO_ASSERT(SX_LOCKED);
so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE|SS_ISDISCONNECTED);
wakeup((caddr_t)&so->so_timeo);
@ -208,9 +198,7 @@ soisdisconnected(so)
register struct socket *so;
{
SIGIO_SLOCK();
soisdisconnected_locked(so);
SIGIO_SUNLOCK();
}
/*
@ -266,9 +254,7 @@ sonewconn(head, connstatus)
head->so_incqlen++;
}
if (connstatus) {
SIGIO_SLOCK();
sorwakeup_locked(head);
SIGIO_SUNLOCK();
wakeup((caddr_t)&head->so_timeo);
so->so_state |= connstatus;
}
@ -290,10 +276,8 @@ socantsendmore(so)
struct socket *so;
{
SIGIO_SLOCK();
so->so_state |= SS_CANTSENDMORE;
sowwakeup_locked(so);
SIGIO_SUNLOCK();
}
void
@ -301,10 +285,8 @@ socantrcvmore(so)
struct socket *so;
{
SIGIO_SLOCK();
so->so_state |= SS_CANTRCVMORE;
sorwakeup_locked(so);
SIGIO_SUNLOCK();
}
/*
@ -353,7 +335,6 @@ sowakeup(so, sb)
register struct socket *so;
register struct sockbuf *sb;
{
SIGIO_ASSERT(SX_LOCKED);
selwakeup(&sb->sb_sel);
sb->sb_flags &= ~SB_SEL;
@ -362,7 +343,7 @@ sowakeup(so, sb)
wakeup((caddr_t)&sb->sb_cc);
}
if ((so->so_state & SS_ASYNC) && so->so_sigio != NULL)
pgsigio(so->so_sigio, SIGIO, 0);
pgsigio(&so->so_sigio, SIGIO, 0);
if (sb->sb_flags & SB_UPCALL)
(*so->so_upcall)(so, so->so_upcallarg, M_DONTWAIT);
if (sb->sb_flags & SB_AIO)

View File

@ -511,7 +511,7 @@ bpf_wakeup(d)
}
wakeup((caddr_t)d);
if (d->bd_async && d->bd_sig && d->bd_sigio)
pgsigio(d->bd_sigio, d->bd_sig, 0);
pgsigio(&d->bd_sigio, d->bd_sig, 0);
selwakeup(&d->bd_sel);
}

View File

@ -626,7 +626,7 @@ tapifstart(ifp)
}
if ((tp->tap_flags & TAP_ASYNC) && (tp->tap_sigio != NULL))
pgsigio(tp->tap_sigio, SIGIO, 0);
pgsigio(&tp->tap_sigio, SIGIO, 0);
selwakeup(&tp->tap_rsel);
ifp->if_opackets ++; /* obytes are counted in ether_output */

View File

@ -223,7 +223,7 @@ tunstart(struct ifnet *ifp)
wakeup((caddr_t)tp);
}
if (tp->tun_flags & TUN_ASYNC && tp->tun_sigio)
pgsigio(tp->tun_sigio, SIGIO, 0);
pgsigio(&tp->tun_sigio, SIGIO, 0);
selwakeup(&tp->tun_rsel);
}

View File

@ -39,7 +39,6 @@
#include <sys/domain.h>
#include <sys/kernel.h>
#include <sys/jail.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/proc.h>
@ -47,7 +46,6 @@
#include <sys/signalvar.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/sx.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
@ -149,10 +147,8 @@ rts_attach(struct socket *so, int proto, struct thread *td)
}
rp->rcb_faddr = &route_src;
route_cb.any_count++;
SIGIO_SLOCK();
soisconnected_locked(so);
so->so_options |= SO_USELOOPBACK;
SIGIO_SUNLOCK();
splx(s);
return 0;
}

View File

@ -30,11 +30,9 @@
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/sysctl.h>
#include <sys/signalvar.h>
#include <sys/socketvar.h>
#include <sys/sx.h>
/* accept filter that holds a socket until data arrives */
@ -59,15 +57,11 @@ static void
sohasdata(struct socket *so, void *arg, int waitflag)
{
SIGIO_SLOCK();
if (!soreadable(so)) {
SIGIO_SUNLOCK();
if (!soreadable(so))
return;
}
so->so_upcall = NULL;
so->so_rcv.sb_flags &= ~SB_UPCALL;
soisconnected_locked(so);
SIGIO_SUNLOCK();
return;
}

View File

@ -31,12 +31,10 @@
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mbuf.h>
#include <sys/signalvar.h>
#include <sys/sysctl.h>
#include <sys/socketvar.h>
#include <sys/sx.h>
/* check for GET/HEAD */
static void sohashttpget(struct socket *so, void *arg, int waitflag);
@ -203,11 +201,9 @@ sohashttpget(struct socket *so, void *arg, int waitflag)
fallout:
DPRINT("fallout");
SIGIO_SLOCK();
so->so_upcall = NULL;
so->so_rcv.sb_flags &= ~SB_UPCALL;
soisconnected_locked(so);
SIGIO_SUNLOCK();
return;
}
@ -287,11 +283,9 @@ soparsehttpvers(struct socket *so, void *arg, int waitflag)
fallout:
DPRINT("fallout");
SIGIO_SLOCK();
so->so_upcall = NULL;
so->so_rcv.sb_flags &= ~SB_UPCALL;
soisconnected_locked(so);
SIGIO_SUNLOCK();
return;
}
@ -359,10 +353,8 @@ soishttpconnected(struct socket *so, void *arg, int waitflag)
return;
gotit:
SIGIO_SLOCK();
so->so_upcall = NULL;
so->so_rcv.sb_flags &= ~SB_UPCALL;
soisconnected_locked(so);
SIGIO_SUNLOCK();
return;
}

View File

@ -42,7 +42,6 @@
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/proc.h> /* for proc0 declaration */
@ -50,7 +49,6 @@
#include <sys/signalvar.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/sx.h>
#include <sys/sysctl.h>
#include <sys/syslog.h>
#include <sys/systm.h>
@ -1845,14 +1843,10 @@ tcp_input(m, off0)
* specification, but if we don't get a FIN
* we'll hang forever.
*/
SIGIO_SLOCK();
if (so->so_state & SS_CANTRCVMORE) {
soisdisconnected_locked(so);
SIGIO_SUNLOCK();
callout_reset(tp->tt_2msl, tcp_maxidle,
tcp_timer_2msl, tp);
} else {
SIGIO_SUNLOCK();
}
tp->t_state = TCPS_FIN_WAIT_2;
}

View File

@ -42,7 +42,6 @@
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/proc.h> /* for proc0 declaration */
@ -50,7 +49,6 @@
#include <sys/signalvar.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/sx.h>
#include <sys/sysctl.h>
#include <sys/syslog.h>
#include <sys/systm.h>
@ -1845,14 +1843,10 @@ tcp_input(m, off0)
* specification, but if we don't get a FIN
* we'll hang forever.
*/
SIGIO_SLOCK();
if (so->so_state & SS_CANTRCVMORE) {
soisdisconnected_locked(so);
SIGIO_SUNLOCK();
callout_reset(tp->tt_2msl, tcp_maxidle,
tcp_timer_2msl, tp);
} else {
SIGIO_SUNLOCK();
}
tp->t_state = TCPS_FIN_WAIT_2;
}

View File

@ -39,15 +39,12 @@
#include <sys/domain.h>
#include <sys/errno.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/mutex.h>
#include <sys/protosw.h>
#include <sys/signalvar.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/sx.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
@ -430,10 +427,8 @@ key_attach(struct socket *so, int proto, struct thread *td)
key_cb.any_count++;
kp->kp_raw.rcb_laddr = &key_src;
kp->kp_raw.rcb_faddr = &key_dst;
SIGIO_SLOCK();
soisconnected_locked(so);
so->so_options |= SO_USELOOPBACK;
SIGIO_SUNLOCK();
splx(s);
return 0;

View File

@ -216,20 +216,20 @@ struct pgrp;
struct thread;
struct proc;
struct sigio;
struct sx;
struct mtx;
extern int sugid_coredump; /* Sysctl variable kern.sugid_coredump */
extern struct sx sigio_lock;
extern struct mtx sigio_lock;
/*
* Lock the pointers for a sigio object in the underlying objects of
* a file descriptor.
*/
#define SIGIO_SLOCK() sx_slock(&sigio_lock)
#define SIGIO_XLOCK() sx_xlock(&sigio_lock)
#define SIGIO_SUNLOCK() sx_sunlock(&sigio_lock)
#define SIGIO_XUNLOCK() sx_xunlock(&sigio_lock)
#define SIGIO_ASSERT(what) sx_assert(&sigio_lock, what)
#define SIGIO_LOCK() mtx_lock(&sigio_lock)
#define SIGIO_TRYLOCK() mtx_trylock(&sigio_lock)
#define SIGIO_UNLOCK() mtx_unlock(&sigio_lock)
#define SIGIO_LOCKED() mtx_owned(&sigio_lock)
#define SIGIO_ASSERT(type) mtx_assert(&sigio_lock, type)
/*
* Machine-independent functions:
@ -239,7 +239,7 @@ void execsigs(struct proc *p);
void gsignal(int pgid, int sig);
int issignal(struct proc *p);
void killproc(struct proc *p, char *why);
void pgsigio(struct sigio *, int signum, int checkctty);
void pgsigio(struct sigio **, int signum, int checkctty);
void pgsignal(struct pgrp *pgrp, int sig, int checkctty);
void postsig(int sig);
void psignal(struct proc *p, int sig);

View File

@ -283,27 +283,21 @@ struct xsocket {
} while(0)
#define sorwakeup_locked(so) do { \
SIGIO_ASSERT(SX_SLOCKED); /* XXX */ \
if (sb_notify(&(so)->so_rcv)) \
sowakeup((so), &(so)->so_rcv); \
} while (0)
#define sorwakeup(so) do { \
SIGIO_SLOCK(); \
sorwakeup_locked(so); \
SIGIO_SUNLOCK(); \
} while (0)
#define sowwakeup_locked(so) do { \
SIGIO_ASSERT(SX_SLOCKED); /* XXX */ \
if (sb_notify(&(so)->so_snd)) \
sowakeup((so), &(so)->so_snd); \
} while (0)
#define sowwakeup(so) do { \
SIGIO_SLOCK(); \
sowwakeup_locked(so); \
SIGIO_SUNLOCK(); \
} while (0)
#ifdef _KERNEL