Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/sys_socket.c
Show First 20 Lines • Show All 173 Lines • ▼ Show 20 Lines | soo_ioctl(struct file *fp, u_long cmd, void *data, struct ucred *active_cred, | ||||
case FIOASYNC: | case FIOASYNC: | ||||
if (*(int *)data) { | if (*(int *)data) { | ||||
SOCK_LOCK(so); | SOCK_LOCK(so); | ||||
so->so_state |= SS_ASYNC; | so->so_state |= SS_ASYNC; | ||||
if (SOLISTENING(so)) { | if (SOLISTENING(so)) { | ||||
so->sol_sbrcv_flags |= SB_ASYNC; | so->sol_sbrcv_flags |= SB_ASYNC; | ||||
so->sol_sbsnd_flags |= SB_ASYNC; | so->sol_sbsnd_flags |= SB_ASYNC; | ||||
} else { | } else { | ||||
SOCKBUF_LOCK(&so->so_rcv); | SOCK_RECVBUF_LOCK(so); | ||||
so->so_rcv.sb_flags |= SB_ASYNC; | so->so_rcv.sb_flags |= SB_ASYNC; | ||||
SOCKBUF_UNLOCK(&so->so_rcv); | SOCK_RECVBUF_UNLOCK(so); | ||||
SOCKBUF_LOCK(&so->so_snd); | SOCK_SENDBUF_LOCK(so); | ||||
so->so_snd.sb_flags |= SB_ASYNC; | so->so_snd.sb_flags |= SB_ASYNC; | ||||
SOCKBUF_UNLOCK(&so->so_snd); | SOCK_SENDBUF_UNLOCK(so); | ||||
} | } | ||||
SOCK_UNLOCK(so); | SOCK_UNLOCK(so); | ||||
} else { | } else { | ||||
SOCK_LOCK(so); | SOCK_LOCK(so); | ||||
so->so_state &= ~SS_ASYNC; | so->so_state &= ~SS_ASYNC; | ||||
if (SOLISTENING(so)) { | if (SOLISTENING(so)) { | ||||
so->sol_sbrcv_flags &= ~SB_ASYNC; | so->sol_sbrcv_flags &= ~SB_ASYNC; | ||||
so->sol_sbsnd_flags &= ~SB_ASYNC; | so->sol_sbsnd_flags &= ~SB_ASYNC; | ||||
} else { | } else { | ||||
SOCKBUF_LOCK(&so->so_rcv); | SOCK_RECVBUF_LOCK(so); | ||||
so->so_rcv.sb_flags &= ~SB_ASYNC; | so->so_rcv.sb_flags &= ~SB_ASYNC; | ||||
SOCKBUF_UNLOCK(&so->so_rcv); | SOCK_RECVBUF_UNLOCK(so); | ||||
SOCKBUF_LOCK(&so->so_snd); | SOCK_SENDBUF_LOCK(so); | ||||
so->so_snd.sb_flags &= ~SB_ASYNC; | so->so_snd.sb_flags &= ~SB_ASYNC; | ||||
SOCKBUF_UNLOCK(&so->so_snd); | SOCK_SENDBUF_UNLOCK(so); | ||||
} | } | ||||
SOCK_UNLOCK(so); | SOCK_UNLOCK(so); | ||||
} | } | ||||
break; | break; | ||||
case FIONREAD: | case FIONREAD: | ||||
SOCK_RECVBUF_LOCK(so); | SOCK_RECVBUF_LOCK(so); | ||||
if (SOLISTENING(so)) { | if (SOLISTENING(so)) { | ||||
▲ Show 20 Lines • Show All 535 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
struct socket *so; | struct socket *so; | ||||
so = context; | so = context; | ||||
soaio_process_sb(so, &so->so_snd); | soaio_process_sb(so, &so->so_snd); | ||||
} | } | ||||
void | void | ||||
sowakeup_aio(struct socket *so, struct sockbuf *sb) | sowakeup_aio(struct socket *so, sb_which which) | ||||
{ | { | ||||
struct sockbuf *sb = sobuf(so, which); | |||||
SOCKBUF_LOCK_ASSERT(sb); | SOCK_BUF_LOCK_ASSERT(so, which); | ||||
sb->sb_flags &= ~SB_AIO; | sb->sb_flags &= ~SB_AIO; | ||||
if (sb->sb_flags & SB_AIO_RUNNING) | if (sb->sb_flags & SB_AIO_RUNNING) | ||||
return; | return; | ||||
sb->sb_flags |= SB_AIO_RUNNING; | sb->sb_flags |= SB_AIO_RUNNING; | ||||
soref(so); | soref(so); | ||||
soaio_enqueue(&sb->sb_aiotask); | soaio_enqueue(&sb->sb_aiotask); | ||||
} | } | ||||
Show All 28 Lines | else | ||||
aio_cancel(job); | aio_cancel(job); | ||||
} | } | ||||
static int | static int | ||||
soo_aio_queue(struct file *fp, struct kaiocb *job) | soo_aio_queue(struct file *fp, struct kaiocb *job) | ||||
{ | { | ||||
struct socket *so; | struct socket *so; | ||||
struct sockbuf *sb; | struct sockbuf *sb; | ||||
sb_which which; | |||||
int error; | int error; | ||||
so = fp->f_data; | so = fp->f_data; | ||||
error = (*so->so_proto->pr_usrreqs->pru_aio_queue)(so, job); | error = (*so->so_proto->pr_usrreqs->pru_aio_queue)(so, job); | ||||
if (error == 0) | if (error == 0) | ||||
return (0); | return (0); | ||||
/* Lock through the socket, since this may be a listening socket. */ | /* Lock through the socket, since this may be a listening socket. */ | ||||
switch (job->uaiocb.aio_lio_opcode & (LIO_WRITE | LIO_READ)) { | switch (job->uaiocb.aio_lio_opcode & (LIO_WRITE | LIO_READ)) { | ||||
case LIO_READ: | case LIO_READ: | ||||
sb = &so->so_rcv; | |||||
SOCK_RECVBUF_LOCK(so); | SOCK_RECVBUF_LOCK(so); | ||||
sb = &so->so_rcv; | |||||
which = SO_RCV; | |||||
break; | break; | ||||
case LIO_WRITE: | case LIO_WRITE: | ||||
sb = &so->so_snd; | |||||
SOCK_SENDBUF_LOCK(so); | SOCK_SENDBUF_LOCK(so); | ||||
sb = &so->so_snd; | |||||
which = SO_SND; | |||||
break; | break; | ||||
default: | default: | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
if (SOLISTENING(so)) { | if (SOLISTENING(so)) { | ||||
if (sb == &so->so_rcv) | if (sb == &so->so_rcv) | ||||
SOCK_RECVBUF_UNLOCK(so); | SOCK_RECVBUF_UNLOCK(so); | ||||
else | else | ||||
SOCK_SENDBUF_UNLOCK(so); | SOCK_SENDBUF_UNLOCK(so); | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
if (!aio_set_cancel_function(job, soo_aio_cancel)) | if (!aio_set_cancel_function(job, soo_aio_cancel)) | ||||
panic("new job was cancelled"); | panic("new job was cancelled"); | ||||
TAILQ_INSERT_TAIL(&sb->sb_aiojobq, job, list); | TAILQ_INSERT_TAIL(&sb->sb_aiojobq, job, list); | ||||
if (!(sb->sb_flags & SB_AIO_RUNNING)) { | if (!(sb->sb_flags & SB_AIO_RUNNING)) { | ||||
if (soaio_ready(so, sb)) | if (soaio_ready(so, sb)) | ||||
sowakeup_aio(so, sb); | sowakeup_aio(so, which); | ||||
else | else | ||||
sb->sb_flags |= SB_AIO; | sb->sb_flags |= SB_AIO; | ||||
} | } | ||||
SOCKBUF_UNLOCK(sb); | SOCKBUF_UNLOCK(sb); | ||||
return (0); | return (0); | ||||
} | } |