-/* $OpenBSD: uipc_socket.c,v 1.336 2024/06/14 08:32:22 mvs Exp $ */
+/* $OpenBSD: uipc_socket.c,v 1.337 2024/07/12 17:20:18 mvs Exp $ */
/* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */
/*
case AF_INET6:
switch (prp->pr_type) {
case SOCK_RAW:
- so->so_snd.sb_flags |= SB_MTXLOCK;
- /* FALLTHROUGH */
case SOCK_DGRAM:
+ so->so_snd.sb_flags |= SB_MTXLOCK;
so->so_rcv.sb_flags |= SB_MTXLOCK;
break;
}
} else if (addr == NULL)
snderr(EDESTADDRREQ);
}
- space = sbspace(so, &so->so_snd);
+ space = sbspace_locked(so, &so->so_snd);
if (flags & MSG_OOB)
space += 1024;
if (so->so_proto->pr_domain->dom_family == AF_UNIX) {
/* Splice so and sosp together. */
mtx_enter(&so->so_rcv.sb_mtx);
+ mtx_enter(&sosp->so_snd.sb_mtx);
so->so_sp->ssp_socket = sosp;
sosp->so_sp->ssp_soback = so;
+ mtx_leave(&sosp->so_snd.sb_mtx);
mtx_leave(&so->so_rcv.sb_mtx);
+
so->so_splicelen = 0;
so->so_splicemax = max;
if (tv)
*/
if (somove(so, M_WAIT)) {
mtx_enter(&so->so_rcv.sb_mtx);
+ mtx_enter(&sosp->so_snd.sb_mtx);
so->so_rcv.sb_flags |= SB_SPLICE;
- mtx_leave(&so->so_rcv.sb_mtx);
sosp->so_snd.sb_flags |= SB_SPLICE;
+ mtx_leave(&sosp->so_snd.sb_mtx);
+ mtx_leave(&so->so_rcv.sb_mtx);
}
release:
task_del(sosplice_taskq, &so->so_splicetask);
timeout_del(&so->so_idleto);
- sosp->so_snd.sb_flags &= ~SB_SPLICE;
mtx_enter(&so->so_rcv.sb_mtx);
+ mtx_enter(&sosp->so_snd.sb_mtx);
so->so_rcv.sb_flags &= ~SB_SPLICE;
+ sosp->so_snd.sb_flags &= ~SB_SPLICE;
so->so_sp->ssp_socket = sosp->so_sp->ssp_soback = NULL;
+ mtx_leave(&sosp->so_snd.sb_mtx);
mtx_leave(&so->so_rcv.sb_mtx);
/* Do not wakeup a socket that is about to be freed. */
maxreached = 1;
}
}
- space = sbspace(sosp, &sosp->so_snd);
+ mtx_enter(&sosp->so_snd.sb_mtx);
+ space = sbspace_locked(sosp, &sosp->so_snd);
if (so->so_oobmark && so->so_oobmark < len &&
so->so_oobmark < space + 1024)
space += 1024;
if (space <= 0) {
+ mtx_leave(&sosp->so_snd.sb_mtx);
maxreached = 0;
goto release;
}
if (space < len) {
maxreached = 0;
- if (space < sosp->so_snd.sb_lowat)
+ if (space < sosp->so_snd.sb_lowat) {
+ mtx_leave(&sosp->so_snd.sb_mtx);
goto release;
+ }
len = space;
}
sosp->so_snd.sb_state |= SS_ISSENDING;
+ mtx_leave(&sosp->so_snd.sb_mtx);
SBLASTRECORDCHK(&so->so_rcv, "somove 1");
SBLASTMBUFCHK(&so->so_rcv, "somove 1");
}
}
+ mtx_enter(&sosp->so_snd.sb_mtx);
/* Append all remaining data to drain socket. */
if (so->so_rcv.sb_cc == 0 || maxreached)
sosp->so_snd.sb_state &= ~SS_ISSENDING;
+ mtx_leave(&sosp->so_snd.sb_mtx);
+
error = pru_send(sosp, m, NULL, NULL);
if (error) {
if (sosp->so_snd.sb_state & SS_CANTSENDMORE)
goto nextpkt;
release:
+ mtx_enter(&sosp->so_snd.sb_mtx);
sosp->so_snd.sb_state &= ~SS_ISSENDING;
+ mtx_leave(&sosp->so_snd.sb_mtx);
+
if (!error && maxreached && so->so_splicemax == so->so_splicelen)
error = EFBIG;
if (error)
if ((so->so_snd.sb_flags & SB_MTXLOCK) == 0)
soassertlocked_readonly(so);
- kn->kn_data = sbspace(so, &so->so_snd);
+ kn->kn_data = sbspace_locked(so, &so->so_snd);
if (so->so_snd.sb_state & SS_CANTSENDMORE) {
kn->kn_flags |= EV_EOF;
if (kn->kn_flags & __EV_POLL) {
-/* $OpenBSD: rtsock.c,v 1.374 2024/06/14 08:32:22 mvs Exp $ */
+/* $OpenBSD: rtsock.c,v 1.375 2024/07/12 17:20:18 mvs Exp $ */
/* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */
/*
mtx_enter(&so->so_rcv.sb_mtx);
if (((rop->rop_flags & ROUTECB_FLAG_FLUSH) != 0) &&
- ((sbspace(so, &so->so_rcv) == so->so_rcv.sb_hiwat)))
+ ((sbspace_locked(so, &so->so_rcv) == so->so_rcv.sb_hiwat)))
rop->rop_flags &= ~ROUTECB_FLAG_FLUSH;
mtx_leave(&so->so_rcv.sb_mtx);
}
return (ENOMEM);
mtx_enter(&so->so_rcv.sb_mtx);
- if (sbspace(so, &so->so_rcv) < (2 * MSIZE) ||
+ if (sbspace_locked(so, &so->so_rcv) < (2 * MSIZE) ||
sbappendaddr(so, &so->so_rcv, &route_src, m, NULL) == 0)
send_desync = 1;
mtx_leave(&so->so_rcv.sb_mtx);
-/* $OpenBSD: socketvar.h,v 1.131 2024/05/17 19:11:14 mvs Exp $ */
+/* $OpenBSD: socketvar.h,v 1.132 2024/07/12 17:20:18 mvs Exp $ */
/* $NetBSD: socketvar.h,v 1.18 1996/02/09 18:25:38 christos Exp $ */
/*-
*/
static inline long
-sbspace(struct socket *so, struct sockbuf *sb)
+sbspace_locked(struct socket *so, struct sockbuf *sb)
{
if (sb->sb_flags & SB_MTXLOCK)
sbmtxassertlocked(so, sb);
return lmin(sb->sb_hiwat - sb->sb_cc, sb->sb_mbmax - sb->sb_mbcnt);
}
+static inline long
+sbspace(struct socket *so, struct sockbuf *sb)
+{
+ long ret;
+
+ sb_mtx_lock(sb);
+ ret = sbspace_locked(so, sb);
+ sb_mtx_unlock(sb);
+
+ return ret;
+}
+
/* do we have to send all at once on a socket? */
#define sosendallatonce(so) \
((so)->so_proto->pr_flags & PR_ATOMIC)