From 18ff54204fa3d60f6cf2493f3358c25aca5ed2de Mon Sep 17 00:00:00 2001 From: Hyunsik Parker <246881935+HyunsikParker@users.noreply.github.com> Date: Tue, 1 Sep 2026 05:01:20 +0900 Subject: [PATCH] Preserve file descriptor blocking mode for poll handles --- tests/test_sockets.py | 23 +++++++++++++++++++++++ uvloop/handles/poll.pyx | 11 ++++++++++- uvloop/includes/stdlib.pxi | 2 ++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/tests/test_sockets.py b/tests/test_sockets.py index e7c335e11..3d2d627ea 100644 --- a/tests/test_sockets.py +++ b/tests/test_sockets.py @@ -1,4 +1,5 @@ import asyncio +import os import pickle import select import socket @@ -14,6 +15,28 @@ class _TestSockets: + def test_add_reader_writer_preserves_blocking_mode(self): + read_fd, write_fd = os.pipe() + try: + self.assertTrue(os.get_blocking(read_fd)) + self.loop.add_reader(read_fd, lambda: None) + try: + self.assertTrue(os.get_blocking(read_fd)) + finally: + self.loop.remove_reader(read_fd) + self.assertTrue(os.get_blocking(read_fd)) + + self.assertTrue(os.get_blocking(write_fd)) + self.loop.add_writer(write_fd, lambda: None) + try: + self.assertTrue(os.get_blocking(write_fd)) + finally: + self.loop.remove_writer(write_fd) + self.assertTrue(os.get_blocking(write_fd)) + finally: + os.close(read_fd) + os.close(write_fd) + async def recv_all(self, sock, nbytes): buf = b'' while len(buf) < nbytes: diff --git a/uvloop/handles/poll.pyx b/uvloop/handles/poll.pyx index c905e9b0b..1a7e7cbda 100644 --- a/uvloop/handles/poll.pyx +++ b/uvloop/handles/poll.pyx @@ -1,7 +1,9 @@ @cython.no_gc_clear cdef class UVPoll(UVHandle): cdef _init(self, Loop loop, int fd): - cdef int err + cdef: + int err + bint was_blocking = os_get_blocking(fd) self._start_init(loop) @@ -18,6 +20,13 @@ cdef class UVPoll(UVHandle): self._finish_init() + if was_blocking: + try: + os_set_blocking(fd, True) + except BaseException: + self._close() + raise + self.fd = fd self.reading_handle = None self.writing_handle = None diff --git a/uvloop/includes/stdlib.pxi b/uvloop/includes/stdlib.pxi index 5fff4ad8e..d9aa13e70 100644 --- a/uvloop/includes/stdlib.pxi +++ b/uvloop/includes/stdlib.pxi @@ -104,6 +104,8 @@ cdef os_environ = os.environ cdef os_dup = os.dup cdef os_set_inheritable = os.set_inheritable cdef os_get_inheritable = os.get_inheritable +cdef os_get_blocking = os.get_blocking +cdef os_set_blocking = os.set_blocking cdef os_close = os.close cdef os_open = os.open cdef os_devnull = os.devnull