New submission from Steve Dower <steve.do...@python.org>: Most Win32 API calls are made within Py_BEGIN_ALLOW_THREADS blocks, as they do not access Python objects and so we can release the GIL.
However, in general, error handling occurs after the Py_END_ALLOW_THREADS line. Due to the design of the Win32 API, the pattern looks like this: Py_BEGIN_ALLOW_THREADS ret = ApiCall(...); Py_END_ALLOW_THREADS if (FAILED(ret)) { error_code = GetLastError(); } However, Py_END_ALLOW_THREADS also makes Win32 API calls (to acquire the GIL), and if any of these fail then the error code may be overwritten. Failures in Py_END_ALLOW_THREADS are either fatal (in which case we don't care about the preceding error any more) or signal a retry (in which case we *do* care about the preceding error), but in the latter case we may have lost the error code. Further, while Win32 APIs are not _supposed_ to set the last error to ERROR_SUCCESS (0) when they succeed, some occasionally do. We should update Py_END_ALLOW_THREADS to preserve the last error code when necessary. Ideally, if we don't have to do any work to reacquire the GIL, we shouldn't do any work to preserve the error code either. ---------- components: Windows messages: 313447 nosy: paul.moore, steve.dower, tim.golden, zach.ware priority: normal severity: normal stage: test needed status: open title: GetLastError() may be overwritten by Py_END_ALLOW_THREADS type: behavior versions: Python 3.6, Python 3.7, Python 3.8 _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue33030> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com