[Python-Dev] Py_END_ALLOW_THREADS and GetLastError()

Ulrich Eckhardt doomster at knuut.de
Sat Jan 10 13:40:10 CET 2009


On Saturday 10 January 2009 12:29:47 Kristján Valur Jónsson wrote:
> Currently on Windows, Py_END_ALLOW_THREADS can have the side effect of
> resetting the windows error code returned by GetLastError(). There is a
> number of cases, particularly in posixmodule, with a pattern like:
> Py_BEGIN_ALLOW_THREADS
>             result = FindNextFile(hFindFile, &FileData);
>             Py_END_ALLOW_THREADS
>             /* FindNextFile sets error to ERROR_NO_MORE_FILES if
>                it got to the end of the directory. */
>             if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
>
> That doesn´t work.  (This particular site is where I noticed the problem,
> running the testsuite in a debug build). Now, the thread swith macro does
> take care to preserve "errno", but not the windows system error.  This is
> easy to add, but it requires that windows.h be included by ceval.c and
> pystate.c The alternative fix is to find all these cases and manually
> preserve the error state, or query it right after the function call if
> needed. Any preferences?

Well, that's what you get for using globals and exactly that is the reason why 
their use is generally discouraged. My preference would be to fix all cases 
where there is an intervening call after the call that set errno to first 
preserve that state. As a short term fix, I would add a workaround to 
Py_END_ALLOW_THREADS though, both for errno and win32's GetLastError().

Generally, I would discourage non-local errno use. My motivation is that MS 
Windows CE simply doesn't have errno and MS Windows in general often uses 
different ways to signal errors, so not using it would restrict the 
conditionally compiled code further. Especially in the math module, I have no 
idea yet how to port that in a way that is still at least remotely clean and 
maintainable because errno is used everywhere there. Translating the errno 
value to a Python error directly after the failed call would help immensely.

just my two embedded cents

Uli


More information about the Python-Dev mailing list