-
Notifications
You must be signed in to change notification settings - Fork 75
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
Fix issue with long timeouts in TCP connect() #210
base: master
Are you sure you want to change the base?
Conversation
❌ Build asyn 1.0.272 failed (commit 770913eff7 by @MarkRivers) |
asyn/drvAsynSerial/drvAsynIPPort.c
Outdated
@@ -520,6 +532,9 @@ connectIt(void *drvPvt, asynUser *pasynUser) | |||
tty->flags |= FLAG_NEED_LOOKUP; | |||
return asynError; | |||
} | |||
if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&saveTV, sizeof saveTV) < 0) { | |||
asynPrint(pasynUser, ASYN_TRACE_ERROR, "connectIt, error calling setsockopt for SO_RECVTIMEO: %s\n", strerror(SOCKERRNO)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All 3 error messages are using the wrong option name (RECV instead of SND).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I fixed that, thanks for catching it.
It does not appear to be supported for connect() on Windows, and takes a different argument. Note sure about vxWorks and RTEMS, they could be added later. Fix typo in error messages.
I read the documentation for SO_SNDTIMEO on Windows.
I have restricted the use of SO_SNDTIMEO to Linux. RTEMS, vxWorks, and Darwin could be added if it is implemented on them. |
If we want a solution that could work on more platforms, why not use poll? Like https://stackoverflow.com/a/61960339 does it (I don't know if the signal handling is even necessary for asyn, which would greatly simplify that code). Especially since Linux always supports poll, it would be a single code path for most platforms. |
The |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks reasonable to me. I assume you'll be documenting the additional asynManager method before release.
I am thinking about Darwin. This document
It is not clear to me whether or not this applies to connect(). I think I will enable it for darwin. Can anyone test? |
I can run tests on Darwin-x86 and/or Darwin-aarch64 if you can tell me exactly what needs doing. You could also add a MacOS entry to the BTW there seems to be a duplicate job defined in the |
@anjohnson yes, but this function already uses Right now we have linux and (possibly) MacOS support. If we use And since the |
@ericonr I would be happy to look at an alternative PR that is tested on Linux, Windows, and Darwin. |
@MarkRivers @anjohnson would you mind taking a look at the latest commit in https://github.com/lnls-dig/asyn/commits/nonblocking-connect-poll/ ? I don't have an easily available Windows machine to test (much less MacOS), but if you are okay with the approach there, I can set up a Windows environment in order to test it there. |
❌ Build asyn 1.0.275 failed (commit f087da5a63 by @MarkRivers) |
@ericonr You probably want to put a loop around
Do any of the unit tests cover IPPort? If so, then maybe this is already covered by a CI build. |
❌ Build asyn 1.0.277 failed (commit 8059e41b78 by @MarkRivers) |
❌ Build asyn 1.0.279 failed (commit 81ad3bbcdf by @MarkRivers) |
❌ Build asyn 1.0.281 failed (commit 3f2175fb92 by @MarkRivers) |
@mdavidsaver That would require using considerably more code to sleep for the correct amount of time, to support an abnormal case (if this connection is interrupted, it can simply be tried again). Furthermore, the version here, which uses blocking connect with a timeout, is subject to being interrupted by signals as well, no? |
@ericonr To avoid confusion, it might be a good idea to move this discussion to a draft PR for your alternate change.
You make a fair point. I suppose looping could be omitted so long as the |
This PR sets the sockopt SO_SNDTIMEO to the time set by pasynManager->setAutoConnectTimeout() during the call to connect(). This allows must faster timeouts than the system default. It has been tested on Linux and Windows.