Block handled signals early in startup before glfw is initialized to ensure that if the graphics libraries start a thread behind our backs, that threads defaults to haveing the signals blocked unless the library explicitly unblocks them. See #4636
This commit is contained in:
parent
94410f2866
commit
9cb0e4d09d
@ -120,6 +120,34 @@ set_maximum_wait(monotonic_t val) {
|
|||||||
if (val >= 0 && (val < maximum_wait || maximum_wait < 0)) maximum_wait = val;
|
if (val >= 0 && (val < maximum_wait || maximum_wait < 0)) maximum_wait = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define KITTY_HANDLED_SIGNALS SIGINT, SIGHUP, SIGTERM, SIGCHLD, SIGUSR1, SIGUSR2, 0
|
||||||
|
|
||||||
|
static void
|
||||||
|
mask_variadic_signals(int sentinel, ...) {
|
||||||
|
// only need to mask signals when using SIGNAL_FD as signal actions are inherited by threads
|
||||||
|
// and only on Linux do we have reports of signals not being handled presumably because libwayland starts
|
||||||
|
// a thread behind our backs. See https://github.com/kovidgoyal/kitty/issues/4636
|
||||||
|
#ifdef HAS_SIGNAL_FD
|
||||||
|
sigset_t signals;
|
||||||
|
sigemptyset(&signals);
|
||||||
|
va_list valist;
|
||||||
|
va_start(valist, sentinel);
|
||||||
|
while (true) {
|
||||||
|
int sig = va_arg(valist, int);
|
||||||
|
if (sig == sentinel) break;
|
||||||
|
sigaddset(&signals, sig);
|
||||||
|
}
|
||||||
|
va_end(valist);
|
||||||
|
sigprocmask(SIG_BLOCK, &signals, NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject*
|
||||||
|
mask_kitty_signals_process_wide(PyObject *self UNUSED, PyObject *a UNUSED) {
|
||||||
|
mask_variadic_signals(0, KITTY_HANDLED_SIGNALS);
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
|
new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
|
||||||
ChildMonitor *self;
|
ChildMonitor *self;
|
||||||
@ -138,7 +166,7 @@ new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
self = (ChildMonitor *)type->tp_alloc(type, 0);
|
self = (ChildMonitor *)type->tp_alloc(type, 0);
|
||||||
if (!init_loop_data(&self->io_loop_data, SIGINT, SIGHUP, SIGTERM, SIGCHLD, SIGUSR1, SIGUSR2, 0)) return PyErr_SetFromErrno(PyExc_OSError);
|
if (!init_loop_data(&self->io_loop_data, KITTY_HANDLED_SIGNALS)) return PyErr_SetFromErrno(PyExc_OSError);
|
||||||
self->talk_fd = talk_fd;
|
self->talk_fd = talk_fd;
|
||||||
self->listen_fd = listen_fd;
|
self->listen_fd = listen_fd;
|
||||||
self->prewarm_fd = prewarm_fd;
|
self->prewarm_fd = prewarm_fd;
|
||||||
@ -1829,6 +1857,7 @@ static PyMethodDef module_methods[] = {
|
|||||||
METHODB(monitor_pid, METH_VARARGS),
|
METHODB(monitor_pid, METH_VARARGS),
|
||||||
METHODB(send_data_to_peer, METH_VARARGS),
|
METHODB(send_data_to_peer, METH_VARARGS),
|
||||||
METHODB(cocoa_set_menubar_title, METH_VARARGS),
|
METHODB(cocoa_set_menubar_title, METH_VARARGS),
|
||||||
|
METHODB(mask_kitty_signals_process_wide, METH_NOARGS),
|
||||||
{"sigqueue", (PyCFunction)sig_queue, METH_VARARGS, ""},
|
{"sigqueue", (PyCFunction)sig_queue, METH_VARARGS, ""},
|
||||||
{NULL} /* Sentinel */
|
{NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1498,3 +1498,4 @@ def unicode_database_version() -> Tuple[int, int, int]: ...
|
|||||||
def wrapped_kitten_names() -> List[str]: ...
|
def wrapped_kitten_names() -> List[str]: ...
|
||||||
def expand_ansi_c_escapes(test: str) -> str: ...
|
def expand_ansi_c_escapes(test: str) -> str: ...
|
||||||
def update_tab_bar_edge_colors(os_window_id: int) -> bool: ...
|
def update_tab_bar_edge_colors(os_window_id: int) -> bool: ...
|
||||||
|
def mask_kitty_signals_process_wide() -> None: ...
|
||||||
|
|||||||
@ -21,8 +21,9 @@ from .constants import (
|
|||||||
)
|
)
|
||||||
from .fast_data_types import (
|
from .fast_data_types import (
|
||||||
GLFW_IBEAM_CURSOR, GLFW_MOD_ALT, GLFW_MOD_SHIFT, SingleKey, create_os_window,
|
GLFW_IBEAM_CURSOR, GLFW_MOD_ALT, GLFW_MOD_SHIFT, SingleKey, create_os_window,
|
||||||
free_font_data, glfw_init, glfw_terminate, load_png_data, set_custom_cursor,
|
free_font_data, glfw_init, glfw_terminate, load_png_data,
|
||||||
set_default_window_icon, set_options,
|
mask_kitty_signals_process_wide, set_custom_cursor, set_default_window_icon,
|
||||||
|
set_options,
|
||||||
)
|
)
|
||||||
from .fonts.box_drawing import set_scale
|
from .fonts.box_drawing import set_scale
|
||||||
from .fonts.render import set_font_family
|
from .fonts.render import set_font_family
|
||||||
@ -102,6 +103,7 @@ def init_glfw_module(glfw_module: str, debug_keyboard: bool = False, debug_rende
|
|||||||
|
|
||||||
|
|
||||||
def init_glfw(opts: Options, debug_keyboard: bool = False, debug_rendering: bool = False) -> str:
|
def init_glfw(opts: Options, debug_keyboard: bool = False, debug_rendering: bool = False) -> str:
|
||||||
|
mask_kitty_signals_process_wide()
|
||||||
glfw_module = 'cocoa' if is_macos else ('wayland' if is_wayland(opts) else 'x11')
|
glfw_module = 'cocoa' if is_macos else ('wayland' if is_wayland(opts) else 'x11')
|
||||||
init_glfw_module(glfw_module, debug_keyboard, debug_rendering)
|
init_glfw_module(glfw_module, debug_keyboard, debug_rendering)
|
||||||
return glfw_module
|
return glfw_module
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user