(Also posted to mail list: http://curl.haxx.se/mail/lib-2013-03/0045.html)
While trying to use curl_multi_socket_action together with epoll I noticed that it didn't work in combination with HTTP redirect.
When a socket is first connected, CURLMOPT_SOCKETFUNCTION is called and the socket is added to the epoll set. Later on when libcurl connects to the HTTP server and sees the redirect it closes the socket (which makes the kernel remove the socket from the epoll set) and opens a new. Unfortunately this new socket gets the same number as the old, and thus the socket function callback is never called to add it to the epoll set.
Tested with libcurl from git: e305f5ec
OS: Linux 3.8.0 (Ubuntu 13.04) x86_64
How to reproduce:
Connect to http://127.0.0.1:9800 to be redirected to http://127.0.0.1:5400
# ./curlepoll http://127.0.0.1:9800 ... >>> calling epoll_wait >>> calling epoll_wait >>> calling epoll_wait ^C
It hangs in epoll_wait and must be aborted with Ctrl-C.
# ./curlepoll http://127.0.0.1:9800 poll ... >>> calling poll Hello Port 5400! >>> calling poll >>> socketCallback: removing fd=4 >>> bye bye
Works as expected.
httpserver.py
Thanks for your report. I haven't verified exactly this, but the problem you describe follow a pattern of bugs we've had before and I can see exactly how it happens. We need to fix this once and for all to make sure we don't keep on getting the same problem...
I hope you don't mind working with me a little here and testing out an idea of mine - I haven't actually tried to repeat the problem with your script etc yet.
Please try out the attached patch and see if it makes things better. It is an attempt to remove the socket properly on socket close so that the new one will be noticed properly and thus inform the callback as it should.
That patch worked perfectly with my test case. I now get a callback to remove the socket and one to add a new socket with the same file descriptor number.
Lovely, then it worked exactly as intended. I felt confident enough to push this to the git repo just now as commit 88c5c63ffc3312a8c.
Thanks for your test and verification. Case closed!