src/server/daemon/event_linux.c

changeset 547
280bf87c8689
parent 545
720893ec7d48
child 552
4ed0e46aa9dc
--- a/src/server/daemon/event_linux.c	Tue Aug 13 20:08:13 2024 +0200
+++ b/src/server/daemon/event_linux.c	Thu Aug 15 21:46:57 2024 +0200
@@ -103,6 +103,20 @@
     return ev;
 }
 
+static volatile int ev_close = 0;
+
+void ev_instance_close(EventHandler *h) {
+    EventHandlerLinux *ev = (EventHandlerLinux*)h;
+    ev_close = 1;
+    close(ev->ep);
+}
+
+// unique event addr that indicates shutdown
+static Event shutdown_event;
+void ev_instance_shutdown(EventHandler *h) {
+    event_send(h, &shutdown_event);
+}
+
 void ev_handle_events(EventHandlerLinux *ev) {
     EventHandler *h = (EventHandler*)ev;
     int ep = ev->ep;
@@ -113,7 +127,8 @@
     size_t queue_len = 0;
     
     int loop_ctn = 0;
-    for(;;) {
+    int ev_shutdown = 0;
+    while(!ev_shutdown) {
         // if ev->event_queue contains events, we process them first
         // otherwise we get events from epoll
         int ret = 0;
@@ -150,8 +165,13 @@
         } else {
             // wait for events
             ret = epoll_wait(ep, events, EV_MAX_EVENTS, EV_IDLE_TIMEOUT * 1000);
-            if(ret == -1 && errno != EINTR) {
-                log_ereport(LOG_FAILURE, "epoll_wait failed: %s", strerror(errno));
+            if(ret == -1) {
+                if(errno != EINTR) {
+                    if(!ev_close) {
+                        log_ereport(LOG_CATASTROPHE, "epoll_wait failed: %s", strerror(errno));
+                    }
+                    break;
+                }
                 continue;
             }
         }
@@ -211,6 +231,8 @@
                         }
                     }
                 }
+            } else if(event == &shutdown_event) {
+                ev_instance_close(h);
             }
         }
         // call event finish handlers
@@ -232,6 +254,21 @@
             loop_ctn = 0;
         }
     }
+    
+    // epoll fd is already closed
+    
+    ev_queue_free(ev->queue_begin);
+    pthread_mutex_destroy(&ev->queue_lock);
+    close(ev->event_fd);
+    free(ev);
+}
+
+void ev_queue_free(EventQueue *queue) {
+    while(queue) {
+        EventQueue *next = queue->next;
+        free(queue);
+        queue = next;
+    }
 }
 
 int ev_convert2sys_events(int events) {

mercurial