From 103ebeaa4d69c00d91ec2df64b0be760ab39b0e7 Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Tue, 24 Oct 2023 11:19:36 +0200 Subject: [PATCH] fix: retry automatically syscall in wait_c if it fails with EINTR Fix #667 --- docs/news.rst | 8 +++++--- psycopg_c/psycopg_c/_psycopg/waiting.pyx | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/docs/news.rst b/docs/news.rst index f7b227e9e..b4e4fd97c 100644 --- a/docs/news.rst +++ b/docs/news.rst @@ -30,17 +30,19 @@ Psycopg 3.2 (unreleased) .. __: https://numpy.org/doc/stable/reference/arrays.scalars.html#built-in-scalar-types -Current release ---------------- - Psycopg 3.1.13 (unreleased) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Raise `DataError` instead of whatever internal failure trying to dump a `~datetime.time` object with with a `!tzinfo` specified as `~zoneinfo.ZoneInfo` (ambiguous offset, see :ticket:`#652`). +- Handle gracefully EINTR on signals instead of raising `InterruptedError`, + consistently with :pep:`475` guideline (:ticket:`#667`). +Current release +--------------- + Psycopg 3.1.12 ^^^^^^^^^^^^^^ diff --git a/psycopg_c/psycopg_c/_psycopg/waiting.pyx b/psycopg_c/psycopg_c/_psycopg/waiting.pyx index cbe716bf5..33c54c513 100644 --- a/psycopg_c/psycopg_c/_psycopg/waiting.pyx +++ b/psycopg_c/psycopg_c/_psycopg/waiting.pyx @@ -71,11 +71,18 @@ wait_c_impl(int fileno, int wait, float timeout) timeout_ms = (int)(timeout * SEC_TO_MS); } +retry_eintr: + Py_BEGIN_ALLOW_THREADS errno = 0; select_rv = poll(&input_fd, 1, timeout_ms); Py_END_ALLOW_THREADS + /* The grace of PEP 475 */ + if (errno == EINTR) { + goto retry_eintr; + } + if (select_rv < 0) { goto error; } if (PyErr_CheckSignals()) { goto finally; } @@ -116,11 +123,18 @@ wait_c_impl(int fileno, int wait, float timeout) tvptr = &tv; } +retry_eintr: + Py_BEGIN_ALLOW_THREADS errno = 0; select_rv = select(fileno + 1, &ifds, &ofds, &efds, tvptr); Py_END_ALLOW_THREADS + /* The grace of PEP 475 */ + if (errno == EINTR) { + goto retry_eintr; + } + if (select_rv < 0) { goto error; } if (PyErr_CheckSignals()) { goto finally; } -- 2.39.5