cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: Select returns -1 on all the multi examples in win32

From: Ray Satiro <raysatiro_at_yahoo.com>
Date: Fri, 14 Nov 2014 04:07:53 -0500

On 11/13/2014 1:59 PM, Daniel Stenberg wrote:
> On Thu, 13 Nov 2014, JOHAN LANTZ wrote:
>
>> However moving to the multi examples, I do not manage to download
>> anything. There are no errors for the api calls setting things up but
>> I always end up at this print: printf("select() returns error, this
>> is badness\n");
>
> I guess that is when maxfd is -1 and there are no file descriptors to
> wait for?
>

Yeah. On Windows select() will return -1 and winsock error code
WSAEINVAL in that case. The documentation for Windows' select() [1] says:

"Any two of the parameters, readfds, writefds, or exceptfds, can be
given as null. At least one must be non-null, and any non-null
descriptor set must contain at least one handle to a socket."

Their remarks for the WSAEINVAL error code isn't as encompassing but
that's what happens. So it won't sleep via select() unless you use a
dummy socket. You could instead call Windows' Sleep(). Its resolution
isn't that granular but I think it's fine for this. The documentation
for curl_multi_fdset() [2] says the recommended time is 100ms at least:

"When libcurl returns -1 in max_fd, it is because libcurl currently does
something that isn't possible for your application to monitor with a
socket and unfortunately you can then not know exactly when the current
action is completed using select(). You then need to wait a while before
you proceed and call curl_multi_perform anyway. How long to wait? We
suggest 100 milliseconds at least, but you may want to test it out in
your own particular conditions to find a suitable value."

I have attached a patch which fixes the multi examples for use on
Windows by sleeping 100ms whenever curl_multi_fdset() doesn't set any
file descriptors. I also added a check on its return value because why
not. Alternatively if you want to get closer to what select() would do
use a dummy socket or something like Sleep((DWORD)(timeout.tv_sec * 1000
+ timeout.tv_usec / 1000)) assuming you have a valid timeval.

Also- The examples are inconsistent on whether or not they notify of
select error.

[1]: http://msdn.microsoft.com/en-us/library/windows/desktop/ms740141.aspx
[2]: http://curl.haxx.se/libcurl/c/curl_multi_fdset.html

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html

  • text/plain attachment: stored
Received on 2014-11-14