From 72c2e24050fc8d21c64d1427d76b58483bdf9d05 Mon Sep 17 00:00:00 2001
From: Lorenz Stechauner <lorenz.stechauner@necronda.net>
Date: Tue, 11 Jul 2023 01:51:47 +0200
Subject: [PATCH] Small improvements in async

---
 src/async.c | 37 +++++++++++++++++++++++++++++++++++++
 src/async.h | 15 ++++++++++-----
 2 files changed, 47 insertions(+), 5 deletions(-)

diff --git a/src/async.c b/src/async.c
index 97ee0f2..82576f2 100644
--- a/src/async.c
+++ b/src/async.c
@@ -49,6 +49,13 @@ static short async_a2p(async_evt_t events) {
     if (events & ASYNC_IN)  ret |= POLLIN;
     if (events & ASYNC_PRI) ret |= POLLPRI;
     if (events & ASYNC_OUT) ret |= POLLOUT;
+    if (events & ASYNC_ERR) ret |= POLLERR;
+    if (events & ASYNC_HUP) ret |= POLLHUP;
+    if (events & ASYNC_RDNORM) ret |= POLLRDNORM;
+    if (events & ASYNC_RDBAND) ret |= POLLRDBAND;
+    if (events & ASYNC_WRNORM) ret |= POLLWRNORM;
+    if (events & ASYNC_WRBAND) ret |= POLLWRBAND;
+    if (events & ASYNC_MSG) ret |= POLLMSG;
     return ret;
 }
 
@@ -57,6 +64,13 @@ static unsigned int async_a2e(async_evt_t events) {
     if (events & ASYNC_IN)  ret |= EPOLLIN;
     if (events & ASYNC_PRI) ret |= EPOLLPRI;
     if (events & ASYNC_OUT) ret |= EPOLLOUT;
+    if (events & ASYNC_ERR) ret |= EPOLLERR;
+    if (events & ASYNC_HUP) ret |= EPOLLHUP;
+    if (events & ASYNC_RDNORM) ret |= EPOLLRDNORM;
+    if (events & ASYNC_RDBAND) ret |= EPOLLRDBAND;
+    if (events & ASYNC_WRNORM) ret |= EPOLLWRNORM;
+    if (events & ASYNC_WRBAND) ret |= EPOLLWRBAND;
+    if (events & ASYNC_MSG) ret |= EPOLLMSG;
     return ret;
 }
 
@@ -67,6 +81,11 @@ static async_evt_t async_p2a(short events) {
     if (events & POLLOUT)  ret |= ASYNC_OUT;
     if (events & POLLERR)  ret |= ASYNC_ERR;
     if (events & POLLHUP)  ret |= ASYNC_HUP;
+    if (events & POLLRDNORM) ret |= ASYNC_RDNORM;
+    if (events & POLLRDBAND) ret |= ASYNC_RDBAND;
+    if (events & POLLWRNORM) ret |= ASYNC_WRNORM;
+    if (events & POLLWRBAND) ret |= ASYNC_WRBAND;
+    if (events & POLLMSG) ret |= ASYNC_MSG;
     return ret;
 }
 
@@ -77,9 +96,22 @@ static async_evt_t async_e2a(unsigned int events) {
     if (events & EPOLLOUT)  ret |= ASYNC_OUT;
     if (events & EPOLLERR)  ret |= ASYNC_ERR;
     if (events & EPOLLHUP)  ret |= ASYNC_HUP;
+    if (events & EPOLLRDNORM) ret |= ASYNC_RDNORM;
+    if (events & EPOLLRDBAND) ret |= ASYNC_RDBAND;
+    if (events & EPOLLWRNORM) ret |= ASYNC_WRNORM;
+    if (events & EPOLLWRBAND) ret |= ASYNC_WRBAND;
+    if (events & EPOLLMSG) ret |= ASYNC_MSG;
     return ret;
 }
 
+static short async_e2p(unsigned int events) {
+    return async_a2p(async_e2a(events));
+}
+
+static unsigned int async_p2e(short events) {
+    return async_a2e(async_p2a(events));
+}
+
 static int async_add_to_queue(evt_listen_t *evt) {
     while (sem_wait(&lock) != 0) {
         if (errno == EINTR) {
@@ -246,11 +278,13 @@ void async_thread(void) {
             while (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, evt->fd, &ev) == -1) {
                 if (errno == EEXIST) {
                     // fd already exists, delete old one
+                    warning("Unable to add file descriptor to epoll instance");
                     errno = 0;
                     if (epoll_ctl(epoll_fd, EPOLL_CTL_DEL, evt->fd, NULL) != -1)
                         continue;
                 } else if (errno == EBADF) {
                     // fd probably already closed
+                    warning("Unable to add file descriptor to epoll instance");
                     errno = 0;
                     local = list_delete(local, &evt);
                     if (local == NULL) {
@@ -277,6 +311,7 @@ void async_thread(void) {
             if (min_ts == -1000 || ts < min_ts) min_ts = ts;
         }
 
+        // epoll is used in level-triggered mode, so buffers are taken into account
         if ((num_fds = epoll_wait(epoll_fd, events, ASYNC_MAX_EVENTS, (int) (min_ts / 1000))) == -1) {
             if (errno == EINTR) {
                 // interrupt
@@ -298,6 +333,7 @@ void async_thread(void) {
                 if (epoll_ctl(epoll_fd, EPOLL_CTL_DEL, evt->fd, NULL) == -1) {
                     if (errno == EBADF || errno == ENOENT) {
                         // already closed fd or not found, do not die
+                        warning("Unable to remove file descriptor from epoll instance");
                         errno = 0;
                     } else {
                         critical("Unable to remove file descriptor from epoll instance");
@@ -328,6 +364,7 @@ void async_thread(void) {
                 if (epoll_ctl(epoll_fd, EPOLL_CTL_DEL, evt->fd, NULL) == -1) {
                     if (errno == EBADF || errno == ENOENT) {
                         // already closed fd or not found, do not die
+                        critical("Unable to remove file descriptor from epoll instance");
                         errno = 0;
                     } else {
                         critical("Unable to remove file descriptor from epoll instance");
diff --git a/src/async.h b/src/async.h
index 206771b..beedaac 100644
--- a/src/async.h
+++ b/src/async.h
@@ -14,11 +14,16 @@
 #define ASYNC_KEEP 1
 #define ASYNC_IGNORE_PENDING 2
 
-#define ASYNC_IN   0x01
-#define ASYNC_PRI  0x02
-#define ASYNC_OUT  0x04
-#define ASYNC_ERR  0x08
-#define ASYNC_HUP  0x10
+#define ASYNC_IN     0x001
+#define ASYNC_PRI    0x002
+#define ASYNC_OUT    0x004
+#define ASYNC_ERR    0x008
+#define ASYNC_HUP    0x010
+#define ASYNC_RDNORM 0x040
+#define ASYNC_RDBAND 0x080
+#define ASYNC_WRNORM 0x100
+#define ASYNC_WRBAND 0x200
+#define ASYNC_MSG    0x400
 
 #define ASYNC_WAIT_READ  ASYNC_IN
 #define ASYNC_WAIT_WRITE ASYNC_OUT