--- 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) {