summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2004-06-14 18:16:22 +0000
committerrwatson <rwatson@FreeBSD.org>2004-06-14 18:16:22 +0000
commitf2c0db1521299639d6b16b7d477a777fbd81ada6 (patch)
tree38ab74987dd7d2d27fad4ea4e4772c7d36baf7d4 /sys/kern
parent1598e7b4234febacb1b16af62169c90a2e93cc6b (diff)
downloadFreeBSD-src-f2c0db1521299639d6b16b7d477a777fbd81ada6.zip
FreeBSD-src-f2c0db1521299639d6b16b7d477a777fbd81ada6.tar.gz
The socket field so_state is used to hold a variety of socket related
flags relating to several aspects of socket functionality. This change breaks out several bits relating to send and receive operation into a new per-socket buffer field, sb_state, in order to facilitate locking. This is required because, in order to provide more granular locking of sockets, different state fields have different locking properties. The following fields are moved to sb_state: SS_CANTRCVMORE (so_state) SS_CANTSENDMORE (so_state) SS_RCVATMARK (so_state) Rename respectively to: SBS_CANTRCVMORE (so_rcv.sb_state) SBS_CANTSENDMORE (so_snd.sb_state) SBS_RCVATMARK (so_rcv.sb_state) This facilitates locking by isolating fields to be located with other identically locked fields, and permits greater granularity in socket locking by avoiding storing fields with different locking semantics in the same short (avoiding locking conflicts). In the future, we may wish to coallesce sb_state and sb_flags; for the time being I leave them separate and there is no additional memory overhead due to the packing/alignment of shorts in the socket buffer structure.
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/sys_socket.c8
-rw-r--r--sys/kern/uipc_sockbuf.c12
-rw-r--r--sys/kern/uipc_socket.c20
-rw-r--r--sys/kern/uipc_socket2.c12
-rw-r--r--sys/kern/uipc_syscalls.c8
-rw-r--r--sys/kern/uipc_usrreq.c2
6 files changed, 35 insertions, 27 deletions
diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c
index 5f14608..a580b43 100644
--- a/sys/kern/sys_socket.c
+++ b/sys/kern/sys_socket.c
@@ -168,7 +168,7 @@ soo_ioctl(fp, cmd, data, active_cred, td)
return (0);
case SIOCATMARK:
- *(int *)data = (so->so_state&SS_RCVATMARK) != 0;
+ *(int *)data = (so->so_rcv.sb_state & SBS_RCVATMARK) != 0;
return (0);
}
/*
@@ -207,13 +207,13 @@ soo_stat(fp, ub, active_cred, td)
bzero((caddr_t)ub, sizeof (*ub));
ub->st_mode = S_IFSOCK;
/*
- * If SS_CANTRCVMORE is set, but there's still data left in the
+ * If SBS_CANTRCVMORE is set, but there's still data left in the
* receive buffer, the socket is still readable.
*/
- if ((so->so_state & SS_CANTRCVMORE) == 0 ||
+ if ((so->so_rcv.sb_state & SBS_CANTRCVMORE) == 0 ||
so->so_rcv.sb_cc != 0)
ub->st_mode |= S_IRUSR | S_IRGRP | S_IROTH;
- if ((so->so_state & SS_CANTSENDMORE) == 0)
+ if ((so->so_snd.sb_state & SBS_CANTSENDMORE) == 0)
ub->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH;
ub->st_size = so->so_rcv.sb_cc - so->so_rcv.sb_ctl;
ub->st_uid = so->so_cred->cr_uid;
diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c
index 7dbc19d..2d50f32 100644
--- a/sys/kern/uipc_sockbuf.c
+++ b/sys/kern/uipc_sockbuf.c
@@ -153,7 +153,9 @@ soisdisconnecting(so)
{
so->so_state &= ~SS_ISCONNECTING;
- so->so_state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE);
+ so->so_state |= SS_ISDISCONNECTING;
+ so->so_rcv.sb_state |= SBS_CANTRCVMORE;
+ so->so_snd.sb_state |= SBS_CANTSENDMORE;
wakeup(&so->so_timeo);
sowwakeup(so);
sorwakeup(so);
@@ -165,7 +167,9 @@ soisdisconnected(so)
{
so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
- so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE|SS_ISDISCONNECTED);
+ so->so_state |= SS_ISDISCONNECTED;
+ so->so_rcv.sb_state |= SBS_CANTRCVMORE;
+ so->so_snd.sb_state |= SBS_CANTSENDMORE;
wakeup(&so->so_timeo);
sbdrop(&so->so_snd, so->so_snd.sb_cc);
sowwakeup(so);
@@ -270,7 +274,7 @@ socantsendmore(so)
struct socket *so;
{
- so->so_state |= SS_CANTSENDMORE;
+ so->so_snd.sb_state |= SBS_CANTSENDMORE;
sowwakeup(so);
}
@@ -279,7 +283,7 @@ socantrcvmore(so)
struct socket *so;
{
- so->so_state |= SS_CANTRCVMORE;
+ so->so_rcv.sb_state |= SBS_CANTRCVMORE;
sorwakeup(so);
}
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 145a5a6..fb9043c 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -608,7 +608,7 @@ restart:
goto out;
do {
s = splnet();
- if (so->so_state & SS_CANTSENDMORE)
+ if (so->so_snd.sb_state & SBS_CANTSENDMORE)
snderr(EPIPE);
if (so->so_error) {
error = so->so_error;
@@ -758,7 +758,7 @@ restart:
so->so_options |= SO_DONTROUTE;
s = splnet(); /* XXX */
/*
- * XXX all the SS_CANTSENDMORE checks previously
+ * XXX all the SBS_CANTSENDMORE checks previously
* done could be out of date. We could have recieved
* a reset packet in an interrupt or maybe we slept
* while doing page faults in uiomove() etc. We could
@@ -920,7 +920,7 @@ restart:
so->so_error = 0;
goto release;
}
- if (so->so_state & SS_CANTRCVMORE) {
+ if (so->so_rcv.sb_state & SBS_CANTRCVMORE) {
if (m)
goto dontblock;
else
@@ -1035,7 +1035,7 @@ dontblock:
else
KASSERT(m->m_type == MT_DATA || m->m_type == MT_HEADER,
("m->m_type == %d", m->m_type));
- so->so_state &= ~SS_RCVATMARK;
+ so->so_rcv.sb_state &= ~SBS_RCVATMARK;
len = uio->uio_resid;
if (so->so_oobmark && len > so->so_oobmark - offset)
len = so->so_oobmark - offset;
@@ -1125,7 +1125,7 @@ dontblock:
if ((flags & MSG_PEEK) == 0) {
so->so_oobmark -= len;
if (so->so_oobmark == 0) {
- so->so_state |= SS_RCVATMARK;
+ so->so_rcv.sb_state |= SBS_RCVATMARK;
break;
}
} else {
@@ -1145,7 +1145,7 @@ dontblock:
*/
while (flags & MSG_WAITALL && m == NULL && uio->uio_resid > 0 &&
!sosendallatonce(so) && nextrecord == NULL) {
- if (so->so_error || so->so_state & SS_CANTRCVMORE)
+ if (so->so_error || so->so_rcv.sb_state & SBS_CANTRCVMORE)
break;
/*
* Notify the protocol that some data has been
@@ -1192,7 +1192,7 @@ dontblock:
(*pr->pr_usrreqs->pru_rcvd)(so, flags);
}
if (orig_resid == uio->uio_resid && orig_resid &&
- (flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) {
+ (flags & MSG_EOR) == 0 && (so->so_rcv.sb_state & SBS_CANTRCVMORE) == 0) {
sbunlock(&so->so_rcv);
splx(s);
goto restart;
@@ -1834,7 +1834,7 @@ sopoll(struct socket *so, int events, struct ucred *active_cred,
revents |= events & (POLLOUT | POLLWRNORM);
if (events & (POLLPRI | POLLRDBAND))
- if (so->so_oobmark || (so->so_state & SS_RCVATMARK))
+ if (so->so_oobmark || (so->so_rcv.sb_state & SBS_RCVATMARK))
revents |= events & (POLLPRI | POLLRDBAND);
if (revents == 0) {
@@ -1905,7 +1905,7 @@ filt_soread(struct knote *kn, long hint)
int result;
kn->kn_data = so->so_rcv.sb_cc - so->so_rcv.sb_ctl;
- if (so->so_state & SS_CANTRCVMORE) {
+ if (so->so_rcv.sb_state & SBS_CANTRCVMORE) {
kn->kn_flags |= EV_EOF;
kn->kn_fflags = so->so_error;
result = 1;
@@ -1938,7 +1938,7 @@ filt_sowrite(struct knote *kn, long hint)
int result;
kn->kn_data = sbspace(&so->so_snd);
- if (so->so_state & SS_CANTSENDMORE) {
+ if (so->so_snd.sb_state & SBS_CANTSENDMORE) {
kn->kn_flags |= EV_EOF;
kn->kn_fflags = so->so_error;
result = 1;
diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c
index 7dbc19d..2d50f32 100644
--- a/sys/kern/uipc_socket2.c
+++ b/sys/kern/uipc_socket2.c
@@ -153,7 +153,9 @@ soisdisconnecting(so)
{
so->so_state &= ~SS_ISCONNECTING;
- so->so_state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE);
+ so->so_state |= SS_ISDISCONNECTING;
+ so->so_rcv.sb_state |= SBS_CANTRCVMORE;
+ so->so_snd.sb_state |= SBS_CANTSENDMORE;
wakeup(&so->so_timeo);
sowwakeup(so);
sorwakeup(so);
@@ -165,7 +167,9 @@ soisdisconnected(so)
{
so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
- so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE|SS_ISDISCONNECTED);
+ so->so_state |= SS_ISDISCONNECTED;
+ so->so_rcv.sb_state |= SBS_CANTRCVMORE;
+ so->so_snd.sb_state |= SBS_CANTSENDMORE;
wakeup(&so->so_timeo);
sbdrop(&so->so_snd, so->so_snd.sb_cc);
sowwakeup(so);
@@ -270,7 +274,7 @@ socantsendmore(so)
struct socket *so;
{
- so->so_state |= SS_CANTSENDMORE;
+ so->so_snd.sb_state |= SBS_CANTSENDMORE;
sowwakeup(so);
}
@@ -279,7 +283,7 @@ socantrcvmore(so)
struct socket *so;
{
- so->so_state |= SS_CANTRCVMORE;
+ so->so_rcv.sb_state |= SBS_CANTRCVMORE;
sorwakeup(so);
}
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index 18a5e24..5ebb7dd 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -292,7 +292,7 @@ accept1(td, uap, compat)
goto noconnection;
}
while (TAILQ_EMPTY(&head->so_comp) && head->so_error == 0) {
- if (head->so_state & SS_CANTRCVMORE) {
+ if (head->so_rcv.sb_state & SBS_CANTRCVMORE) {
head->so_error = ECONNABORTED;
break;
}
@@ -1842,7 +1842,7 @@ retry_lookup:
* before going to the extra work of constituting the sf_buf.
*/
if ((so->so_state & SS_NBIO) && sbspace(&so->so_snd) <= 0) {
- if (so->so_state & SS_CANTSENDMORE)
+ if (so->so_snd.sb_state & SBS_CANTSENDMORE)
error = EPIPE;
else
error = EAGAIN;
@@ -2001,8 +2001,8 @@ retry_space:
* blocks before the pru_send (or more accurately, any blocking
* results in a loop back to here to re-check).
*/
- if ((so->so_state & SS_CANTSENDMORE) || so->so_error) {
- if (so->so_state & SS_CANTSENDMORE) {
+ if ((so->so_snd.sb_state & SBS_CANTSENDMORE) || so->so_error) {
+ if (so->so_snd.sb_state & SBS_CANTSENDMORE) {
error = EPIPE;
} else {
error = so->so_error;
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index aa435f2..18a4274 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -378,7 +378,7 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
}
}
- if (so->so_state & SS_CANTSENDMORE) {
+ if (so->so_snd.sb_state & SBS_CANTSENDMORE) {
error = EPIPE;
break;
}
OpenPOWER on IntegriCloud