diff options
Diffstat (limited to 'netio_posix.c')
-rw-r--r-- | netio_posix.c | 84 |
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) { |