]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
fix: fix return values of wait_poll(), wait_epoll()
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Sun, 14 Sep 2025 03:40:11 +0000 (05:40 +0200)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Mon, 13 Oct 2025 01:25:16 +0000 (03:25 +0200)
psycopg/psycopg/waiting.py
tests/test_waiting.py

index 7df0b960d6a1021331f697c676d4f555e23cc6e5..db3845c347f93f79a2515b1924c624fb73097319 100644 (file)
@@ -260,10 +260,9 @@ def wait_select(gen: PQGen[RV], fileno: int, interval: float | None = None) -> R
 
 if hasattr(selectors, "EpollSelector"):
     _epoll_evmasks = {
-        WAIT_R: select.EPOLLONESHOT | select.EPOLLIN | select.EPOLLERR,
-        WAIT_W: select.EPOLLONESHOT | select.EPOLLOUT | select.EPOLLERR,
-        WAIT_RW: select.EPOLLONESHOT
-        | (select.EPOLLIN | select.EPOLLOUT | select.EPOLLERR),
+        WAIT_R: select.EPOLLONESHOT | select.EPOLLIN,
+        WAIT_W: select.EPOLLONESHOT | select.EPOLLOUT,
+        WAIT_RW: select.EPOLLONESHOT | select.EPOLLIN | select.EPOLLOUT,
     }
 else:
     _epoll_evmasks = {}
@@ -300,9 +299,9 @@ def wait_epoll(gen: PQGen[RV], fileno: int, interval: float | None = None) -> RV
                     continue
                 ev = fileevs[0][1]
                 ready = 0
-                if ev & ~select.EPOLLOUT:
+                if ev & select.EPOLLIN:
                     ready = READY_R
-                if ev & ~select.EPOLLIN:
+                if ev & select.EPOLLOUT:
                     ready |= READY_W
                 s = gen.send(ready)
                 evmask = _epoll_evmasks[s]
@@ -347,9 +346,9 @@ def wait_poll(gen: PQGen[RV], fileno: int, interval: float | None = None) -> RV:
 
             ev = fileevs[0][1]
             ready = 0
-            if ev & ~select.POLLOUT:
+            if ev & select.POLLIN:
                 ready = READY_R
-            if ev & ~select.POLLIN:
+            if ev & select.POLLOUT:
                 ready |= READY_W
             s = gen.send(ready)
             evmask = _poll_evmasks[s]
index 61cf99e9e84c2153bd37529351e6720cafa18a07..646f3c5eb12f1ffb4fc516e172cc3cba38302947 100644 (file)
@@ -2,6 +2,7 @@ import sys
 import time
 import select  # noqa: used in pytest.mark.skipif
 import socket
+from threading import Event
 
 import pytest
 
@@ -10,6 +11,8 @@ from psycopg import generators, waiting
 from psycopg.pq import ConnStatus, ExecStatus
 from psycopg.conninfo import make_conninfo
 
+from .acompat import gather, spawn
+
 skip_if_not_linux = pytest.mark.skipif(
     not sys.platform.startswith("linux"), reason="non-Linux platform"
 )
@@ -46,6 +49,42 @@ def test_wait_conn_bad(dsn):
         waiting.wait_conn(gen)
 
 
+@pytest.mark.slow
+@pytest.mark.parametrize("waitfn", waitfns)
+@skip_if_not_linux
+def test_wait_r(waitfn):
+    waitfn = getattr(waiting, waitfn)
+
+    port = None
+    ev = Event()
+
+    def writer():
+        ev.wait()
+        assert port
+        time.sleep(0.2)
+        with socket.create_connection(("127.0.0.1", port)):
+            pass
+
+    t = spawn(writer)
+
+    def gen():
+        r = yield waiting.Wait.R
+        return r
+
+    with socket.socket() as s:
+        s.bind(("", 0))
+        port = s.getsockname()[1]
+        s.listen()
+        ev.set()
+        t0 = time.time()
+        r = waitfn(gen(), s.fileno(), 0.3)
+        tf = time.time()
+        assert r == waiting.Ready.R
+        assert 0.2 <= tf - t0 < 0.3
+
+    gather(t)
+
+
 @pytest.mark.parametrize("waitfn", waitfns)
 @pytest.mark.parametrize("event", events)
 @skip_if_not_linux