Daniel Stenberg a écrit :
On Tue, 5 Jan 2010, Daniel Stenberg wrote:
I think this is because you're using the default (synchronous) name
resolver within libcurl, and during the name resolving libcurl has no
socket handler to "export". As soon as the resolving is done, libcurl
creates a socket and then it _can_ return something in curl_multi_fdset.
No, I'm wrong. During the name resolve the curl_multi_perform() will
actually block... Thinking further about this, I can't really explain
it. I guess I need to do some tests of my own first to understand what
you're describing...
In fact, this is not related to the DNS. Here is my test program and the
output log. It may help to understand the problem. As you can see, I
often have no file descriptor set and my "select" is blocking until the
timeout occurs (so the connection is slower, the only workaround I have
to get things faster is to do a busy loop until I have a correct fdset,
or to put a shorter timeout on select)
int main(int argc, char **argv)
{
CURL *sftp_handle;
CURLM *multi_handle;
CURLMcode ret;
int still_running;
sftp_handle = curl_easy_init();
curl_easy_setopt(sftp_handle, CURLOPT_URL,
"sftp://172.25.110.46/cygdrive/c/Temp/file.txt");
curl_easy_setopt(sftp_handle, CURLOPT_USERPWD, "user:password");
curl_easy_setopt(sftp_handle, CURLOPT_VERBOSE, 1);
multi_handle = curl_multi_init();
curl_multi_add_handle(multi_handle, sftp_handle);
printf("%ld : begin...\n", time(NULL));
while(CURLM_CALL_MULTI_PERFORM ==
curl_multi_perform(multi_handle, &still_running));
while(still_running) {
struct timeval timeout;
int rc;
fd_set fdread;
fd_set fdwrite;
fd_set fdexcep;
int maxfd;
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_ZERO(&fdexcep);
ret = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep,
&maxfd);
printf("%ld : %d process running, maxfd = %d, ret = %d\n",
time(NULL), still_running, maxfd, ret);
timeout.tv_sec = (maxfd == -1) ? 2 : 30;
timeout.tv_usec = 0;
rc = select(50, &fdread, &fdwrite, &fdexcep, &timeout);
switch(rc) {
case -1:
still_running = 0;
printf("select() returns error, this is badness\n");
break;
case 0:
default:
while(CURLM_CALL_MULTI_PERFORM ==
curl_multi_perform(multi_handle, &still_running));
break;
}
}
curl_multi_cleanup(multi_handle);
curl_easy_cleanup(sftp_handle);
return 0;
}
And the log :
1262681772 : begin...
* About to connect() to 172.25.110.46 port 22 (#0)
* Trying 172.25.110.46... * connected
* Connected to 172.25.110.46 (172.25.110.46) port 22 (#0)
* Expire cleared
1262681774 : 1 process running, maxfd = -1, ret = 0
1262681776 : 1 process running, maxfd = 3, ret = 0
* SSH authentication methods available:
publickey,password,keyboard-interactive
1262681780 : 1 process running, maxfd = -1, ret = 0
* Using ssh public key file /root/.ssh/id_dsa.pub
* Using ssh private key file /root/.ssh/id_dsa
1262681782 : 1 process running, maxfd = -1, ret = 0
* SSH public key authentication failed: Unable to open public key file
1262681784 : 1 process running, maxfd = -1, ret = 0
1262681786 : 1 process running, maxfd = -1, ret = 0
1262681788 : 1 process running, maxfd = 3, ret = 0
* Initialized password authentication
1262681789 : 1 process running, maxfd = -1, ret = 0
* Authentication complete
1262681791 : 1 process running, maxfd = -1, ret = 0
1262681793 : 1 process running, maxfd = 3, ret = 0
1262681793 : 1 process running, maxfd = 3, ret = 0
1262681793 : 1 process running, maxfd = 3, ret = 0
1262681798 : 1 process running, maxfd = -1, ret = 0
1262681800 : 1 process running, maxfd = 3, ret = 0
1262681800 : 1 process running, maxfd = -1, ret = 0
1262681802 : 1 process running, maxfd = -1, ret = 0
1262681804 : 1 process running, maxfd = 3, ret = 0
1262681804 : 1 process running, maxfd = -1, ret = 0
1262681806 : 1 process running, maxfd = 3, ret = 0
1262681806 : 1 process running, maxfd = 3, ret = 0
* Expire cleared
* Connection #0 to host 172.25.110.46 left intact
file.txt content
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html