summaryrefslogtreecommitdiff
path: root/libhw/host_net.c
diff options
context:
space:
mode:
authorLuke T. Shumaker <lukeshu@lukeshu.com>2025-03-02 13:30:05 -0700
committerLuke T. Shumaker <lukeshu@lukeshu.com>2025-03-02 13:30:05 -0700
commit255baf6db201dcdf8da017d55c577622f217a888 (patch)
tree905a389bc9fdf072cbdf7e9f21b2b936881eb620 /libhw/host_net.c
parent188ac62a0c0f5519f5d45519fa7d224cb25305c6 (diff)
parent5a84ba2361cecade0343b88f696b6a63454cc3c6 (diff)
Merge branch 'lukeshu/iov'
Diffstat (limited to 'libhw/host_net.c')
-rw-r--r--libhw/host_net.c130
1 files changed, 77 insertions, 53 deletions
diff --git a/libhw/host_net.c b/libhw/host_net.c
index eee293e..9d3e97b 100644
--- a/libhw/host_net.c
+++ b/libhw/host_net.c
@@ -30,8 +30,18 @@
#include "host_util.h" /* for host_sigrt_alloc(), ns_to_host_us_time() */
-LO_IMPLEMENTATION_C(net_stream_conn, struct _hostnet_tcp_conn, hostnet_tcp, static)
+LO_IMPLEMENTATION_C(io_closer, struct hostnet_tcp_listener, hostnet_tcplist, static)
LO_IMPLEMENTATION_C(net_stream_listener, struct hostnet_tcp_listener, hostnet_tcplist, static)
+
+LO_IMPLEMENTATION_C(io_reader, struct _hostnet_tcp_conn, hostnet_tcp, static)
+LO_IMPLEMENTATION_C(io_writer, struct _hostnet_tcp_conn, hostnet_tcp, static)
+LO_IMPLEMENTATION_C(io_readwriter, struct _hostnet_tcp_conn, hostnet_tcp, static)
+LO_IMPLEMENTATION_C(io_closer, struct _hostnet_tcp_conn, hostnet_tcp, static)
+LO_IMPLEMENTATION_C(io_bidi_closer, struct _hostnet_tcp_conn, hostnet_tcp, static)
+LO_IMPLEMENTATION_C(net_stream_conn, struct _hostnet_tcp_conn, hostnet_tcp, static)
+
+
+LO_IMPLEMENTATION_C(io_closer, struct hostnet_udp_conn, hostnet_udp, static)
LO_IMPLEMENTATION_C(net_packet_conn, struct hostnet_udp_conn, hostnet_udp, static)
/* common *********************************************************************/
@@ -196,27 +206,27 @@ static void hostnet_tcp_set_read_deadline(struct _hostnet_tcp_conn *conn, uint64
conn->read_deadline_ns = ts_ns;
}
-struct hostnet_pthread_read_args {
- pthread_t cr_thread;
- cid_t cr_coroutine;
+struct hostnet_pthread_readv_args {
+ pthread_t cr_thread;
+ cid_t cr_coroutine;
- int connfd;
- struct timeval timeout;
- void *buf;
- size_t count;
+ int connfd;
+ struct timeval timeout;
+ const struct iovec *iov;
+ int iovcnt;
- ssize_t *ret;
+ ssize_t *ret;
};
-static void *hostnet_pthread_read(void *_args) {
- struct hostnet_pthread_read_args *args = _args;
+static void *hostnet_pthread_readv(void *_args) {
+ struct hostnet_pthread_readv_args *args = _args;
*(args->ret) = setsockopt(args->connfd, SOL_SOCKET, SO_RCVTIMEO,
&args->timeout, sizeof(args->timeout));
if (*(args->ret) < 0)
goto end;
- *(args->ret) = read(args->connfd, args->buf, args->count);
+ *(args->ret) = readv(args->connfd, args->iov, args->iovcnt);
if (*(args->ret) < 0)
goto end;
@@ -227,20 +237,19 @@ static void *hostnet_pthread_read(void *_args) {
return NULL;
}
-static ssize_t hostnet_tcp_read(struct _hostnet_tcp_conn *conn, void *buf, size_t count) {
+static ssize_t hostnet_tcp_readv(struct _hostnet_tcp_conn *conn, const struct iovec *iov, int iovcnt) {
assert(conn);
- assert(count == 0 || buf);
- if (count == 0)
- return 0;
+ assert(iov);
+ assert(iovcnt > 0);
ssize_t ret;
- struct hostnet_pthread_read_args args = {
+ struct hostnet_pthread_readv_args args = {
.cr_thread = pthread_self(),
.cr_coroutine = cr_getcid(),
.connfd = conn->fd,
- .buf = buf,
- .count = count,
+ .iov = iov,
+ .iovcnt = iovcnt,
.ret = &ret,
};
@@ -253,78 +262,93 @@ static ssize_t hostnet_tcp_read(struct _hostnet_tcp_conn *conn, void *buf, size_
args.timeout = (host_us_time_t){0};
}
- if (RUN_PTHREAD(hostnet_pthread_read, &args))
+ if (RUN_PTHREAD(hostnet_pthread_readv, &args))
return -NET_ETHREAD;
return ret;
}
/* TCP write() ****************************************************************/
-struct hostnet_pthread_write_args {
- pthread_t cr_thread;
- cid_t cr_coroutine;
+struct hostnet_pthread_writev_args {
+ pthread_t cr_thread;
+ cid_t cr_coroutine;
- int connfd;
- void *buf;
- size_t count;
+ int connfd;
+ const struct iovec *iov;
+ int iovcnt;
- ssize_t *ret;
+ ssize_t *ret;
};
-static void *hostnet_pthread_write(void *_args) {
- struct hostnet_pthread_write_args *args = _args;
+static void *hostnet_pthread_writev(void *_args) {
+ struct hostnet_pthread_writev_args *args = _args;
+
+ size_t count = 0;
+ struct iovec *iov = alloca(sizeof(struct iovec)*args->iovcnt);
+ for (int i = 0; i < args->iovcnt; i++) {
+ iov[i] = args->iov[i];
+ count += args->iov[i].iov_len;
+ }
+ int iovcnt = args->iovcnt;
+
size_t done = 0;
- while (done < args->count) {
- ssize_t r = write(args->connfd, args->buf, args->count);
+ while (done < count) {
+ ssize_t r = writev(args->connfd, iov, iovcnt);
if (r < 0) {
hostnet_map_negerrno(-errno, OP_RECV);
break;
}
done += r;
+ while (iovcnt && (size_t)r >= iov[0].iov_len) {
+ r -= iov[0].iov_len;
+ iov++;
+ iovcnt--;
+ }
+ if (r > 0) {
+ iov[0].iov_base += r;
+ iov[0].iov_len -= r;
+ }
}
- if (done == args->count)
+ if (done == count)
*(args->ret) = done;
WAKE_COROUTINE(args);
return NULL;
}
-static ssize_t hostnet_tcp_write(struct _hostnet_tcp_conn *conn, void *buf, size_t count) {
+static ssize_t hostnet_tcp_writev(struct _hostnet_tcp_conn *conn, const struct iovec *iov, int iovcnt) {
assert(conn);
- assert(count == 0 || buf);
- if (count == 0)
- return 0;
+ assert(iov);
+ assert(iovcnt > 0);
ssize_t ret;
- struct hostnet_pthread_write_args args = {
+ struct hostnet_pthread_writev_args args = {
.cr_thread = pthread_self(),
.cr_coroutine = cr_getcid(),
.connfd = conn->fd,
- .buf = buf,
- .count = count,
+ .iov = iov,
+ .iovcnt = iovcnt,
.ret = &ret,
};
- if (RUN_PTHREAD(hostnet_pthread_write, &args))
+ if (RUN_PTHREAD(hostnet_pthread_writev, &args))
return -NET_ETHREAD;
return ret;
}
/* TCP close() ****************************************************************/
-static int hostnet_tcp_close(struct _hostnet_tcp_conn *conn, bool rd, bool wr) {
+static int hostnet_tcp_close(struct _hostnet_tcp_conn *conn) {
assert(conn);
-
- int how;
- if (rd && wr)
- how = SHUT_RDWR;
- else if (rd && !wr)
- how = SHUT_RD;
- else if (!rd && wr)
- how = SHUT_WR;
- else
- assert_notreached("invalid arguments to stream_conn.close()");
- return hostnet_map_negerrno(shutdown(conn->fd, how) ? -errno : 0, OP_NONE);
+ return hostnet_map_negerrno(shutdown(conn->fd, SHUT_RDWR) ? -errno : 0, OP_NONE);
+}
+static int hostnet_tcp_close_read(struct _hostnet_tcp_conn *conn) {
+ assert(conn);
+ return hostnet_map_negerrno(shutdown(conn->fd, SHUT_RD) ? -errno : 0, OP_NONE);
+}
+static int hostnet_tcp_close_write(struct _hostnet_tcp_conn *conn) {
+ assert(conn);
+ return hostnet_map_negerrno(shutdown(conn->fd, SHUT_WR) ? -errno : 0, OP_NONE);
}
/* UDP init() *****************************************************************/
@@ -412,7 +436,7 @@ static ssize_t hostnet_udp_sendto(struct hostnet_udp_conn *conn, void *buf, size
/* UDP recvfrom() *************************************************************/
-static void hostnet_udp_set_read_deadline(struct hostnet_udp_conn *conn,
+static void hostnet_udp_set_recv_deadline(struct hostnet_udp_conn *conn,
uint64_t ts_ns) {
assert(conn);