Run at exit cleanup functions explicitly instead of relying on the ever unreliable python interpreter to do it

This commit is contained in:
Kovid Goyal 2025-02-10 15:06:18 +05:30
parent 5ebdfe17d9
commit 82d4234d9a
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C
5 changed files with 15 additions and 0 deletions

View file

@ -6,6 +6,7 @@
*/
#include "cleanup.h"
#include <unistd.h>
kitty_cleanup_at_exit_func exit_funcs[NUM_CLEANUP_FUNCS] = {0};
@ -19,5 +20,6 @@ void
run_at_exit_cleanup_functions(void) {
for (unsigned i = 0; i < NUM_CLEANUP_FUNCS; i++) {
if (exit_funcs[i]) exit_funcs[i]();
exit_funcs[i] = NULL;
}
}

View file

@ -605,6 +605,11 @@ py_timed_debug_print(PyObject *self UNUSED, PyObject *args) {
Py_RETURN_NONE;
}
static PyObject*
py_run_atexit_cleanup_functions(PyObject *self UNUSED, PyObject *args UNUSED) {
run_at_exit_cleanup_functions();
Py_RETURN_NONE;
}
static PyMethodDef module_methods[] = {
METHODB(replace_c0_codes_except_nl_space_tab, METH_O),
@ -632,6 +637,7 @@ static PyMethodDef module_methods[] = {
{"monotonic", (PyCFunction)py_monotonic, METH_NOARGS, ""},
{"timed_debug_print", (PyCFunction)py_timed_debug_print, METH_VARARGS, ""},
{"find_in_memoryview", (PyCFunction)find_in_memoryview, METH_VARARGS, ""},
{"run_at_exit_cleanup_functions", (PyCFunction)py_run_atexit_cleanup_functions, METH_NOARGS, ""},
#ifdef __APPLE__
METHODB(user_cache_dir, METH_NOARGS),
METHODB(process_group_map, METH_NOARGS),

View file

@ -1723,6 +1723,7 @@ def set_redirect_keys_to_overlay(os_window_id: int, tab_id: int, window_id: int,
def buffer_keys_in_window(os_window_id: int, tab_id: int, window_id: int, enabled: bool = True) -> bool: ...
def sprite_idx_to_pos(idx: int, xnum: int, ynum: int) -> tuple[int, int, int]: ...
def render_box_char(ch: int, width: int, height: int, scale: float = 1.0, dpi_x: float = 96.0, dpi_y: float = 96.0) -> bytes: ...
def run_at_exit_cleanup_functions() -> None: ...
class MousePosition(TypedDict):
cell_x: int

View file

@ -466,5 +466,6 @@ int main(int argc, char *argv[], char* envp[]) {
RunData run_data = {.exe = exe, .exe_dir = exe_dir, .lib_dir = lib, .argc = argc, .argv = argv, .lc_ctype = lc_ctype};
ret = run_embedded(&run_data);
single_instance_main(-1, NULL, NULL);
Py_FinalizeEx();
return ret;
}

View file

@ -40,6 +40,7 @@ from .fast_data_types import (
glfw_terminate,
load_png_data,
mask_kitty_signals_process_wide,
run_at_exit_cleanup_functions,
set_custom_cursor,
set_default_window_icon,
set_options,
@ -537,3 +538,7 @@ def main() -> None:
tb = traceback.format_exc()
log_error(tb)
raise SystemExit(1)
finally:
# we cant rely on this running during module unloading of fast_data_types as Python fails
# to unload the module, due to reference cycles, I am guessing.
run_at_exit_cleanup_functions()