move first request poll to the event handler

Sat, 24 Aug 2024 18:34:13 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sat, 24 Aug 2024 18:34:13 +0200
changeset 555
66b0accda0a8
parent 554
e0a6b761ddbc
child 556
b036ccad4b49

move first request poll to the event handler

src/server/daemon/event.c file | annotate | diff | comparison | revisions
src/server/daemon/event.h file | annotate | diff | comparison | revisions
src/server/daemon/sessionhandler.c file | annotate | diff | comparison | revisions
src/server/daemon/sessionhandler.h file | annotate | diff | comparison | revisions
--- a/src/server/daemon/event.c	Sat Aug 24 12:13:01 2024 +0200
+++ b/src/server/daemon/event.c	Sat Aug 24 18:34:13 2024 +0200
@@ -32,7 +32,7 @@
 
 #include "event.h"
 
-CxMap *event_handler_map = NULL;
+static CxMap *event_handler_map = NULL;
 int numevhandlers = 0;
 
 EVHandler *default_event_handler = NULL;
@@ -78,6 +78,20 @@
     return ret;
 }
 
+void shutdown_eventhandlers_wait(void) {
+    CxIterator i = cxMapIteratorValues(event_handler_map);
+    cx_foreach(EVHandler *, e, i) {
+        evhandler_shutdown(e);
+    }
+    
+    i = cxMapIteratorValues(event_handler_map);
+    cx_foreach(EVHandler *, e, i) {
+        evhandler_wait_and_destroy(e);
+    }
+    
+    cxMapDestroy(event_handler_map);
+}
+
 void evhandler_shutdown(EVHandler *h) {
     for(int i=0;i<h->numins;i++) {
         ev_instance_shutdown(h->instances[i]);
--- a/src/server/daemon/event.h	Sat Aug 24 12:13:01 2024 +0200
+++ b/src/server/daemon/event.h	Sat Aug 24 18:34:13 2024 +0200
@@ -89,6 +89,8 @@
 } EventHandler;
 
 
+void shutdown_eventhandlers_wait(void);
+
 void evhandler_shutdown(EVHandler *h);
 
 void evhandler_close(EVHandler *h);
--- a/src/server/daemon/sessionhandler.c	Sat Aug 24 12:13:01 2024 +0200
+++ b/src/server/daemon/sessionhandler.c	Sat Aug 24 18:34:13 2024 +0200
@@ -236,65 +236,72 @@
     evt_request_error(h, io->io_event);
 }
 
-int evt_add_request_timeout(EventHandler *h, Event *event) {
+int evt_add_request(EventHandler *h, Event *event) {
     EventHttpIO *io = event->cookie;
-    io->watch.intdata = 1;
-    ev_watchlist_add(h, &io->watch); 
+    Connection *conn = io->request->connection;
+    
+    if(ev_pollin(h, conn->fd, io->io_event) != 0) {
+        // TODO: ev_pollin should log, intercept some errors here
+        log_ereport(LOG_FAILURE, "Cannot enqueue connection");
+        evt_request_error(h, event);
+    } else {
+        // add request timeout
+        io->watch.intdata = 1;
+        io->watch.created = time(NULL);
+        io->watch.expire = io->watch.created + 240; // TODO: config
+        io->watch.destroy = evt_request_timeout;
+        io->watch.data1 = io;
+        ev_watchlist_add(h, &io->watch); 
+    }
+    
     return 0;
 }
 
 void evt_enq_conn(SessionHandler *handler, Connection *conn) {
+    Event *start_request = malloc(sizeof(Event));
+    if(!start_request) {
+        connection_destroy(conn);
+        return;
+    }
+    
     Event *event = malloc(sizeof(Event));
     if(!event) {
         connection_destroy(conn);
+        free(start_request);
         return;
     }
     
     EventHttpIO *io = evt_req_init(handler, conn);
     if(!io) {
         connection_destroy(conn);
+        free(start_request);
         free(event);
         return;
     }
     
-    /*
-     * to start the request handling, we begin with a poll on the socket,
-     * 
-     * evt_enq_conn() --> event handler --> handle_request()
-     */
-    
     ZERO(event, sizeof(Event));
     event->fn = conn->ssl && !conn->ssl_accepted ? evt_request_ssl_accept : evt_request_input;
     event->finish = evt_request_finish;
     event->cookie = io;
     io->io_event = event;
     
+    /*
+     * to start the request handling, switch to the event handler
+     * 
+     * evt_enq_conn() --> event handler --> handle_request()
+     */
+    
     EventHandler *ev = ev_instance(((EventSessionHandler*)handler)->eventhandler);
     
-    if(ev_pollin(ev, conn->fd, event) != 0) {
-        // TODO: ev_pollin should log, intercept some errors here
-        log_ereport(LOG_FAILURE, "Cannot enqueue connection");
+    ZERO(start_request, sizeof(Event));
+    start_request->cookie = io;
+    start_request->fn = evt_add_request;
+    start_request->finish = ev_free_event;
+    start_request->error = 0;
+    if(event_send(ev, start_request)) {
+        log_ereport(LOG_FAILURE, "Cannot start request timeout: event_send failed");
         evt_request_error(ev, event);
-    } else {
-        // add request timeout
-        io->watch.created = time(NULL);
-        io->watch.expire = io->watch.created + 240; // TODO: config
-        io->watch.destroy = evt_request_timeout;
-        io->watch.data1 = io;
-        
-        Event *add_timeout = malloc(sizeof(Event));
-        if(add_timeout) {
-            add_timeout->cookie = io;
-            add_timeout->fn = evt_add_request_timeout;
-            add_timeout->finish = ev_free_event;
-            add_timeout->error = 0;
-            if(event_send(ev, add_timeout)) {
-                log_ereport(LOG_FAILURE, "Cannot add request timeout: event_send failed");
-            }
-        } else {
-            // not an error that breaks everything, a log message is enough
-            log_ereport(LOG_FAILURE, "Cannot add request timeout: OOM");
-        }
+        free(start_request);
     }
 }
 
--- a/src/server/daemon/sessionhandler.h	Sat Aug 24 12:13:01 2024 +0200
+++ b/src/server/daemon/sessionhandler.h	Sat Aug 24 18:34:13 2024 +0200
@@ -158,7 +158,7 @@
 
 void evt_request_timeout(EventHandler *h, EVWatchList *item);
 
-int evt_add_request_timeout(EventHandler *h, Event *event);
+int evt_add_request(EventHandler *h, Event *event);
 
 void evt_enq_conn(SessionHandler *handler, Connection *conn);
 

mercurial