From c4d73c306b87e32acba3a77f933da72ac5604659 Mon Sep 17 00:00:00 2001 From: Wayne Zhang Date: Thu, 7 Jul 2022 18:21:37 -0400 Subject: [PATCH] zos: delay signal handling until after normal i/o (#3643) Port the changes made to AIX and other unix systems in #611 to z/OS. Defers the signal watcher that is used for process management until after the dispatch of regular i/o watchers. Refs: https://github.com/libuv/libuv/pull/611 Co-authored-by: Igor Todorovski --- src/unix/os390.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/unix/os390.c b/src/unix/os390.c index e8e388b1..3b16318c 100644 --- a/src/unix/os390.c +++ b/src/unix/os390.c @@ -807,6 +807,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { struct epoll_event* pe; struct epoll_event e; uv__os390_epoll* ep; + int have_signals; int real_timeout; QUEUE* q; uv__io_t* w; @@ -869,6 +870,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { count = 48; /* Benchmarks suggest this gives the best throughput. */ real_timeout = timeout; int nevents = 0; + have_signals = 0; if (uv__get_internal_fields(loop)->flags & UV_METRICS_IDLE_TIME) { reset_timeout = 1; @@ -983,19 +985,35 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { pe->events |= w->pevents & (POLLIN | POLLOUT); if (pe->events != 0) { - uv__metrics_update_idle_time(loop); - w->cb(loop, w, pe->events); + /* Run signal watchers last. This also affects child process watchers + * because those are implemented in terms of signal watchers. + */ + if (w == &loop->signal_io_watcher) { + have_signals = 1; + } else { + uv__metrics_update_idle_time(loop); + w->cb(loop, w, pe->events); + } nevents++; } } - loop->watchers[loop->nwatchers] = NULL; - loop->watchers[loop->nwatchers + 1] = NULL; if (reset_timeout != 0) { timeout = user_timeout; reset_timeout = 0; } + if (have_signals != 0) { + uv__metrics_update_idle_time(loop); + loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN); + } + + loop->watchers[loop->nwatchers] = NULL; + loop->watchers[loop->nwatchers + 1] = NULL; + + if (have_signals != 0) + return; /* Event loop should cycle now so don't poll again. */ + if (nevents != 0) { if (nfds == ARRAY_SIZE(events) && --count != 0) { /* Poll for more events but don't block this time. */