-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
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
On MacOS, if a remote socket is closed while curl is connecting to it, the program will spin until the connection timeout elapses #7595
Comments
What does your sample code need to build? I tried |
I forgot to mention that you need to compile it with |
I can't reproduce, but I have a few other versions in my env:
Presumably, my kernel version doesn't behave the same as yours... |
I reran the test with a fresh 7.78.0 build (bfbde88) but again it doesn't reproduce. |
This doesn't reproduce in Windows but that's probably because Curl_poll emulates poll with select. It looks like this: ufds[i].events: 1040 POLLOUT (POLLWRNORM) | POLLPRI |
That's odd, because it happens to me on kernel 20.6.0. Maybe it's affected by the build method? I'm building with cmake, with the variables I've also bisected it, and it seems to have been introduced in commit e21bd22, which makes sense since that's when |
I built with configure, but I can't see how that would change these things. Does reverting that commit fix things for you? @mback2k, do you recall if you brought |
Yes, reverting that commit fixes the issue. |
The original commit says it was needed for "poll()" to detect connection problems, but we've used poll for many years before that without problems to detect connect problems... |
Uh-oh. I think we can take this in another direction. poll() should not be used on macOS, because Apple keeps messing it up and we avoid it on configure builds. That's why I didn't spot any problem with this! This is yet another bug in the cmake build... |
... like we do in configure builds. Since poll() on macOS is not reliable enough. Reported-by: marc-groundctl Fixes #7595
I did this
Compiled and ran the following program:
I expected the following
The program should exit almost immediately, since it is attempting to communicate with a closed socket
What actually happened
The program consumed an entire CPU core for 5 minutes before the connection timed out.
This only happens on Mac; Linux works fine.
The issue appears to be that when waiting for the socket to be ready,
multi_wait
callspoll
withevents
set toPOLLOUT
, and the OS setsrevents
toPOLLOUT
and returns immediately. However, whenmulti_runsingle
callspoll
it setsevents
toPOLLOUT|POLLPRI
and the OS setsrevents
toPOLLHUP|POLLPRI
. Curl interprets thePOLLHUP
as an error, but then whenverifyconnect
checksSO_ERROR
it gets back 0 so it assumes that there wasn't actually an error. Becauserevents
didn't containPOLLOUT
curl thinks that it needs to wait for the socket to be writable, so it callsmulti_wait
and the cycle repeats until the connect timeout elapses.curl/libcurl version
I built curl off of commit bfbde88
operating system
Darwin NYC-L5169-MAC.local 19.5.0 Darwin Kernel Version 19.5.0: Tue May 26 20:41:44 PDT 2020; root:xnu-6153.121.2~2/RELEASE_X86_64 x86_64 i386 MacBookPro16,1 Darwin
The text was updated successfully, but these errors were encountered: