summaryrefslogtreecommitdiff
path: root/netio_posix.c
diff options
context:
space:
mode:
Diffstat (limited to 'netio_posix.c')
-rw-r--r--netio_posix.c84
1 files changed, 45 insertions, 39 deletions
diff --git a/netio_posix.c b/netio_posix.c
index 3730f98..3cc00bb 100644
--- a/netio_posix.c
+++ b/netio_posix.c
@@ -1,7 +1,3 @@
-#define LINUX 1
-#define NUM_SOCKETS 1
-#define NUM_WORKERS 8
-
#define _GNU_SOURCE
#include <aio.h> /* for struct aiocb, aio_read(), aio_write(), aio_error(), aio_return(), SIGEV_SIGNAL */
#include <arpa/inet.h> /* for htons() */
@@ -12,7 +8,11 @@
#include <stdlib.h> /* for shutdown(), SHUT_RD, SHUT_WR, SHUT_RDWR */
#include <string.h> /* for memset() */
#include <sys/socket.h> /* for struct sockaddr, socket(), SOCK_* flags, setsockopt(), SOL_SOCKET, SO_REUSEADDR, bind(), listen(), accept() */
-#if LINUX
+
+#define USE_CONFIG_NETIO_POSIX
+#include "config.h"
+
+#if CONFIG_NETIO_ISLINUX
# include <fcntl.h> /* for fcntl(), F_SETFL, O_ASYNC, F_SETSIG */
#endif
@@ -24,32 +24,32 @@
static int sigs_allocated = 0;
static int sig_io = 0;
-#if LINUX
+#if CONFIG_NETIO_ISLINUX
static int sig_accept = 0;
#endif
struct netio_socket {
int fd;
-#if LINUX
- cid_t accept_waiters[NUM_WORKERS];
+#if CONFIG_NETIO_ISLINUX
+ cid_t accept_waiters[CONFIG_NETIO_NUM_CONNS];
#endif
};
-static struct netio_socket socket_table[NUM_SOCKETS] = {0};
+static struct netio_socket socket_table[CONFIG_NETIO_NUM_PORTS] = {0};
static void handle_sig_io(int sig __attribute__ ((unused)), siginfo_t *info, void *ucontext __attribute__ ((unused))) {
cr_unpause((cid_t)info->si_value.sival_int);
}
-#if LINUX
+#if CONFIG_NETIO_ISLINUX
static void handle_sig_accept(int sig __attribute__ ((unused)), siginfo_t *info, void *ucontext __attribute__ ((unused))) {
struct netio_socket *sock = NULL;
- for (int i = 0; sock == NULL && i < NUM_SOCKETS; i++)
+ for (int i = 0; sock == NULL && i < CONFIG_NETIO_NUM_PORTS; i++)
if (info->si_fd == socket_table[i].fd)
sock = &socket_table[i];
if (!sock)
return;
- for (int i = 0; i < NUM_WORKERS; i++)
+ for (int i = 0; i < CONFIG_NETIO_NUM_CONNS; i++)
if (sock->accept_waiters[i] > 0) {
cr_unpause(sock->accept_waiters[i]);
sock->accept_waiters[i] = 0;
@@ -73,7 +73,7 @@ static void _netio_init(void) {
if (sigaction(sig_io, &action, NULL) < 0)
error(1, errno, "sigaction");
-#if LINUX
+#if CONFIG_NETIO_ISLINUX
sig_accept = SIGRTMIN + (sigs_allocated++);
if (sig_accept > SIGRTMAX)
error(1, 0, "SIGRTMAX exceeded");
@@ -97,23 +97,23 @@ int netio_listen(uint16_t port) {
/* Allocate a handle out of socket_table. */
handle = -1;
- for (int i = 0; handle < 0 && i < NUM_SOCKETS; i++)
+ for (int i = 0; handle < 0 && i < CONFIG_NETIO_NUM_PORTS; i++)
if (socket_table[i].fd == 0)
handle = i;
if (handle < 0)
- error(1, 0, "NUM_SOCKETS exceeded");
+ error(1, 0, "CONFIG_NETIO_NUM_PORTS exceeded");
sock = &socket_table[handle];
/* Bind the socket. */
memset(&addr, 0, sizeof addr);
addr.in.sin_family = AF_INET;
addr.in.sin_port = htons(port);
- sock->fd = socket(AF_INET, SOCK_STREAM | (LINUX ? 0 : SOCK_NONBLOCK), 0);
+ sock->fd = socket(AF_INET, SOCK_STREAM | (CONFIG_NETIO_ISLINUX ? 0 : SOCK_NONBLOCK), 0);
if (sock->fd < 0)
error(1, errno, "socket");
if (setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)) < 0)
error(1, errno, "setsockopt");
-#if LINUX
+#if CONFIG_NETIO_ISLINUX
if (fcntl(sock->fd, F_SETFL, O_ASYNC) < 0)
error(1, errno, "fcntl(F_SETFL)");
if (fcntl(sock->fd, F_SETSIG, sig_accept) < 0)
@@ -121,7 +121,7 @@ int netio_listen(uint16_t port) {
#endif
if (bind(sock->fd, &addr.gen, sizeof addr) < 0)
error(1, errno, "bind");
- if (listen(sock->fd, NUM_WORKERS) < 0)
+ if (listen(sock->fd, CONFIG_NETIO_NUM_CONNS) < 0)
error(1, errno, "listen");
/* Return. */
@@ -129,9 +129,9 @@ int netio_listen(uint16_t port) {
}
int netio_accept(int sock) {
-#if LINUX
+#if CONFIG_NETIO_ISLINUX
int conn;
- for (int i = 0; i < NUM_WORKERS; i++)
+ for (int i = 0; i < CONFIG_NETIO_NUM_CONNS; i++)
if (socket_table[sock].accept_waiters[i] == 0) {
socket_table[sock].accept_waiters[i] = cr_getcid();
break;
@@ -156,7 +156,7 @@ int netio_accept(int sock) {
#endif
}
-size_t netio_read(int conn, void *buf, size_t count) {
+ssize_t netio_read(int conn, void *buf, size_t count) {
int r;
struct aiocb ctl_block = {
.aio_fildes = conn,
@@ -179,27 +179,33 @@ size_t netio_read(int conn, void *buf, size_t count) {
return r ? -abs(r) : aio_return(&ctl_block);
}
-size_t netio_write(int conn, void *buf, size_t count) {
- int r;
- struct aiocb ctl_block = {
- .aio_fildes = conn,
- .aio_buf = buf,
- .aio_nbytes = count,
- .aio_sigevent = {
- .sigev_notify = SIGEV_SIGNAL,
- .sigev_signo = sig_io,
- .sigev_value = {
- .sival_int = (int)cr_getcid(),
+ssize_t netio_write(int conn, void *buf, size_t goal) {
+ size_t done = 0;
+ while (done < goal) {
+ int r;
+ struct aiocb ctl_block = {
+ .aio_fildes = conn,
+ .aio_buf = &buf[done],
+ .aio_nbytes = goal-done,
+ .aio_sigevent = {
+ .sigev_notify = SIGEV_SIGNAL,
+ .sigev_signo = sig_io,
+ .sigev_value = {
+ .sival_int = (int)cr_getcid(),
+ },
},
- },
- };
+ };
- if (aio_write(&ctl_block) < 0)
- return -errno;
+ if (aio_write(&ctl_block) < 0)
+ return -errno;
- while ((r = aio_error(&ctl_block)) == EINPROGRESS)
- cr_pause_and_yield();
- return r ? -abs(r) : aio_return(&ctl_block);
+ while ((r = aio_error(&ctl_block)) == EINPROGRESS)
+ cr_pause_and_yield();
+ if ((r) < 0)
+ return -abs(r);
+ done += aio_return(&ctl_block);
+ }
+ return done;
}
int netio_close(int conn, bool rd, bool wr) {