Simply reaping of dead processes

Let the kernel do the reaping, since we do not care about the exit code
anyway. This should also fix #151.
This commit is contained in:
Kovid Goyal 2017-10-22 17:42:49 +05:30
parent bdb6723564
commit d239db8492
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 9 additions and 30 deletions

View File

@ -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 static inline void
cleanup_child(ssize_t i) { cleanup_child(ssize_t i) {
close(children[i].fd); close(children[i].fd);
hangup(children[i].pid); 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;
} }

View File

@ -5,6 +5,7 @@
import argparse import argparse
import locale import locale
import os import os
import signal
import sys import sys
from contextlib import contextmanager from contextlib import contextmanager
from gettext import gettext as _ 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') exe = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'kitty-profile')
cg = '/tmp/kitty-profile.callgrind' cg = '/tmp/kitty-profile.callgrind'
print('Post processing profile data for', exe, '...') 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: try:
subprocess.Popen(['kcachegrind', cg]) subprocess.Popen(['kcachegrind', cg])
except FileNotFoundError: 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) print('To view the graphical call data, use: kcachegrind', cg)
@ -286,6 +287,9 @@ def main():
raise SystemExit('GLFW initialization failed') raise SystemExit('GLFW initialization failed')
try: try:
with setup_profiling(args): 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) run_app(opts, args)
signal.signal(signal.SIGCHLD, signal.SIG_DFL)
finally: finally:
glfw_terminate() glfw_terminate()

View File

@ -165,7 +165,8 @@ def get_primary_selection():
return '' # There is no primary selection on OS X return '' # There is no primary selection on OS X
g = selection_clipboard_funcs()[0] g = selection_clipboard_funcs()[0]
if g is None: 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: if ans:
# Without this for some reason repeated pastes dont work # Without this for some reason repeated pastes dont work
set_primary_selection(ans) set_primary_selection(ans)
@ -192,7 +193,7 @@ def open_cmd(cmd, arg=None):
if arg is not None: if arg is not None:
cmd = list(cmd) cmd = list(cmd)
cmd.append(arg) 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'): def open_url(url, program='default'):