cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: new multi interface functions, continued

From: Justin Hammond <justin_at_dynam.ac>
Date: Thu, 10 Mar 2005 15:22:35 +0000 (UTC)

Jamie Lokier <jamie_at_shareable.org> wrote:
>Daniel Stenberg wrote:
<snip>
>> >Another option that might be worthwhile considering is having
>> >curl_multi_update called only once when initilizing curl, and then curl
>> >itself calling the curl_socket_callback when there are changes internally
>> >by curl automatically. This avoids on extra call on each loop, and would
>> >make curl integrate a lot easier (as well I suspect, have a minor
>> >performance boost around the mainloop area, but its *debatable* if the
>> >extra overhead for curl to check the socket status at the end of each of
>> >its iterations will offset any further performance boost)
>>
>> The reason I didn't integrate it, is that I was thinking that _always_
>> calling the callback on socket changes might cause a lot of extra calls
>> since a socket change might get changed again later before the app get a
>> chance to wait for anything on it.
>
>Why would it call the callback more often?
>
>Why not, in effect, call curl_multi_update() at the end of each call
>to curl_multi_socket(), just before it returns?
>
>In most cases, that will call the callback once per fd, if there have
>been any changes for that fd. Occasionally it will call the callback
>for a different, related fd (e.g. due to the two sockets for FTP being
>related). Either way, that's not likely to call the callback much
>more times than a separate curl_multi_update() in the event loop, is it?
>

My only comment on this one is that when a new curl transfer is started,
ideally the application would have to call curl_multi_update as well... but if
Curl already knows about the callback, why not have curl automatically call the
callback before returning to the application space?
This way, you might end up with something along these lines:

typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */
                                    curl_socket_t s, /* socket */
                                    int what, /* see above */
                                    long milliseconds, /* timeout for this wait
*/
                                    void *userp); /* "private" pointer */

curl_multi_socket_init(CURLM *multihandle, curl_socket_callback call, void
*userp);
and
curl_multi_socket(CurlM *multi(easy)handle?, curl_socket_s fd, int what);

Then it looks like:

curl_socket_callback(easyhandle, socket, what, timeout, userp) {
addsocket(socket, what, curl_multi_socket(), timeout, easyhandle);
}

main()
curl_multi_socket_init( multihandle, curl_socket_callback, NULL);
/* start a new transfer which will automatically call the callback above with
the sockets its interested in before returning control to the application */
easy = curl_easy_init();
runmainloop();
exit(1);
}

This way the user doesn't ever have to worry about running curl_multi_socket()
to get a updated list of FD's that curl has some interest in, curl makes the
callback itself?

even if curl does update the sockets a few times, the overhead shouldnt be as
great as having to call curl_multi_socket on each run of the loop. Imagine Curl
with a few thousand connections, and only updates to maybe 2 or 3 sockets its
interested in. Calling curl_multi_socket to check for differences on those few
thousand connections might be a hit in performance when its only updating the
status for a small amount of sockets, whereas, if you can trigger the callback
to the easy interface socket code directly, then it doesn't suffer from that
performance overhead, and you might even be able to get away without the need
of using a hash to store the current states of the socket?

Otherwise, I got a feeling you might just be shifting the performance problems
from the applications "Select" based implementation (or whatever wrappers they
use) to curl itself... :)
Received on 2005-03-10