From 4860f01ac0f07cdc8fc0cc27c33f5a64e5cfec9f Mon Sep 17 00:00:00 2001 From: Tony Roberts Date: Sat, 2 Feb 2019 18:16:42 +0100 Subject: bpo-33895: Relase GIL while calling functions that acquire Windows loader lock (GH-7789) LoadLibrary, GetProcAddress, FreeLibrary and GetModuleHandle acquire the system loader lock. Calling these while holding the GIL will cause a deadlock on the rare occasion that another thread is detaching and needs to destroy its thread state at the same time. --- Python/dynload_win.c | 6 ++++++ Python/sysmodule.c | 2 ++ 2 files changed, 8 insertions(+) (limited to 'Python') diff --git a/Python/dynload_win.c b/Python/dynload_win.c index 0fdf77f552..129e04d1b2 100644 --- a/Python/dynload_win.c +++ b/Python/dynload_win.c @@ -218,8 +218,10 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, /* We use LoadLibraryEx so Windows looks for dependent DLLs in directory of pathname first. */ /* XXX This call doesn't exist in Windows CE */ + Py_BEGIN_ALLOW_THREADS hDLL = LoadLibraryExW(wpathname, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); + Py_END_ALLOW_THREADS #if HAVE_SXS _Py_DeactivateActCtx(cookie); #endif @@ -298,11 +300,15 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, "Module use of %.150s conflicts " "with this version of Python.", import_python); + Py_BEGIN_ALLOW_THREADS FreeLibrary(hDLL); + Py_END_ALLOW_THREADS return NULL; } } + Py_BEGIN_ALLOW_THREADS p = GetProcAddress(hDLL, funcname); + Py_END_ALLOW_THREADS } return p; diff --git a/Python/sysmodule.c b/Python/sysmodule.c index f1cd74ebec..c7e68aa364 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -1159,7 +1159,9 @@ sys_getwindowsversion_impl(PyObject *module) // We need to read the version info from a system file resource // to accurately identify the OS version. If we fail for any reason, // just return whatever GetVersion said. + Py_BEGIN_ALLOW_THREADS hKernel32 = GetModuleHandleW(L"kernel32.dll"); + Py_END_ALLOW_THREADS if (hKernel32 && GetModuleFileNameW(hKernel32, kernel32_path, MAX_PATH) && (verblock_size = GetFileVersionInfoSizeW(kernel32_path, NULL)) && (verblock = PyMem_RawMalloc(verblock_size))) { -- cgit v1.2.1