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.
--- /dev/null
+GIL is released while calling functions that acquire Windows loader lock.
}
#ifdef MS_WIN32
+ Py_BEGIN_ALLOW_THREADS
address = (void *)GetProcAddress(handle, name);
+ Py_END_ALLOW_THREADS
if (!address) {
PyErr_Format(PyExc_ValueError,
"symbol '%s' not found",
#ifdef MS_WIN32
static PPROC FindAddress(void *handle, const char *name, PyObject *type)
{
+ PPROC address;
#ifdef MS_WIN64
/* win64 has no stdcall calling conv, so it should
also not have the name mangling of it.
*/
- return (PPROC)GetProcAddress(handle, name);
+ Py_BEGIN_ALLOW_THREADS
+ address = (PPROC)GetProcAddress(handle, name);
+ Py_END_ALLOW_THREADS
+ return address;
#else
- PPROC address;
char *mangled_name;
int i;
StgDictObject *dict;
+ Py_BEGIN_ALLOW_THREADS
address = (PPROC)GetProcAddress(handle, name);
+ Py_END_ALLOW_THREADS
if (address)
return address;
if (((size_t)name & ~0xFFFF) == 0) {
return NULL;
for (i = 0; i < 32; ++i) {
sprintf(mangled_name, "_%s@%d", name, i*4);
+ Py_BEGIN_ALLOW_THREADS
address = (PPROC)GetProcAddress(handle, mangled_name);
+ Py_END_ALLOW_THREADS
if (address)
return address;
}
if (!name)
return NULL;
+ Py_BEGIN_ALLOW_THREADS
hMod = LoadLibraryW(name);
+ Py_END_ALLOW_THREADS
+
if (!hMod)
return PyErr_SetFromWindowsErr(GetLastError());
#ifdef _WIN64
static PyObject *free_library(PyObject *self, PyObject *args)
{
void *hMod;
+ BOOL result;
if (!PyArg_ParseTuple(args, "O&:FreeLibrary", &_parse_voidp, &hMod))
return NULL;
- if (!FreeLibrary((HMODULE)hMod))
+
+ Py_BEGIN_ALLOW_THREADS
+ result = FreeLibrary((HMODULE)hMod);
+ Py_END_ALLOW_THREADS
+
+ if (!result)
return PyErr_SetFromWindowsErr(GetLastError());
Py_RETURN_NONE;
}
closesocket(s);
/* On WinXP we will have Py_CancelIoEx == NULL */
+ Py_BEGIN_ALLOW_THREADS
hKernel32 = GetModuleHandle("KERNEL32");
*(FARPROC *)&Py_CancelIoEx = GetProcAddress(hKernel32, "CancelIoEx");
+ Py_END_ALLOW_THREADS
return 0;
}
/* only recheck */
if (Py_CreateSymbolicLinkW)
return 1;
+
+ Py_BEGIN_ALLOW_THREADS
hKernel32 = GetModuleHandleW(L"KERNEL32");
*(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
"CreateSymbolicLinkW");
+ Py_END_ALLOW_THREADS
+
return Py_CreateSymbolicLinkW != NULL;
}
the system SHELL32.DLL, even if there is another SHELL32.DLL
in the DLL search path. */
hShell32 = LoadLibraryW(L"SHELL32");
- Py_END_ALLOW_THREADS
if (hShell32) {
*(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
"ShellExecuteW");
} else {
has_ShellExecute = 0;
}
+ Py_END_ALLOW_THREADS
}
return has_ShellExecute;
}
/* Vista is supported and the GetMaximumProcessorCount API is Win7+
Need to fallback to Vista behavior if this call isn't present */
HINSTANCE hKernel32;
- hKernel32 = GetModuleHandleW(L"KERNEL32");
-
static DWORD(CALLBACK *_GetMaximumProcessorCount)(WORD) = NULL;
+ Py_BEGIN_ALLOW_THREADS
+ hKernel32 = GetModuleHandleW(L"KERNEL32");
*(FARPROC*)&_GetMaximumProcessorCount = GetProcAddress(hKernel32,
"GetMaximumProcessorCount");
+ Py_END_ALLOW_THREADS
if (_GetMaximumProcessorCount != NULL) {
ncpu = _GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS);
}
/* Only available on 64bit platforms, so we must load it
dynamically. */
+ Py_BEGIN_ALLOW_THREADS
hMod = GetModuleHandleW(L"advapi32.dll");
if (hMod)
pfn = (RDKEFunc)GetProcAddress(hMod,
"RegDeleteKeyExW");
+ Py_END_ALLOW_THREADS
if (!pfn) {
PyErr_SetString(PyExc_NotImplementedError,
"not implemented on this platform");
/* Only available on 64bit platforms, so we must load it
dynamically.*/
+ Py_BEGIN_ALLOW_THREADS
hMod = GetModuleHandleW(L"advapi32.dll");
if (hMod)
pfn = (RDRKFunc)GetProcAddress(hMod,
"RegDisableReflectionKey");
+ Py_END_ALLOW_THREADS
if (!pfn) {
PyErr_SetString(PyExc_NotImplementedError,
"not implemented on this platform");
/* Only available on 64bit platforms, so we must load it
dynamically.*/
+ Py_BEGIN_ALLOW_THREADS
hMod = GetModuleHandleW(L"advapi32.dll");
if (hMod)
pfn = (RERKFunc)GetProcAddress(hMod,
"RegEnableReflectionKey");
+ Py_END_ALLOW_THREADS
if (!pfn) {
PyErr_SetString(PyExc_NotImplementedError,
"not implemented on this platform");
/* Only available on 64bit platforms, so we must load it
dynamically.*/
+ Py_BEGIN_ALLOW_THREADS
hMod = GetModuleHandleW(L"advapi32.dll");
if (hMod)
pfn = (RQRKFunc)GetProcAddress(hMod,
"RegQueryReflectionKey");
+ Py_END_ALLOW_THREADS
if (!pfn) {
PyErr_SetString(PyExc_NotImplementedError,
"not implemented on this platform");
/* 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
"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;
// 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))) {