commit 35e3b69d60f337724163e9543b5728b907ce34dd
Author:     Laslo Hunhold <[email protected]>
AuthorDate: Sun Jan 31 11:33:46 2021 +0100
Commit:     Laslo Hunhold <[email protected]>
CommitDate: Sun Jan 31 11:33:46 2021 +0100

    Refactor queue-event-handling to be pointer-centric
    
    This is one aspect where we can see that kqueue(2) is superior to
    epoll(7). While kqueue(2) allows you to both store a pointer and read
    out the fd of an event in the ready-list, epoll(7) only provides you
    with one of the two (by only offering a union-type-field where you
    either store an fd or a pointer).
    
    Previously, wrapper functions would allow to extract either from any
    event, which was only non-hacky in the OpenBSD-case, because nothing
    stopped you from reading the "fd" from the union that actually was
    assigned as a pointer. The distinction was there in the first place
    because we are listening on the main incoming socket and other "client"-
    sockets at the same time. The main-socket-events contained the socket-fd
    and the client-sockets contained the connection-struct-pointer. Now, we
    just set the data-pointer of the main socket to NULL to indicate it,
    yielding a much more refined usage with one fewer way to screw things
    up.
    
    Signed-off-by: Laslo Hunhold <[email protected]>

diff --git a/main.c b/main.c
index 2911bc8..0478993 100644
--- a/main.c
+++ b/main.c
@@ -210,9 +210,9 @@ static void *
 thread_method(void *data)
 {
        queue_event *event = NULL;
-       struct connection *connection, *c;
+       struct connection *connection, *c, *newc;
        struct worker_data *d = (struct worker_data *)data;
-       int qfd, fd;
+       int qfd;
        ssize_t nready;
        size_t i;
 
@@ -226,7 +226,7 @@ thread_method(void *data)
                exit(1);
        }
 
-       /* add insock to the interest list */
+       /* add insock to the interest list (with data=NULL) */
        if (queue_add_fd(qfd, d->insock, QUEUE_EVENT_IN, 1, NULL) < 0) {
                exit(1);
        }
@@ -244,12 +244,12 @@ thread_method(void *data)
 
                /* handle events */
                for (i = 0; i < (size_t)nready; i++) {
-                       if (queue_event_is_dropped(&event[i])) {
-                               fd = queue_event_get_fd(&event[i]);
+                       c = queue_event_get_data(&event[i]);
 
-                               if (fd != d->insock) {
-                                       memset(queue_event_get_ptr(&event[i]),
-                                              0, sizeof(struct connection));
+                       if (queue_event_is_dropped(&event[i])) {
+                               if (c != NULL) {
+                                       queue_rem_fd(qfd, c->fd);
+                                       close_connection(c);
                                }
 
                                printf("dropped a connection\n");
@@ -257,11 +257,11 @@ thread_method(void *data)
                                continue;
                        }
 
-                       if (queue_event_get_fd(&event[i]) == d->insock) {
+                       if (c == NULL) {
                                /* add new connection to the interest list */
-                               if (!(c = accept_connection(d->insock,
-                                                           connection,
-                                                           d->nslots))) {
+                               if (!(newc = accept_connection(d->insock,
+                                                              connection,
+                                                              d->nslots))) {
                                        /*
                                         * the socket is either blocking
                                         * or something failed.
@@ -275,20 +275,19 @@ thread_method(void *data)
                                 * (we want IN, because we start
                                 * with receiving the header)
                                 */
-                               if (queue_add_fd(qfd, c->fd,
+                               if (queue_add_fd(qfd, newc->fd,
                                                 QUEUE_EVENT_IN,
-                                                0, c) < 0) {
+                                                0, newc) < 0) {
                                        /* not much we can do here */
                                        continue;
                                }
                        } else {
-                               c = queue_event_get_ptr(&event[i]);
-
                                /* serve existing connection */
                                serve_connection(c, d->srv);
 
                                if (c->fd == 0) {
                                        /* we are done */
+                                       memset(c, 0, sizeof(struct connection));
                                        continue;
                                }
 
diff --git a/queue.c b/queue.c
index 53a13f1..0a94e68 100644
--- a/queue.c
+++ b/queue.c
@@ -65,14 +65,8 @@ queue_add_fd(int qfd, int fd, enum queue_event_type t, int 
shared,
                        break;
                }
 
-               /* set data */
-               if (data == NULL) {
-                       /* the data is the fd itself */
-                       e.data.fd = fd;
-               } else {
-                       /* set data pointer */
-                       e.data.ptr = (void *)data;
-               }
+               /* set data pointer */
+               e.data.ptr = (void *)data;
 
                /* register fd in the interest list */
                if (epoll_ctl(qfd, EPOLL_CTL_ADD, fd, &e) < 0) {
@@ -124,14 +118,8 @@ queue_mod_fd(int qfd, int fd, enum queue_event_type t, 
const void *data)
                        break;
                }
 
-               /* set data */
-               if (data == NULL) {
-                       /* the data is the fd itself */
-                       e.data.fd = fd;
-               } else {
-                       /* set data pointer */
-                       e.data.ptr = (void *)data;
-               }
+               /* set data pointer */
+               e.data.ptr = (void *)data;
 
                /* register fd in the interest list */
                if (epoll_ctl(qfd, EPOLL_CTL_MOD, fd, &e) < 0) {
@@ -208,18 +196,8 @@ queue_wait(int qfd, queue_event *e, size_t elen)
        return nready;
 }
 
-int
-queue_event_get_fd(const queue_event *e)
-{
-       #ifdef __linux__
-               return e->data.fd;
-       #else
-               return e->ident;
-       #endif
-}
-
 void *
-queue_event_get_ptr(const queue_event *e)
+queue_event_get_data(const queue_event *e)
 {
        #ifdef __linux__
                return e->data.ptr;
diff --git a/queue.h b/queue.h
index a59ab6f..162ac38 100644
--- a/queue.h
+++ b/queue.h
@@ -26,8 +26,7 @@ int queue_mod_fd(int, int, enum queue_event_type, const void 
*);
 int queue_rem_fd(int, int);
 ssize_t queue_wait(int, queue_event *, size_t);
 
-int queue_event_get_fd(const queue_event *);
-void *queue_event_get_ptr(const queue_event *);
+void *queue_event_get_data(const queue_event *);
 
 int queue_event_is_dropped(const queue_event *e);
 

Reply via email to