summaryrefslogtreecommitdiff
path: root/libhw/host_net.c
diff options
context:
space:
mode:
Diffstat (limited to 'libhw/host_net.c')
-rw-r--r--libhw/host_net.c97
1 files changed, 58 insertions, 39 deletions
diff --git a/libhw/host_net.c b/libhw/host_net.c
index f977739..e89cd66 100644
--- a/libhw/host_net.c
+++ b/libhw/host_net.c
@@ -33,6 +33,9 @@
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)
@@ -202,27 +205,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;
@@ -233,20 +236,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,
};
@@ -259,59 +261,76 @@ 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;
}