WM: restore support for calling WM_exit with a NULL context

While currently the context is never null, a null context is meant
to be supported. Apply minor changes needed for this to work again.
This commit is contained in:
Campbell Barton
2023-05-30 14:51:59 +10:00
parent cb0c4f04d4
commit d979d535a6
2 changed files with 30 additions and 10 deletions

View File

@@ -100,6 +100,13 @@ void WM_init_input_devices(void);
*/
void WM_init(struct bContext *C, int argc, const char **argv);
/**
* Main exit function (implementation).
*
* \note Unlike #WM_exit this does not call `exit()`,
* the caller is responsible for this.
*
* \param C: The context or null, a null context implies `do_user_exit_actions == false` &
* prevents some editor-exit operations from running.
* \param do_python: Free all data associated with Blender's Python integration.
* Also exit the Python interpreter (unless `WITH_PYTHON_MODULE` is enabled).
* \param do_user_exit_actions: When enabled perform actions associated with a user
@@ -107,13 +114,12 @@ void WM_init(struct bContext *C, int argc, const char **argv);
* and writing any changes to preferences.
* Set to false in background mode or when exiting because of failed command line argument parsing.
* In general automated actions where the user isn't making changes should pass in false too.
*
* \note doesn't run exit() call #WM_exit() for that.
*/
void WM_exit_ex(struct bContext *C, bool do_python, bool do_user_exit_actions);
/**
* \brief Main exit function to close Blender ordinarily.
* Main exit function to close Blender ordinarily.
*
* \note Use #wm_exit_schedule_delayed() to close Blender from an operator.
* Might leak memory otherwise.
*

View File

@@ -541,9 +541,17 @@ void WM_exit_ex(bContext *C, const bool do_python, const bool do_user_exit_actio
*
* Don't run this code when built as a Python module as this runs when Python is in the
* process of shutting down, where running a snippet like this will crash, see #82675.
* Instead use the `atexit` module, installed by #BPY_python_start */
const char *imports[2] = {"addon_utils", nullptr};
BPY_run_string_eval(C, imports, "addon_utils.disable_all()");
* Instead use the `atexit` module, installed by #BPY_python_start.
*
* Don't run this code when `C` is null because #pyrna_unregister_class
* passes in `CTX_data_main(C)` to un-registration functions.
* Further: `addon_utils.disable_all()` may call into functions that expect a valid context,
* supporting all these code-paths with a NULL context is quite involved for such a corner-case.
*/
if (C) {
const char *imports[2] = {"addon_utils", nullptr};
BPY_run_string_eval(C, imports, "addon_utils.disable_all()");
}
#endif
BLI_timer_free();
@@ -565,8 +573,6 @@ void WM_exit_ex(bContext *C, const bool do_python, const bool do_user_exit_actio
ED_editors_exit(bmain, true);
}
ED_undosys_type_free();
free_openrecent();
BKE_mball_cubeTable_free();
@@ -601,7 +607,13 @@ void WM_exit_ex(bContext *C, const bool do_python, const bool do_user_exit_actio
BKE_image_free_unused_gpu_textures();
}
BKE_blender_free(); /* blender.c, does entire library and spacetypes */
/* Frees the entire library (#G_MAIN) and space-types. */
BKE_blender_free();
/* Important this runs after #BKE_blender_free because the window manager may be allocated
* when `C` is null, holding references to undo steps which will fail to free if their types
* have been freed first. */
ED_undosys_type_free();
/* Free the GPU subdivision data after the database to ensure that subdivision structs used by
* the modifiers were garbage collected. */
@@ -671,7 +683,9 @@ void WM_exit_ex(bContext *C, const bool do_python, const bool do_user_exit_actio
wm_ghost_exit();
CTX_free(C);
if (C) {
CTX_free(C);
}
GHOST_DisposeSystemPaths();