diff --git a/newsfragments/3509.bugfix.rst b/newsfragments/3509.bugfix.rst new file mode 100644 index 0000000000..2966f4706f --- /dev/null +++ b/newsfragments/3509.bugfix.rst @@ -0,0 +1,4 @@ +On Windows, :func:`trio.lowlevel.wait_readable`, :func:`trio.lowlevel.wait_writable` +and :func:`trio.lowlevel.notify_closing` raised ``BusyResourceError`` and +``ClosedResourceError`` without any message. They now explain themselves, as they +already did on the epoll and kqueue backends. diff --git a/src/trio/_core/_io_windows.py b/src/trio/_core/_io_windows.py index 7b789c3dec..99f31aea0a 100644 --- a/src/trio/_core/_io_windows.py +++ b/src/trio/_core/_io_windows.py @@ -740,7 +740,9 @@ async def _afd_poll(self, sock: _HasFileNo | int, mode: str) -> None: waiters = AFDWaiters() self._afd_waiters[base_handle] = waiters if getattr(waiters, mode) is not None: - raise _core.BusyResourceError + raise _core.BusyResourceError( + "another task is already reading / writing this socket", + ) setattr(waiters, mode, _core.current_task()) # Could potentially raise if the handle is somehow invalid; that's OK, # we let it escape. @@ -822,7 +824,10 @@ def notify_closing(self, handle: Handle | int | _HasFileNo) -> None: handle = _get_base_socket(handle) waiters = self._afd_waiters.get(handle) if waiters is not None: - wake_all(waiters, _core.ClosedResourceError()) + wake_all( + waiters, + _core.ClosedResourceError("another task closed this socket"), + ) self._refresh_afd(handle) ################################################################