diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2024-06-14 19:54:46 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-14 19:54:46 (GMT) |
commit | 18ea22a8306b5746da74d83a9db00dcc390bf092 (patch) | |
tree | 234eece50eb1ddd9a564e69334c5de0b9033f9cd /Modules | |
parent | da40fa35263893f78e75205c54fa3bcd24a64468 (diff) | |
download | cpython-18ea22a8306b5746da74d83a9db00dcc390bf092.zip cpython-18ea22a8306b5746da74d83a9db00dcc390bf092.tar.gz cpython-18ea22a8306b5746da74d83a9db00dcc390bf092.tar.bz2 |
[3.13] gh-120161: Fix a Crash in the _datetime Module (gh-120518)
In gh-120009 I used an atexit hook to finalize the _datetime module's static types at interpreter shutdown. However, atexit hooks are executed very early in finalization, which is a problem in the few cases where a subclass of one of those static types is still alive until the final GC collection. The static builtin types don't have this probably because they are finalized toward the end, after the final GC collection. To avoid the problem for _datetime, I have applied a similar approach here.
Also, credit goes to @mgorny and @neonene for the new tests.
FYI, I would have liked to take a slightly cleaner approach with managed static types, but wanted to get a smaller fix in first for the sake of backporting. I'll circle back to the cleaner approach with a future change on the main branch.
(cherry picked from commit b2e71ff4f8fa5b7d8117dd8125137aee3d01f015, AKA gh-120182)
Co-authored-by: Eric Snow <ericsnowcurrently@gmail.com>
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_datetimemodule.c | 48 |
1 files changed, 2 insertions, 46 deletions
diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 7db3030..135d6cb 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -7126,37 +7126,6 @@ clear_state(datetime_state *st) } -/* --------------------------------------------------------------------------- - * Global module state. - */ - -// If we make _PyStaticType_*ForExtension() public -// then all this should be managed by the runtime. - -static struct { - PyMutex mutex; - int64_t interp_count; -} _globals = {0}; - -static void -callback_for_interp_exit(void *Py_UNUSED(data)) -{ - PyInterpreterState *interp = PyInterpreterState_Get(); - - assert(_globals.interp_count > 0); - PyMutex_Lock(&_globals.mutex); - _globals.interp_count -= 1; - int final = !_globals.interp_count; - PyMutex_Unlock(&_globals.mutex); - - /* They must be done in reverse order so subclasses are finalized - * before base classes. */ - for (size_t i = Py_ARRAY_LENGTH(capi_types); i > 0; i--) { - PyTypeObject *type = capi_types[i-1]; - _PyStaticType_FiniForExtension(interp, type, final); - } -} - static int init_static_types(PyInterpreterState *interp, int reloading) { @@ -7179,19 +7148,6 @@ init_static_types(PyInterpreterState *interp, int reloading) } } - PyMutex_Lock(&_globals.mutex); - assert(_globals.interp_count >= 0); - _globals.interp_count += 1; - PyMutex_Unlock(&_globals.mutex); - - /* It could make sense to add a separate callback - * for each of the types. However, for now we can take the simpler - * approach of a single callback. */ - if (PyUnstable_AtExit(interp, callback_for_interp_exit, NULL) < 0) { - callback_for_interp_exit(NULL); - return -1; - } - return 0; } @@ -7376,8 +7332,8 @@ module_clear(PyObject *mod) PyInterpreterState *interp = PyInterpreterState_Get(); clear_current_module(interp, mod); - // We take care of the static types via an interpreter atexit hook. - // See callback_for_interp_exit() above. + // The runtime takes care of the static types for us. + // See _PyTypes_FiniExtTypes().. return 0; } |