diff options
| author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2024-06-27 22:12:12 (GMT) |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-06-27 22:12:12 (GMT) |
| commit | d5441f6aacc1eab69ad539445568a2ef779cb267 (patch) | |
| tree | 73588f46cb441ee3b1ee10c8f681b2daa2addc9b /Python/pylifecycle.c | |
| parent | 49a01d6290631ef65da6cd142df41c72a7dae3b5 (diff) | |
| download | cpython-d5441f6aacc1eab69ad539445568a2ef779cb267.zip cpython-d5441f6aacc1eab69ad539445568a2ef779cb267.tar.gz cpython-d5441f6aacc1eab69ad539445568a2ef779cb267.tar.bz2 | |
[3.13] gh-120837: Update _Py_DumpExtensionModules to be async-signal-safe (gh-121051) (gh-121107)
gh-120837: Update _Py_DumpExtensionModules to be async-signal-safe (gh-121051)
(cherry picked from commit 1a2e7a747540f74414e7c50556bcb2cc127e9d1c)
Co-authored-by: Donghee Na <donghee.na@python.org>
Diffstat (limited to 'Python/pylifecycle.c')
| -rw-r--r-- | Python/pylifecycle.c | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index af9d4ed..13bd62d 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -3036,6 +3036,30 @@ fatal_error_exit(int status) } } +static inline int +acquire_dict_lock_for_dump(PyObject *obj) +{ +#ifdef Py_GIL_DISABLED + PyMutex *mutex = &obj->ob_mutex; + if (_PyMutex_LockTimed(mutex, 0, 0) == PY_LOCK_ACQUIRED) { + return 1; + } + return 0; +#else + return 1; +#endif +} + +static inline void +release_dict_lock_for_dump(PyObject *obj) +{ +#ifdef Py_GIL_DISABLED + PyMutex *mutex = &obj->ob_mutex; + // We can not call PyMutex_Unlock because it's not async-signal-safe. + // So not to wake up other threads, we just use a simple atomic store in here. + _Py_atomic_store_uint8(&mutex->_bits, _Py_UNLOCKED); +#endif +} // Dump the list of extension modules of sys.modules, excluding stdlib modules // (sys.stdlib_module_names), into fd file descriptor. @@ -3063,13 +3087,18 @@ _Py_DumpExtensionModules(int fd, PyInterpreterState *interp) PyObject *stdlib_module_names = NULL; if (interp->sysdict != NULL) { pos = 0; - while (PyDict_Next(interp->sysdict, &pos, &key, &value)) { + if (!acquire_dict_lock_for_dump(interp->sysdict)) { + // If we cannot acquire the lock, just don't dump the list of extension modules. + return; + } + while (_PyDict_Next(interp->sysdict, &pos, &key, &value, NULL)) { if (PyUnicode_Check(key) && PyUnicode_CompareWithASCIIString(key, "stdlib_module_names") == 0) { stdlib_module_names = value; break; } } + release_dict_lock_for_dump(interp->sysdict); } // If we failed to get sys.stdlib_module_names or it's not a frozenset, // don't exclude stdlib modules. @@ -3081,7 +3110,11 @@ _Py_DumpExtensionModules(int fd, PyInterpreterState *interp) int header = 1; Py_ssize_t count = 0; pos = 0; - while (PyDict_Next(modules, &pos, &key, &value)) { + if (!acquire_dict_lock_for_dump(modules)) { + // If we cannot acquire the lock, just don't dump the list of extension modules. + return; + } + while (_PyDict_Next(modules, &pos, &key, &value, NULL)) { if (!PyUnicode_Check(key)) { continue; } @@ -3122,6 +3155,7 @@ _Py_DumpExtensionModules(int fd, PyInterpreterState *interp) _Py_DumpASCII(fd, key); count++; } + release_dict_lock_for_dump(modules); if (count) { PUTS(fd, " (total: "); |
