[Python-Dev] EINTR handling...
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