Improve at exit cleanup functions

Now they are run in a defined order not based on
the order of initialization
This commit is contained in:
Kovid Goyal
2021-04-01 11:48:36 +05:30
parent 0ec7e6c36f
commit 55dc354e68
11 changed files with 70 additions and 34 deletions

23
kitty/cleanup.c Normal file
View File

@@ -0,0 +1,23 @@
/*
* cleanup.c
* Copyright (C) 2021 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#include "cleanup.h"
kitty_cleanup_at_exit_func exit_funcs[NUM_CLEANUP_FUNCS] = {0};
void
register_at_exit_cleanup_func(AtExitCleanupFunc which, kitty_cleanup_at_exit_func func) {
if (which < NUM_CLEANUP_FUNCS) exit_funcs[which] = func;
}
void
run_at_exit_cleanup_functions(void) {
for (unsigned i = 0; i < NUM_CLEANUP_FUNCS; i++) {
if (exit_funcs[i]) exit_funcs[i]();
}
}

25
kitty/cleanup.h Normal file
View File

@@ -0,0 +1,25 @@
/*
* Copyright (C) 2021 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#pragma once
typedef void (*kitty_cleanup_at_exit_func)(void);
typedef enum {
STATE_CLEANUP_FUNC,
GLFW_CLEANUP_FUNC,
DESKTOP_CLEANUP_FUNC,
FREETYPE_CLEANUP_FUNC,
CORE_TEXT_CLEANUP_FUNC,
COCOA_CLEANUP_FUNC,
PNG_READER_CLEANUP_FUNC,
FONTCONFIG_CLEANUP_FUNC,
NUM_CLEANUP_FUNCS
} AtExitCleanupFunc;
void register_at_exit_cleanup_func(AtExitCleanupFunc which, kitty_cleanup_at_exit_func func);
void run_at_exit_cleanup_functions(void);

View File

@@ -7,6 +7,7 @@
#include "state.h"
#include "cleanup.h"
#include "monotonic.h"
#include <Cocoa/Cocoa.h>
#ifndef KITTY_USE_DEPRECATED_MACOS_NOTIFICATION_API
@@ -656,9 +657,6 @@ bool
init_cocoa(PyObject *module) {
memset(&global_shortcuts, 0, sizeof(global_shortcuts));
if (PyModule_AddFunctions(module, module_methods) != 0) return false;
if (Py_AtExit(cleanup) != 0) {
PyErr_SetString(PyExc_RuntimeError, "Failed to register the cocoa_window at exit handler");
return false;
}
register_at_exit_cleanup_func(COCOA_CLEANUP_FUNC, cleanup);
return true;
}

View File

@@ -6,6 +6,7 @@
*/
#include "state.h"
#include "cleanup.h"
#include "fonts.h"
#include "unicode-data.h"
#include <structmember.h>
@@ -608,10 +609,7 @@ init_CoreText(PyObject *module) {
if (PyType_Ready(&CTFace_Type) < 0) return 0;
if (PyModule_AddObject(module, "CTFace", (PyObject *)&CTFace_Type) != 0) return 0;
if (PyModule_AddFunctions(module, module_methods) != 0) return 0;
if (Py_AtExit(finalize) != 0) {
PyErr_SetString(PyExc_RuntimeError, "Failed to register the CoreText at exit handler");
return false;
}
register_at_exit_cleanup_func(CORE_TEXT_CLEANUP_FUNC, finalize);
return 1;
}

View File

@@ -12,6 +12,7 @@
#undef _DARWIN_C_SOURCE
#endif
#include "data-types.h"
#include "cleanup.h"
#include "safe-wrappers.h"
#include "control-codes.h"
#include "wcwidth-std.h"
@@ -226,6 +227,10 @@ PyInit_fast_data_types(void) {
m = PyModule_Create(&module);
if (m == NULL) return NULL;
if (Py_AtExit(run_at_exit_cleanup_functions) != 0) {
PyErr_SetString(PyExc_RuntimeError, "Failed to register the atexit cleanup handler");
return NULL;
}
init_monotonic();
if (!init_logging(m)) return NULL;
@@ -237,6 +242,7 @@ PyInit_fast_data_types(void) {
if (!init_child_monitor(m)) return NULL;
if (!init_ColorProfile(m)) return NULL;
if (!init_Screen(m)) return NULL;
if (!init_glfw(m)) return NULL;
if (!init_child(m)) return NULL;
if (!init_state(m)) return NULL;
if (!init_keys(m)) return NULL;
@@ -256,7 +262,6 @@ PyInit_fast_data_types(void) {
if (!init_freetype_render_ui_text(m)) return NULL;
#endif
if (!init_fonts(m)) return NULL;
if (!init_glfw(m)) return NULL;
PyModule_AddIntConstant(m, "BOLD", BOLD_SHIFT);
PyModule_AddIntConstant(m, "ITALIC", ITALIC_SHIFT);

View File

@@ -6,6 +6,7 @@
*/
#include "data-types.h"
#include "cleanup.h"
#include <dlfcn.h>
#define FUNC(name, restype, ...) typedef restype (*name##_func)(__VA_ARGS__); static name##_func name = NULL
@@ -174,9 +175,6 @@ finalize(void) {
bool
init_desktop(PyObject *m) {
if (PyModule_AddFunctions(m, module_methods) != 0) return false;
if (Py_AtExit(finalize) != 0) {
PyErr_SetString(PyExc_RuntimeError, "Failed to register the desktop.c at exit handler");
return false;
}
register_at_exit_cleanup_func(DESKTOP_CLEANUP_FUNC, finalize);
return true;
}

View File

@@ -6,6 +6,7 @@
*/
#include "state.h"
#include "cleanup.h"
#include "lineops.h"
#include "fonts.h"
#include <fontconfig/fontconfig.h>
@@ -339,10 +340,7 @@ init_fontconfig_library(PyObject *module) {
PyErr_SetString(PyExc_RuntimeError, "Failed to initialize the fontconfig library");
return false;
}
if (Py_AtExit(FcFini) != 0) {
PyErr_SetString(PyExc_RuntimeError, "Failed to register the fontconfig library at exit handler");
return false;
}
register_at_exit_cleanup_func(FONTCONFIG_CLEANUP_FUNC, FcFini);
if (PyModule_AddFunctions(module, module_methods) != 0) return false;
PyModule_AddIntMacro(module, FC_WEIGHT_REGULAR);
PyModule_AddIntMacro(module, FC_WEIGHT_MEDIUM);

View File

@@ -6,6 +6,7 @@
*/
#include "fonts.h"
#include "cleanup.h"
#include "state.h"
#include <math.h>
#include <structmember.h>
@@ -737,10 +738,7 @@ init_freetype_library(PyObject *m) {
set_freetype_error("Failed to initialize FreeType library, with error:", error);
return false;
}
if (Py_AtExit(free_freetype) != 0) {
PyErr_SetString(FreeType_Exception, "Failed to register the freetype library at exit handler");
return false;
}
register_at_exit_cleanup_func(FREETYPE_CLEANUP_FUNC, free_freetype);
return true;
}

View File

@@ -5,6 +5,7 @@
*/
#include "state.h"
#include "cleanup.h"
#include "fonts.h"
#include "monotonic.h"
#include "charsets.h"
@@ -1426,10 +1427,7 @@ void cleanup_glfw(void) {
bool
init_glfw(PyObject *m) {
if (PyModule_AddFunctions(m, module_methods) != 0) return false;
if (Py_AtExit(cleanup_glfw) != 0) {
PyErr_SetString(PyExc_RuntimeError, "Failed to register the glfw exit handler");
return false;
}
register_at_exit_cleanup_func(GLFW_CLEANUP_FUNC, cleanup_glfw);
#define ADDC(n) if(PyModule_AddIntConstant(m, #n, n) != 0) return false;
ADDC(GLFW_RELEASE);
ADDC(GLFW_PRESS);

View File

@@ -6,6 +6,7 @@
*/
#include "png-reader.h"
#include "cleanup.h"
#include "state.h"
#include <lcms2.h>
@@ -167,10 +168,6 @@ unload(void) {
bool
init_png_reader(PyObject *module) {
if (PyModule_AddFunctions(module, module_methods) != 0) return false;
if (Py_AtExit(unload) != 0) {
PyErr_SetString(PyExc_RuntimeError, "Failed to register the PNG library at exit handler");
return false;
}
register_at_exit_cleanup_func(PNG_READER_CLEANUP_FUNC, unload);
return true;
}

View File

@@ -6,6 +6,7 @@
*/
#include "state.h"
#include "cleanup.h"
#include <math.h>
GlobalState global_state = {{0}};
@@ -1251,10 +1252,7 @@ init_state(PyObject *module) {
PyModule_AddIntConstant(module, "IMPERATIVE_CLOSE_REQUESTED", IMPERATIVE_CLOSE_REQUESTED);
PyModule_AddIntConstant(module, "NO_CLOSE_REQUESTED", NO_CLOSE_REQUESTED);
PyModule_AddIntConstant(module, "CLOSE_BEING_CONFIRMED", CLOSE_BEING_CONFIRMED);
if (Py_AtExit(finalize) != 0) {
PyErr_SetString(PyExc_RuntimeError, "Failed to register the state at exit handler");
return false;
}
register_at_exit_cleanup_func(STATE_CLEANUP_FUNC, finalize);
return true;
}
// }}}