mirror of https://github.com/python/cpython
gh-112278: Improve error handling in wmi module and tests (GH-117818)
This commit is contained in:
parent
185999bb3a
commit
7d9d6b53bc
|
@ -14,11 +14,13 @@ def wmi_exec_query(query):
|
||||||
# gh-112278: WMI maybe slow response when first call.
|
# gh-112278: WMI maybe slow response when first call.
|
||||||
try:
|
try:
|
||||||
return _wmi.exec_query(query)
|
return _wmi.exec_query(query)
|
||||||
|
except BrokenPipeError:
|
||||||
|
pass
|
||||||
except WindowsError as e:
|
except WindowsError as e:
|
||||||
if e.winerror != 258:
|
if e.winerror != 258:
|
||||||
raise
|
raise
|
||||||
time.sleep(LOOPBACK_TIMEOUT)
|
time.sleep(LOOPBACK_TIMEOUT)
|
||||||
return _wmi.exec_query(query)
|
return _wmi.exec_query(query)
|
||||||
|
|
||||||
|
|
||||||
class WmiTests(unittest.TestCase):
|
class WmiTests(unittest.TestCase):
|
||||||
|
|
|
@ -279,9 +279,11 @@ _wmi_exec_query_impl(PyObject *module, PyObject *query)
|
||||||
// a timeout. The initEvent will be set after COM initialization, it will
|
// a timeout. The initEvent will be set after COM initialization, it will
|
||||||
// take a longer time when first initialized. The connectEvent will be set
|
// take a longer time when first initialized. The connectEvent will be set
|
||||||
// after connected to WMI.
|
// after connected to WMI.
|
||||||
err = wait_event(data.initEvent, 1000);
|
|
||||||
if (!err) {
|
if (!err) {
|
||||||
err = wait_event(data.connectEvent, 100);
|
err = wait_event(data.initEvent, 1000);
|
||||||
|
if (!err) {
|
||||||
|
err = wait_event(data.connectEvent, 100);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!err) {
|
while (!err) {
|
||||||
|
@ -305,28 +307,33 @@ _wmi_exec_query_impl(PyObject *module, PyObject *query)
|
||||||
CloseHandle(data.readPipe);
|
CloseHandle(data.readPipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow the thread some time to clean up
|
if (hThread) {
|
||||||
switch (WaitForSingleObject(hThread, 100)) {
|
// Allow the thread some time to clean up
|
||||||
case WAIT_OBJECT_0:
|
int thread_err;
|
||||||
// Thread ended cleanly
|
switch (WaitForSingleObject(hThread, 100)) {
|
||||||
if (!GetExitCodeThread(hThread, (LPDWORD)&err)) {
|
case WAIT_OBJECT_0:
|
||||||
err = GetLastError();
|
// Thread ended cleanly
|
||||||
|
if (!GetExitCodeThread(hThread, (LPDWORD)&thread_err)) {
|
||||||
|
thread_err = GetLastError();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WAIT_TIMEOUT:
|
||||||
|
// Probably stuck - there's not much we can do, unfortunately
|
||||||
|
thread_err = WAIT_TIMEOUT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
thread_err = GetLastError();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
// An error on our side is more likely to be relevant than one from
|
||||||
case WAIT_TIMEOUT:
|
// the thread, but if we don't have one on our side we'll take theirs.
|
||||||
// Probably stuck - there's not much we can do, unfortunately
|
|
||||||
if (err == 0 || err == ERROR_BROKEN_PIPE) {
|
if (err == 0 || err == ERROR_BROKEN_PIPE) {
|
||||||
err = WAIT_TIMEOUT;
|
err = thread_err;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
default:
|
CloseHandle(hThread);
|
||||||
if (err == 0 || err == ERROR_BROKEN_PIPE) {
|
|
||||||
err = GetLastError();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseHandle(hThread);
|
|
||||||
CloseHandle(data.initEvent);
|
CloseHandle(data.initEvent);
|
||||||
CloseHandle(data.connectEvent);
|
CloseHandle(data.connectEvent);
|
||||||
hThread = NULL;
|
hThread = NULL;
|
||||||
|
|
Loading…
Reference in New Issue