]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
fix: retry automatically syscall in wait_c if it fails with EINTR 670/head
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Tue, 24 Oct 2023 09:19:36 +0000 (11:19 +0200)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Tue, 24 Oct 2023 12:30:14 +0000 (14:30 +0200)
Fix #667

docs/news.rst
psycopg_c/psycopg_c/_psycopg/waiting.pyx

index f7b227e9e459ce08a0f1b9ae8091da622b469549..b4e4fd97c76e5dce604dc56bd9ec31f828d05975 100644 (file)
@@ -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
 ^^^^^^^^^^^^^^
 
index cbe716bf57ee958cf7036793f5a811ccc7ee8719..33c54c513b8d0e4ed5afbd4db7cb9b5e8c792dd8 100644 (file)
@@ -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; }