From: Daniele Varrazzo Date: Wed, 26 Oct 2022 01:02:14 +0000 (+0200) Subject: fix(c): allow wait_select() to be interrupted by signals X-Git-Tag: 3.1.5~7^2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=159e43d98aac8e4ed0dc7aa90d33db75687ca18a;p=thirdparty%2Fpsycopg.git fix(c): allow wait_select() to be interrupted by signals --- diff --git a/psycopg_c/psycopg_c/_psycopg/waiting.pyx b/psycopg_c/psycopg_c/_psycopg/waiting.pyx index 3b0c1259d..be8aaee56 100644 --- a/psycopg_c/psycopg_c/_psycopg/waiting.pyx +++ b/psycopg_c/psycopg_c/_psycopg/waiting.pyx @@ -16,6 +16,12 @@ cdef extern from *: #define SELECT_EV_WRITE 2 #define SEC_TO_US (1000 * 1000) +/* Use select to wait for readiness on fileno. + * + * - Return SELECT_EV_* if the file is ready + * - Return 0 on timeout + * - Return -1 (and set an exception) on error. + */ static int select_impl(int fileno, int wait, float timeout) { @@ -23,7 +29,7 @@ select_impl(int fileno, int wait, float timeout) fd_set ofds; fd_set efds; struct timeval tv, *tvptr; - int select_rv, rv = 0; + int select_rv; FD_ZERO(&ifds); FD_ZERO(&ofds); @@ -53,44 +59,44 @@ select_impl(int fileno, int wait, float timeout) select_rv = select(fileno + 1, &ifds, &ofds, &efds, tvptr); Py_END_ALLOW_THREADS - if (select_rv <= 0) { - rv = select_rv; - } - else { - if (FD_ISSET(fileno, &ifds)) { - rv |= SELECT_EV_READ; - } - if (FD_ISSET(fileno, &ofds)) { - rv |= SELECT_EV_WRITE; - } + if (PyErr_CheckSignals()) { + return -1; } - return rv; -} + if (select_rv < 0) { -static int -select_raise(int n) -{ #ifdef MS_WINDOWS - if (n == SOCKET_ERROR) { - PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError()); - return -1; - } + if (select_rv == SOCKET_ERROR) { + PyErr_SetExcFromWindowsErr(PyExc_OSError, WSAGetLastError()); + } #else - if (n < 0) { - PyErr_SetFromErrno(PyExc_OSError); + if (select_rv < 0) { + PyErr_SetFromErrno(PyExc_OSError); + } +#endif + else { + PyErr_SetString(PyExc_OSError, "unexpected error from select()"); + } return -1; } -#endif - - PyErr_SetString(PyExc_OSError, "unexpected error from select()"); - return -1; + else { + int rv = 0; + + if (select_rv >= 0) { + if (FD_ISSET(fileno, &ifds)) { + rv = SELECT_EV_READ; + } + if (FD_ISSET(fileno, &ofds)) { + rv |= SELECT_EV_WRITE; + } + } + return rv; + } } """ const int SELECT_EV_READ const int SELECT_EV_WRITE - cdef int select_impl(int fileno, int wait, float timeout) - cdef int select_raise(int e) except -1 + cdef int select_impl(int fileno, int wait, float timeout) except -1 def wait_select(gen: PQGen[RV], int fileno, timeout = None) -> RV: @@ -112,8 +118,6 @@ def wait_select(gen: PQGen[RV], int fileno, timeout = None) -> RV: ready = select_impl(fileno, wait, ctimeout) if ready == 0: continue - elif ready < 0: - select_raise(ready) wait = gen.send(ready)