Skip to content

gh-85972: Use native timeout for inet socket operations #110988

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 22 commits into
base: main
Choose a base branch
from

Conversation

aisk
Copy link
Contributor

@aisk aisk commented Oct 17, 2023

I have a dig into using SO_SENDTIMEO and SO_RECVTIMEO to implement the timeout operation, and found that most platforms support using them to set the write / send / read / recv ... timeouts for INET sockets.

For Unix domain sockets, only Linux supports using these options to set the timeout.

For connect / accept, SO_SENDTIMEO and SO_RECVTIMEO also affect these two operations' timeout on Linux.

So, in this PR, Unix domain sockets will keep the old behavior (use setblocking(0) and select to emulate timeout).

For INET sockets, socket.settimeout will use SO_SENDTIMEO and SO_RECVTIMEO options to set the timeout to the socket directly and use this to enforce a timeout.

For INET sockets, connect will use the old behavior (use setblocking(0) and select to emulate timeout) to enforce a timeout. To achieve this, we should set it to non-blocking mode and call the old connect, then set it to blocking mode again.

@aisk aisk changed the title use native timeout for inet socket operations gh-85972: use native timeout for inet socket operations Oct 17, 2023
@erlend-aasland erlend-aasland requested a review from zooba January 6, 2024 21:18
@erlend-aasland erlend-aasland changed the title gh-85972: use native timeout for inet socket operations gh-85972: Use native timeout for inet socket operations Jan 6, 2024
Copy link
Member

@zooba zooba left a comment

Choose a reason for hiding this comment

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

A few code suggestions and comment typos, but otherwise looks good to me. I'm not a sockets programmer though, so I'd appreciate someone confirming that this is good across platforms and that the tests have it covered.

@@ -3421,6 +3540,13 @@ internal_connect(PySocketSockObject *s, struct sockaddr *addr, int addrlen,

/* save error, PyErr_CheckSignals() can replace it */
err = GET_SOCK_ERROR;

if (s->sock_timeout > 0) {
if (internal_setblocking(s, 1) < 0) {
Copy link
Member

Choose a reason for hiding this comment

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

Does this call not affect errno? And hence the following CHECK_ERRNO checks?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I checked and found that it does. Updated to use the pre-stored errno to avoid this.

aisk and others added 4 commits January 13, 2024 22:26
Co-authored-by: Steve Dower <steve.dower@microsoft.com>
Co-authored-by: Steve Dower <steve.dower@microsoft.com>
@aisk
Copy link
Contributor Author

aisk commented Jan 14, 2024

Thanks for the review! I added some note on the first comment of this PR.

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