From: Daniele Varrazzo Date: Tue, 24 Oct 2023 09:19:36 +0000 (+0200) Subject: fix: retry automatically syscall in wait_c if it fails with EINTR X-Git-Tag: pool-3.2.0~3^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F670%2Fhead;p=thirdparty%2Fpsycopg.git fix: retry automatically syscall in wait_c if it fails with EINTR Fix #667 --- 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; }