From 7f19424f2d0d7155f314113ce5f868ac672f5c44 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 13 Dec 2017 22:20:11 +0530 Subject: [PATCH] Fix for kitty sometimes not detecting child death on macOS --- kitty/child-monitor.c | 16 ++++++++-------- kitty/data-types.c | 3 +++ kitty/data-types.h | 1 + 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/kitty/child-monitor.c b/kitty/child-monitor.c index 7cc6a085b..3b8bb99a0 100644 --- a/kitty/child-monitor.c +++ b/kitty/child-monitor.c @@ -191,13 +191,13 @@ dealloc(ChildMonitor* self) { close(signal_fds[1]); } -static void -wakeup_io_loop() { +void +wakeup_io_loop(bool in_signal_handler) { while(true) { ssize_t ret = write(wakeup_fds[1], "w", 1); if (ret < 0) { if (errno == EINTR) continue; - perror("Failed to write to wakeup fd with error"); + if (!in_signal_handler) perror("Failed to write to wakeup fd with error"); } break; } @@ -230,7 +230,7 @@ join(ChildMonitor *self) { static PyObject * wakeup(ChildMonitor UNUSED *self) { #define wakeup_doc "wakeup() -> wakeup the ChildMonitor I/O thread, forcing it to exit from poll() if it is waiting there." - wakeup_io_loop(); + wakeup_io_loop(false); Py_RETURN_NONE; } @@ -249,7 +249,7 @@ add_child(ChildMonitor *self, PyObject *args) { INCREF_CHILD(add_queue[add_queue_count]); add_queue_count++; children_mutex(unlock); - wakeup_io_loop(); + wakeup_io_loop(false); Py_RETURN_NONE; } @@ -281,7 +281,7 @@ schedule_write_to_child(unsigned long id, const char *data, size_t sz) { screen->write_buf = PyMem_RawRealloc(screen->write_buf, screen->write_buf_sz); if (screen->write_buf == NULL) { fatal("Out of memory."); } } - if (screen->write_buf_used) wakeup_io_loop(); + if (screen->write_buf_used) wakeup_io_loop(false); screen_mutex(unlock, write); break; } @@ -316,7 +316,7 @@ do_parse(ChildMonitor *self, Screen *screen, double now) { double time_since_new_input = now - screen->new_input_at; if (time_since_new_input >= OPT(input_delay)) { parse_func(screen, self->dump_callback); - if (screen->read_buf_sz >= READ_BUF_SZ) wakeup_io_loop(); // Ensure the read fd has POLLIN set + if (screen->read_buf_sz >= READ_BUF_SZ) wakeup_io_loop(false); // Ensure the read fd has POLLIN set screen->read_buf_sz = 0; screen->new_input_at = 0; } else set_maximum_wait(OPT(input_delay) - time_since_new_input); @@ -392,7 +392,7 @@ mark_child_for_close(ChildMonitor *self, id_type window_id) { } } children_mutex(unlock); - wakeup_io_loop(); + wakeup_io_loop(false); } diff --git a/kitty/data-types.c b/kitty/data-types.c index fbd5954f1..d201da6fd 100644 --- a/kitty/data-types.c +++ b/kitty/data-types.c @@ -108,6 +108,9 @@ handle_sigchld(int UNUSED signum, siginfo_t *sinfo, void UNUSED *unused) { if (errno != EINTR) break; } else break; } + // wakeup I/O loop as without this on macOS sometimes poll() does not detect the fd close, so + // kitty does not detect child death. + wakeup_io_loop(true); errno = sav_errno; } diff --git a/kitty/data-types.h b/kitty/data-types.h index 16edf6905..556ce2fbb 100644 --- a/kitty/data-types.h +++ b/kitty/data-types.h @@ -275,6 +275,7 @@ void change_wcwidth(bool use9); void set_mouse_cursor(MouseShape); void mouse_event(int, int); void focus_in_event(); +void wakeup_io_loop(bool); void scroll_event(double, double); void fake_scroll(bool); void set_special_key_combo(int glfw_key, int mods);