refactore EventHandler: add common fields to base struct

Sun, 11 Aug 2024 13:26:17 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 11 Aug 2024 13:26:17 +0200
changeset 541
1e1fca11aaff
parent 540
d9c3c23c635b
child 542
1327febf99c4

refactore EventHandler: add common fields to base struct

src/server/daemon/event.c file | annotate | diff | comparison | revisions
src/server/daemon/event.h file | annotate | diff | comparison | revisions
src/server/daemon/event_bsd.c file | annotate | diff | comparison | revisions
src/server/daemon/event_bsd.h file | annotate | diff | comparison | revisions
src/server/daemon/event_linux.c file | annotate | diff | comparison | revisions
src/server/daemon/event_linux.h file | annotate | diff | comparison | revisions
src/server/daemon/event_solaris.c file | annotate | diff | comparison | revisions
src/server/daemon/event_solaris.h file | annotate | diff | comparison | revisions
src/server/daemon/httplistener.c file | annotate | diff | comparison | revisions
src/server/daemon/httplistener.h file | annotate | diff | comparison | revisions
--- a/src/server/daemon/event.c	Sun Aug 11 10:09:20 2024 +0200
+++ b/src/server/daemon/event.c	Sun Aug 11 13:26:17 2024 +0200
@@ -27,6 +27,7 @@
  */
 
 #include <cx/hash_map.h>
+#include <cx/linked_list.h>
 #include "../util/atomic.h"
 
 #include "event.h"
@@ -118,3 +119,42 @@
     ws_atomic_inc32(&ev->current);
     return ev->instances[ins];
 }
+
+
+void ev_watchlist_add(EventHandler *h, EVWatchList *elm) {
+    watchlist_add(&h->watchlist_begin, &h->watchlist_end, elm);
+}
+
+void ev_watchlist_remove(EventHandler *h, EVWatchList *elm) {
+    watchlist_remove(&h->watchlist_begin, &h->watchlist_end, elm);
+}
+
+void ev_saf_return(EventHandler *h, Session *sn, Request *rq, int ret) {
+    h->fnreturn[h->numret++] = (EVReturn){ sn, rq, ret };
+}
+
+void watchlist_add(EVWatchList **begin, EVWatchList **end, EVWatchList *elm) {
+    cx_linked_list_add(
+            (void**)begin,
+            (void**)end,
+            offsetof(EVWatchList, prev),
+            offsetof(EVWatchList, next),
+            elm);
+}
+
+void watchlist_remove(EVWatchList **begin, EVWatchList **end, EVWatchList *elm) {
+    cx_linked_list_remove(
+            (void**)begin,
+            (void**)end,
+            offsetof(EVWatchList, prev),
+            offsetof(EVWatchList, next),
+            elm);
+}
+
+void watchlist_check(EventHandler *h, time_t t) {
+    if(t == 0) {
+        t = time(NULL);
+    }
+    
+    
+}
--- a/src/server/daemon/event.h	Sun Aug 11 10:09:20 2024 +0200
+++ b/src/server/daemon/event.h	Sun Aug 11 13:26:17 2024 +0200
@@ -35,6 +35,8 @@
 #ifdef	__cplusplus
 extern "C" {
 #endif
+    
+#define EV_MAX_EVENTS 32
 
 typedef struct EVHandler {
     EventHandler **instances;
@@ -54,6 +56,35 @@
     int ret;
 } EVReturn;
 
+typedef struct EVWatchList EVWatchList;
+typedef void(*evwatchlist_destroyfunc)(EventHandler *h, EVWatchList *item, void *data);
+
+struct EVWatchList {
+    time_t created;
+    time_t expire;
+    evwatchlist_destroyfunc destroy;
+    void *destroydata;
+    EVWatchList *prev;
+    EVWatchList *next;
+};
+
+
+typedef struct EventHandler {
+    /*
+     * return call list
+     */
+    EVReturn fnreturn[EV_MAX_EVENTS];
+    /*
+     * number of fnreturn entries
+     */
+    int numret;
+    
+    EVWatchList *watchlist_begin;
+    EVWatchList *watchlist_end;
+} EventHandler;
+
+
+
 int create_event_handler(EventHandlerConfig *cfg);
 
 int check_event_handler_cfg();
@@ -64,6 +95,11 @@
 
 EventHandler* ev_instance(EVHandler *ev);
 
+void watchlist_add(EVWatchList **begin, EVWatchList **end, EVWatchList *elm);
+void watchlist_remove(EVWatchList **begin, EVWatchList **end, EVWatchList *elm);
+
+void watchlist_check(EventHandler *h, time_t t);
+
 /* implementation in event_$platform */
 EVHandler* evhandler_create(EventHandlerConfig *cfg);
 
@@ -77,6 +113,9 @@
 
 void ev_saf_return(EventHandler *h, Session *sn, Request *rq, int ret);
 
+void ev_watchlist_add(EventHandler *h, EVWatchList *elm);
+void ev_watchlist_remove(EventHandler *h, EVWatchList *elm);
+
 
 #ifdef	__cplusplus
 }
--- a/src/server/daemon/event_bsd.c	Sun Aug 11 10:09:20 2024 +0200
+++ b/src/server/daemon/event_bsd.c	Sun Aug 11 13:26:17 2024 +0200
@@ -43,7 +43,8 @@
     ev->numins = cfg->nthreads;
     
     for(int i=0;i<cfg->nthreads;i++) {
-        EventHandler *handler = malloc(sizeof(EventHandler));
+        EventHandlerKqueue *handler = malloc(sizeof(EventHandlerKqueue));
+        memset(handler, 0, sizeof(EventHandlerKqueue));
         ev->instances[i] = handler;
         
         handler->kqueue = kqueue();
@@ -64,7 +65,8 @@
 }
 
 
-void ev_handle_events(EventHandler *ev) {
+void ev_handle_events(EventHandlerKqueue *ev) {
+    EventHandler *h = (EventHandler*)ev;
     struct timespec timeout;
     timeout.tv_nsec = 0;
     timeout.tv_sec = 600;
@@ -103,7 +105,7 @@
             
             if(event->fn) {
                 int saved_ev = event->events;
-                if(!event->fn(ev, event)) {
+                if(!event->fn(h, event)) {
                     // ret 0 => remove event
                     
                     if(event->finish) {
@@ -145,12 +147,12 @@
             Event *event = finished[i];
             // check again if the finish callback is set
             if(finished[i]->finish) {
-                finished[i]->finish(ev, event);
+                finished[i]->finish(h, event);
             }
         }
         // execute return calls
-        for(int i=0;i<ev->numret;i++) {
-            EVReturn ret = ev->fnreturn[i];
+        for(int i=0;i<ev->base.numret;i++) {
+            EVReturn ret = ev->base.fnreturn[i];
             nsapi_saf_return(ret.sn, ret.rq, ret.ret);
         }
     }
@@ -215,8 +217,3 @@
 int event_removepoll(EventHandler *ev, SYS_NETFD fd) {
     return ((IOStream*)fd)->poll(fd, ev, IO_POLL_NONE, NULL);
 }
-
-
-void ev_saf_return(EventHandler *h, Session *sn, Request *rq, int ret) {
-    h->fnreturn[h->numret++] = (EVReturn){ sn, rq, ret };
-}
--- a/src/server/daemon/event_bsd.h	Sun Aug 11 10:09:20 2024 +0200
+++ b/src/server/daemon/event_bsd.h	Sun Aug 11 13:26:17 2024 +0200
@@ -37,24 +37,18 @@
 
 #ifdef	__cplusplus
 extern "C" {
-#endif
-    
-#define EV_MAX_EVENTS 32
+#endif  
 
-struct EventHandler {
-    int kqueue;
-    
+typedef struct EventHandlerKqueue {
     /*
-     * return call list
+     * base eventhandler elements (fnreturn, watchlist)
      */
-    EVReturn fnreturn[EV_MAX_EVENTS];
-    /*
-     * number of fnreturn entries
-     */
-    int numret;
-};
+    EventHandler base;
+    
+    int kqueue;
+} EventHandlerKqueue;
 
-void ev_handle_events(EventHandler *ev);
+void ev_handle_events(EventHandlerKqueue *ev);
 
 int ev_convert2sys_events(int events);
 
--- a/src/server/daemon/event_linux.c	Sun Aug 11 10:09:20 2024 +0200
+++ b/src/server/daemon/event_linux.c	Sun Aug 11 13:26:17 2024 +0200
@@ -50,8 +50,9 @@
     ev->numins = cfg->nthreads;
        
     for(int i=0;i<cfg->nthreads;i++) {
-        EventHandler *handler = malloc(sizeof(EventHandler));
-        ev->instances[i] = handler;
+        EventHandlerLinux *handler = malloc(sizeof(EventHandlerLinux));
+        memset(handler, 0, sizeof(EventHandlerLinux));
+        ev->instances[i] = (EventHandler*)handler;
         
         handler->ep = epoll_create(64);
         if(handler->ep < 0) {
@@ -86,7 +87,8 @@
     return ev;
 }
 
-void ev_handle_events(EventHandler *ev) {
+void ev_handle_events(EventHandlerLinux *ev) {
+    EventHandler *h = (EventHandler*)ev;
     int ep = ev->ep;
     
     struct epoll_event events[EV_MAX_EVENTS];
@@ -101,7 +103,7 @@
         }
         
         int numfinished = 0;
-        ev->numret = 0;
+        ev->base.numret = 0;
         for(int i=0;i<ret;i++) {
             Event *event = events[i].data.ptr;
             if(!event) {
@@ -131,7 +133,7 @@
             
             if(event->fn) {
                 int saved_ev = event->events;
-                if(!event->fn(ev, event)) {
+                if(!event->fn(h, event)) {
                     // event fn returned 0 -> remove event from epoll
                     if(epoll_ctl(ep, EPOLL_CTL_DEL, event->object, NULL)) {
                         event->error = 1;
@@ -173,12 +175,12 @@
             Event *event = finished[i];
             // check again if the finish callback is set
             if(finished[i]->finish) {
-                finished[i]->finish(ev, event);
+                finished[i]->finish(h, event);
             }
         }
         // execute return calls
-        for(int i=0;i<ev->numret;i++) {
-            EVReturn ret = ev->fnreturn[i];
+        for(int i=0;i<ev->base.numret;i++) {
+            EVReturn ret = ev->base.fnreturn[i];
             nsapi_saf_return(ret.sn, ret.rq, ret.ret);
         }
     }
@@ -196,31 +198,35 @@
 }
 
 int ev_pollin(EventHandler *h, int fd, Event *event) {
+    EventHandlerLinux *ev = (EventHandlerLinux*)h;
     event->object = (intptr_t)fd;
     event->events = EVENT_POLLIN;
     struct epoll_event epev;
     epev.events = EPOLLIN | EPOLLET; // input event, edge triggered
     epev.data.ptr = event;
-    return epoll_ctl(h->ep, EPOLL_CTL_ADD, fd, &epev);
+    return epoll_ctl(ev->ep, EPOLL_CTL_ADD, fd, &epev);
 }
 
 int ev_pollout(EventHandler *h, int fd, Event *event) {
+    EventHandlerLinux *ev = (EventHandlerLinux*)h;
     event->object = (intptr_t)fd;
     event->events = EVENT_POLLOUT;
     struct epoll_event epev;
     epev.events = EPOLLOUT | EPOLLET; // input event, edge triggered
     epev.data.ptr = event;
-    return epoll_ctl(h->ep, EPOLL_CTL_ADD, fd, &epev);
+    return epoll_ctl(ev->ep, EPOLL_CTL_ADD, fd, &epev);
 }
 
 int ev_remove_poll(EventHandler *h, int fd) {
-    return epoll_ctl(h->ep, EPOLL_CTL_DEL, fd, NULL);
+    EventHandlerLinux *ev = (EventHandlerLinux*)h;
+    return epoll_ctl(ev->ep, EPOLL_CTL_DEL, fd, NULL);
 }
 
 int event_send(EventHandler *h, Event *event) {
+    EventHandlerLinux *ev = (EventHandlerLinux*)h;
     event->object = 0;
     event->events = 0;
-    ssize_t r = write(h->eventout, &event, sizeof(Event*));
+    ssize_t r = write(ev->eventout, &event, sizeof(Event*));
     if(r < sizeof(Event*)) {
         log_ereport(LOG_FAILURE, "failed to send event: %s", strerror(errno));
     }
@@ -258,8 +264,3 @@
 int event_removepoll(EventHandler *ev, SYS_NETFD fd) {
     return ((IOStream*)fd)->poll(fd, ev, IO_POLL_NONE, NULL);
 }
-
-
-void ev_saf_return(EventHandler *h, Session *sn, Request *rq, int ret) {
-    h->fnreturn[h->numret++] = (EVReturn){ sn, rq, ret };
-}
--- a/src/server/daemon/event_linux.h	Sun Aug 11 10:09:20 2024 +0200
+++ b/src/server/daemon/event_linux.h	Sun Aug 11 13:26:17 2024 +0200
@@ -35,10 +35,13 @@
 #ifdef	__cplusplus
 extern "C" {
 #endif
-
-#define EV_MAX_EVENTS 32
     
-struct EventHandler {
+typedef struct EventHandlerLinux {
+    /*
+     * base eventhandler elements (fnreturn, watchlist)
+     */
+    EventHandler base;
+    
     /*
      * epoll fd
      */
@@ -51,17 +54,9 @@
      * pipe write fd
      */
     int eventout;
-    /*
-     * return call list
-     */
-    EVReturn fnreturn[EV_MAX_EVENTS];
-    /*
-     * number of fnreturn entries
-     */
-    int numret;
-};
+} EventHandlerLinux;
 
-void ev_handle_events(EventHandler *ev);
+void ev_handle_events(EventHandlerLinux *ev);
 
 int ev_convert2sys_events(int events);
 
--- a/src/server/daemon/event_solaris.c	Sun Aug 11 10:09:20 2024 +0200
+++ b/src/server/daemon/event_solaris.c	Sun Aug 11 13:26:17 2024 +0200
@@ -43,8 +43,9 @@
     ev->numins = cfg->nthreads;
     
     for(int i=0;i<cfg->nthreads;i++) {
-        EventHandler *handler = malloc(sizeof(EventHandler));
-        ev->instances[i] = handler;
+        EventHandlerSolaris *handler = malloc(sizeof(EventHandlerSolaris));
+        memset(handler, 0, sizeof(EventHandlerSolaris));
+        ev->instances[i] = (EventHandler*)handler;
         
         handler->port = port_create();
         if(handler->port < 0) {
@@ -64,7 +65,8 @@
 }
 
 
-void ev_handle_events(EventHandler *ev) {   
+void ev_handle_events(EventHandlerSolaris *ev) {
+    EventHandler *h = (EventHandler*)ev;
     port_event_t events[EV_MAX_EVENTS];
     Event *finished[EV_MAX_EVENTS];
     struct timespec timeout;
@@ -92,7 +94,7 @@
                     aio->result = aiocb->aio_resultp.aio_return;
                     aio->result_errno = aiocb->aio_resultp.aio_errno;
                     if(event->fn) {
-                        if(!event->fn(ev, event) && event->finish) {
+                        if(!event->fn(h, event) && event->finish) {
                             finished[numfinished++] = event;
                         }
                     }
@@ -116,7 +118,7 @@
                             perror("port_associate");
                         }                 
                     } else if(event->finish) {
-                        event->finish(ev, event);
+                        event->finish(h, event);
                     }
                 }
             }  
@@ -130,8 +132,8 @@
             }
         }
         // execute return calls
-        for(int i=0;i<ev->numret;i++) {
-            EVReturn ret = ev->fnreturn[i];
+        for(int i=0;i<ev->base.numret;i++) {
+            EVReturn ret = ev->base.fnreturn[i];
             nsapi_saf_return(ret.sn, ret.rq, ret.ret);
         }
     }
@@ -150,10 +152,11 @@
 
 
 int ev_pollin(EventHandler *h, int fd, Event *event) {
+    EventHandlerSolaris *ev = (EventHandlerSolaris*)h;
     event->object = (intptr_t)fd;
     event->events = EVENT_POLLIN;
     return port_associate(
-            h->port,
+            ev->port,
             PORT_SOURCE_FD,
             (uintptr_t)fd,
             POLLIN,
@@ -161,10 +164,11 @@
 }
 
 int ev_pollout(EventHandler *h, int fd, Event *event) {
+    EventHandlerSolaris *ev = (EventHandlerSolaris*)h;
     event->object = (intptr_t)fd;
     event->events = EVENT_POLLOUT;
     return port_associate(
-            h->port,
+            ev->port,
             PORT_SOURCE_FD,
             (uintptr_t)fd,
             POLLOUT,
@@ -172,17 +176,19 @@
 }
 
 int ev_remove_poll(EventHandler *h, int fd) {
-    return port_dissociate(h->port, PORT_SOURCE_FD, (uintptr_t)fd);
+    EventHandlerSolaris *ev = (EventHandlerSolaris*)h;
+    return port_dissociate(ev->port, PORT_SOURCE_FD, (uintptr_t)fd);
 }
 
 int event_send(EventHandler *h, Event *event) {
+    EventHandlerSolaris *ev = (EventHandlerSolaris*)h;
     event->object = 0;
     event->events = 0;
-    return port_send(h->port, 0, event);
+    return port_send(ev->port, 0, event);
 }
 
 static int ev_aio(int fd, aiocb_s *cb, WSBool read) {
-    EventHandler *ev = cb->evhandler;
+    EventHandlerSolaris *ev = cb->evhandler;
     if(!ev) {
         return -1;
     }
@@ -235,7 +241,3 @@
 int event_removepoll(EventHandler *ev, SYS_NETFD fd) {
     return ((IOStream*)fd)->poll(fd, ev, IO_POLL_NONE, NULL);
 }
-
-void ev_saf_return(EventHandler *h, Session *sn, Request *rq, int ret) {
-    h->fnreturn[h->numret++] = (EVReturn){ sn, rq, ret };
-}
--- a/src/server/daemon/event_solaris.h	Sun Aug 11 10:09:20 2024 +0200
+++ b/src/server/daemon/event_solaris.h	Sun Aug 11 13:26:17 2024 +0200
@@ -39,25 +39,20 @@
 extern "C" {
 #endif
 
-    
-#define EV_MAX_EVENTS 32
+   
     
-struct EventHandler {
-    int port;
-    
+typedef struct EventHandlerSolaris {
     /*
-     * return call list
+     * base eventhandler elements (fnreturn, watchlist)
      */
-    EVReturn fnreturn[EV_MAX_EVENTS];
-    /*
-     * number of fnreturn entries
-     */
-    int numret;
-};
+    EventHandler base;
+    
+    int port;
+} EventHandlerSolaris;
 
 int ev_convert2sys_events(int events);
 
-void ev_handle_events(EventHandler *ev);
+void ev_handle_events(EventHandlerSolaris *ev);
 
 #ifdef	__cplusplus
 }
--- a/src/server/daemon/httplistener.c	Sun Aug 11 10:09:20 2024 +0200
+++ b/src/server/daemon/httplistener.c	Sun Aug 11 13:26:17 2024 +0200
@@ -34,6 +34,7 @@
 #include <sys/shm.h>
 #include <sys/ipc.h>
 #include <sys/file.h>
+#include <netinet/tcp.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <fcntl.h>
@@ -635,7 +636,12 @@
             }
             continue;
         }
-                 
+        
+        //if(http_listener_apply_keep_alive_settings(listener, clientfd)) {
+        //    close(clientfd);
+        //    continue;
+        //}
+             
         // check listener
         HttpListener *ls = listener;
         int acceptor_exit = 0;
@@ -731,3 +737,33 @@
     // a socket
     ws_atomic_dec32(&ws->ref);
 }
+
+
+int http_listener_apply_keep_alive_settings(HttpListener *listener, int fd) {
+    // TODO: all these values should be configurable
+    int optval = 1;
+    if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval))) {
+        log_ereport(LOG_FAILURE, "listener: cannot set SO_KEEPALIVE: %s", strerror(errno));
+        return 1;
+    }
+
+    int keepidle = 60;
+    if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &keepidle, sizeof(keepidle))) {
+        log_ereport(LOG_FAILURE, "listener: cannot set TCP_KEEPIDLE to value %d: %s", keepidle, strerror(errno));
+        return 1;
+    }
+
+    int keepintvl = 10;
+    if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &keepintvl, sizeof(keepintvl))) {
+        log_ereport(LOG_FAILURE, "listener: cannot set TCP_KEEPINTVL to value %d: %s", keepintvl, strerror(errno));
+        return 1;
+    }
+
+    int keepcnt = 3;
+    if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &keepcnt, sizeof(keepcnt))) {
+        log_ereport(LOG_FAILURE, "listener: cannot set TCP_KEEPCNT to value %d: %s", keepcnt, strerror(errno));
+        return 1;
+    }
+    
+    return 0;
+}
--- a/src/server/daemon/httplistener.h	Sun Aug 11 10:09:20 2024 +0200
+++ b/src/server/daemon/httplistener.h	Sun Aug 11 13:26:17 2024 +0200
@@ -183,6 +183,8 @@
 void wssocket_ref(WSSocket *ws);
 void wssocket_unref(WSSocket *ws);
 
+int http_listener_apply_keep_alive_settings(HttpListener *listener, int fd);
+
 
 #ifdef	__cplusplus
 }

mercurial