Skip to content

gh-156400: Close the socket or pipe when transport creation fails in asyncio datagram/pipe endpoints - #156401

Open
tonghuaroot wants to merge 2 commits into
python:mainfrom
tonghuaroot:gh-156400-datagram-pipe-transport-error
Open

gh-156400: Close the socket or pipe when transport creation fails in asyncio datagram/pipe endpoints#156401
tonghuaroot wants to merge 2 commits into
python:mainfrom
tonghuaroot:gh-156400-datagram-pipe-transport-error

Conversation

@tonghuaroot

@tonghuaroot tonghuaroot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

create_datagram_endpoint(), connect_read_pipe() and connect_write_pipe() create or take ownership of a socket/pipe and then run protocol_factory() and transport creation. The only cleanup (except: transport.close()) covers await waiter, so if protocol_factory() or _make_*_transport() raises the resource is never closed and leaks until garbage collection.

Close the socket/pipe on that path, matching the create_connection() fix in gh-153133. The added regression tests fail without the fix and pass with it; the full test_asyncio suite passes.

@kumaraditya303 kumaraditya303 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI is failing

@bedevere-app

bedevere-app Bot commented Aug 31, 2026

Copy link
Copy Markdown

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

And if you don't make the requested changes, you will be put in the comfy chair!

On the proactor, _make_*_transport() takes ownership of the socket/pipe and
starts I/O before it can raise, so closing it in connect_*()/create_*()
double-manages it (broke test_windows_events). Close only when
protocol_factory() raises, before any transport exists.
@tonghuaroot

Copy link
Copy Markdown
Contributor Author

Thanks — fixed. The Windows failure was test_windows_events.check_write_rejected: on the proactor, _make_write_pipe_transport() takes ownership of the pipe and starts IOCP I/O before it can raise (WinError 87), so closing the pipe in connect_write_pipe's except double-managed it (the half-built transport's __del__ then hit I/O operation on closed pipe).

I've narrowed all three methods to close the socket/pipe only when protocol_factory() raises — i.e. before any transport exists. Once _make_*_transport() is called the transport owns the resource and cleans up on failure itself. The added tests still pass and the Windows regression is gone.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants