Vectorize netconn_write for TCP
This commit adds support to the netconn write APIs to take an input of vectors instead of a single data pointer This allows vectors sent on a TCP connection via sendmsg to be treated atomically. The set of vectors is segmented into as much data as can fit into the send buffer and then the TCP output function is called Previously, each vector was passed to netconn_write_partly and tcp_write segmented it into its own packet, which was then it was sent via tcp_output (if not Nagleing) This commit adds vector support to lwip_netconn_do_writemore() which is the meat of the TCP write functionality from netconn/sockets layer. A new netconn API netconn_write_vectors_partly() takes a set of vectors as input and hooks up to do_writemore() This commit also defines IOV_MAX because we are limited to only supporting 65535 vectors due to choice of u16_t for the vector count
This commit is contained in:
@@ -1061,6 +1061,8 @@ lwip_sendmsg(int s, const struct msghdr *msg, int flags)
|
||||
|
||||
LWIP_ERROR("lwip_sendmsg: invalid msghdr", msg != NULL,
|
||||
sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;);
|
||||
LWIP_ERROR("lwip_sendmsg: maximum iovs exceeded", (msg->msg_iovlen <= IOV_MAX),
|
||||
sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;);
|
||||
|
||||
LWIP_UNUSED_ARG(msg->msg_control);
|
||||
LWIP_UNUSED_ARG(msg->msg_controllen);
|
||||
@@ -1074,32 +1076,11 @@ lwip_sendmsg(int s, const struct msghdr *msg, int flags)
|
||||
((flags & MSG_MORE) ? NETCONN_MORE : 0) |
|
||||
((flags & MSG_DONTWAIT) ? NETCONN_DONTBLOCK : 0);
|
||||
|
||||
for (i = 0; i < msg->msg_iovlen; i++) {
|
||||
u8_t apiflags = write_flags;
|
||||
if (i + 1 < msg->msg_iovlen) {
|
||||
apiflags |= NETCONN_MORE;
|
||||
}
|
||||
written = 0;
|
||||
err = netconn_write_partly(sock->conn, msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len, write_flags, &written);
|
||||
if (err == ERR_OK) {
|
||||
size += written;
|
||||
/* check that the entire IO vector was accepected, if not return a partial write */
|
||||
if (written != msg->msg_iov[i].iov_len)
|
||||
break;
|
||||
}
|
||||
/* none of this IO vector was accepted, but previous was, return partial write and conceal ERR_WOULDBLOCK */
|
||||
else if (err == ERR_WOULDBLOCK && size > 0) {
|
||||
err = ERR_OK;
|
||||
/* let ERR_WOULDBLOCK persist on the netconn since we are returning ERR_OK */
|
||||
break;
|
||||
} else {
|
||||
size = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
written = 0;
|
||||
err = netconn_write_vectors_partly(sock->conn, (struct netvector *)msg->msg_iov, (u16_t)msg->msg_iovlen, write_flags, &written);
|
||||
sock_set_errno(sock, err_to_errno(err));
|
||||
done_socket(sock);
|
||||
return size;
|
||||
return (err == ERR_OK ? (int)written : -1);
|
||||
#else /* LWIP_TCP */
|
||||
sock_set_errno(sock, err_to_errno(ERR_ARG));
|
||||
done_socket(sock);
|
||||
|
||||
Reference in New Issue
Block a user