[Python-Dev] EINTR handling... (original) (raw)

Charles-François Natali cf.natali at gmail.com
Fri Aug 30 15:10:49 CEST 2013


2013/8/30 Amaury Forgeot d'Arc <amauryfa at gmail.com>:

I agree. Is there a way to see in C code where EINTR is not handled?

EINTR can be returned on slow syscalls, so a good heuristic would be to start with code that releases the GIL. But I don't see a generic way apart from grepping for syscalls that are documented to return EINTR.

Or a method to handle this systematically?

The glibc defines this macro:

define TEMP_FAILURE_RETRY(expression) \

(extension
({ long int __result;
do __result = (long int) (expression);
while (__result == -1L && errno == EINTR);
__result; })) #endif

which you can then use as: pid = TEMP_FAILURE_RETRY(waitpid(pid, &status, options));

Unfortunately, it's not as easy for us, since we must release the GIL around the syscall, try again if it failed with EINTR, only after having called PyErr_CheckSignals() to run signal handlers.

e.g. waitpid():

""" Py_BEGIN_ALLOW_THREADS pid = waitpid(pid, &status, options); Py_END_ALLOW_THREADS """

should become (conceptually):

""" begin_handle_eintr: Py_BEGIN_ALLOW_THREADS pid = waitpid(pid, &status, options); Py_END_ALLOW_THREADS

    if (pid < 0 && errno == EINTR) {
        if (PyErr_CheckSignals())
            return NULL;
        goto begin_handle_eintr;
    }

"""

We might want to go for a clever macro (like BEGIN_SELECT_LOOP in socketmodule.c).

2013/8/30 Nick Coghlan <ncoghlan at gmail.com>:

Sounds good to me. I don't believe there's been a conscious decision that we shouldn't handle it, it just hasn't annoyed anyone enough for them to propose a systematic fix in CPython. If that latter part is no longer true, great ;)

Great, I'll open a bug report then :)

cf



More information about the Python-Dev mailing list