# HG changeset patch # User Olaf Wintermann # Date 1723751217 -7200 # Node ID 280bf87c8689d99cf4dfcd0634fd49fcfad766c3 # Parent 5494c28db8960c7d94dc94ccb74f83bf01e6dc07 add functions to stop event handlers diff -r 5494c28db896 -r 280bf87c8689 src/server/daemon/event.c --- a/src/server/daemon/event.c Tue Aug 13 20:08:13 2024 +0200 +++ b/src/server/daemon/event.c Thu Aug 15 21:46:57 2024 +0200 @@ -78,6 +78,13 @@ return ret; } +void evhandler_close(EVHandler *h) { + for(int i=0;inumins;i++) { + ev_instance_close(h->instances[i]); + } + h->numins = 0; +} + /* * checks if there is at least one event handler and a default handler * if necessary, check_event_handler_cfg() creates a default event handler diff -r 5494c28db896 -r 280bf87c8689 src/server/daemon/event.h --- a/src/server/daemon/event.h Tue Aug 13 20:08:13 2024 +0200 +++ b/src/server/daemon/event.h Thu Aug 15 21:46:57 2024 +0200 @@ -89,6 +89,7 @@ } EventHandler; +void evhandler_close(EVHandler *h); int create_event_handler(EventHandlerConfig *cfg); @@ -107,6 +108,8 @@ /* implementation in event_$platform */ EVHandler* evhandler_create(EventHandlerConfig *cfg); +void ev_instance_close(EventHandler *h); +void ev_instance_shutdown(EventHandler *h); int ev_pollin(EventHandler *h, int fd, Event *event); int ev_pollout(EventHandler *h, int fd, Event *event); diff -r 5494c28db896 -r 280bf87c8689 src/server/daemon/event_bsd.c --- a/src/server/daemon/event_bsd.c Tue Aug 13 20:08:13 2024 +0200 +++ b/src/server/daemon/event_bsd.c Thu Aug 15 21:46:57 2024 +0200 @@ -64,6 +64,19 @@ return ev; } +static volatile int ev_close = 0; + +void ev_instance_close(EventHandler *h) { + EventHandlerKqueue *ev = (EventHandlerKqueue*)h; + close(ev->kqueue); + ev_close = 1; +} + +// 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(EventHandlerKqueue *ev) { EventHandler *h = (EventHandler*)ev; @@ -81,7 +94,12 @@ // wait for events int nev = kevent(ev->kqueue, changes, numchanges, events, EV_MAX_EVENTS, &timeout); if(nev == -1) { - log_ereport(LOG_FAILURE, "kevent: %s", strerror(errno)); + if(errno != EINTR) { + if(!ev_close) { + log_ereport(LOG_CATASTROPHE, "kevent failed: %s", strerror(errno)); + } + break; + } continue; } @@ -140,6 +158,8 @@ } } } + } else if(event == &shutdown_event) { + ev_instance_close(h); } } // call event finish handlers @@ -156,6 +176,8 @@ nsapi_saf_return(ret.sn, ret.rq, ret.ret); } } + + free(ev); } int ev_pollin(EventHandler *h, int fd, Event *event) { diff -r 5494c28db896 -r 280bf87c8689 src/server/daemon/event_linux.c --- 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) { diff -r 5494c28db896 -r 280bf87c8689 src/server/daemon/event_linux.h --- a/src/server/daemon/event_linux.h Tue Aug 13 20:08:13 2024 +0200 +++ b/src/server/daemon/event_linux.h Thu Aug 15 21:46:57 2024 +0200 @@ -108,6 +108,8 @@ int ev_convert2sys_events(int events); +void ev_queue_free(EventQueue *queue); + #ifdef __cplusplus } #endif diff -r 5494c28db896 -r 280bf87c8689 src/server/daemon/event_solaris.c --- a/src/server/daemon/event_solaris.c Tue Aug 13 20:08:13 2024 +0200 +++ b/src/server/daemon/event_solaris.c Thu Aug 15 21:46:57 2024 +0200 @@ -64,6 +64,20 @@ return ev; } +static volatile int ev_close = 0; + +void ev_instance_close(EventHandler *h) { + EventHandlerSolaris *ev = (EventHandlerSolaris*)h; + close(ev->port); + ev_close = 1; +} + +// 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(EventHandlerSolaris *ev) { EventHandler *h = (EventHandler*)ev; @@ -78,8 +92,12 @@ uint_t nev = 1; int ret = port_getn(ev->port, events, EV_MAX_EVENTS, &nev, &timeout); if(ret == -1) { - // TODO: check for error - perror("port_getn"); + if(errno != EINTR && errno != ETIME) { + if(!ev_close) { + log_ereport(LOG_CATASTROPHE, "port_getn failed: %s", strerror(errno)); + } + break; + } continue; } @@ -120,6 +138,8 @@ } else if(event->finish) { event->finish(h, event); } + } else if(event == &shutdown_event) { + ev_instance_close(h); } } } @@ -137,6 +157,8 @@ nsapi_saf_return(ret.sn, ret.rq, ret.ret); } } + + free(ev); } int ev_convert2sys_events(int events) {