diff --git a/kitty/child-monitor.c b/kitty/child-monitor.c index a1de8ffef..53cb73530 100644 --- a/kitty/child-monitor.c +++ b/kitty/child-monitor.c @@ -662,37 +662,11 @@ hangup(pid_t pid) { } } -static pid_t pid_buf[MAX_CHILDREN] = {0}; -static size_t pid_buf_pos = 0; -static pthread_t reap_thread; - - -static void* -reap(void *pid_p) { - set_thread_name("KittyReapChild"); - pid_t pid = *((pid_t*)pid_p); - while(true) { - pid_t ret = waitpid(pid, NULL, 0); - if (ret != pid) { - if (errno == EINTR) continue; - fprintf(stderr, "Failed to reap child process with pid: %d with error: %s\n", pid, strerror(errno)); - } - break; - } - return 0; -} static inline void cleanup_child(ssize_t i) { close(children[i].fd); hangup(children[i].pid); - pid_buf[pid_buf_pos] = children[i].pid; - if (waitpid(pid_buf[pid_buf_pos], NULL, WNOHANG) != pid_buf[pid_buf_pos]) { - errno = 0; - int ret = pthread_create(&reap_thread, NULL, reap, pid_buf + pid_buf_pos); - if (ret != 0) perror("Failed to create thread to reap child"); - } - pid_buf_pos = (pid_buf_pos + 1) % MAX_CHILDREN; } diff --git a/kitty/main.py b/kitty/main.py index 264b4559b..99c4039de 100644 --- a/kitty/main.py +++ b/kitty/main.py @@ -5,6 +5,7 @@ import argparse import locale import os +import signal import sys from contextlib import contextmanager from gettext import gettext as _ @@ -235,11 +236,11 @@ def setup_profiling(args): exe = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'kitty-profile') cg = '/tmp/kitty-profile.callgrind' print('Post processing profile data for', exe, '...') - subprocess.check_call(['pprof', '--callgrind', exe, '/tmp/kitty-profile.log'], stdout=open(cg, 'wb')) + subprocess.call(['pprof', '--callgrind', exe, '/tmp/kitty-profile.log'], stdout=open(cg, 'wb')) try: subprocess.Popen(['kcachegrind', cg]) except FileNotFoundError: - subprocess.check_call(['pprof', '--text', exe, '/tmp/kitty-profile.log']) + subprocess.call(['pprof', '--text', exe, '/tmp/kitty-profile.log']) print('To view the graphical call data, use: kcachegrind', cg) @@ -286,6 +287,9 @@ def main(): raise SystemExit('GLFW initialization failed') try: with setup_profiling(args): + # Let the kernel take care of reaping zombie child processes + signal.signal(signal.SIGCHLD, signal.SIG_IGN) run_app(opts, args) + signal.signal(signal.SIGCHLD, signal.SIG_DFL) finally: glfw_terminate() diff --git a/kitty/utils.py b/kitty/utils.py index 314c1b4bd..2596db2b6 100644 --- a/kitty/utils.py +++ b/kitty/utils.py @@ -165,7 +165,8 @@ def get_primary_selection(): return '' # There is no primary selection on OS X g = selection_clipboard_funcs()[0] if g is None: - ans = subprocess.check_output(['xsel', '-p'], stderr=subprocess.DEVNULL, stdin=subprocess.DEVNULL).decode('utf-8') + # We cannot use check_output as we set SIGCHLD to SIG_IGN + ans = subprocess.Popen(['xsel', '-p'], stderr=subprocess.DEVNULL, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE).stdout.read().decode('utf-8') if ans: # Without this for some reason repeated pastes dont work set_primary_selection(ans) @@ -192,7 +193,7 @@ def open_cmd(cmd, arg=None): if arg is not None: cmd = list(cmd) cmd.append(arg) - return subprocess.Popen(cmd, stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).wait() + return subprocess.Popen(cmd, stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) def open_url(url, program='default'):