cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: new multi interface functions, continued

From: Justin Hammond <justin_at_dynam.ac>
Date: Wed, 9 Mar 2005 20:06:35 +0800

Hi Daniel,
I saw your post about the new multi interface your planning for Curl. I wait
with anticipation on it being committed.

The only thing I think I can offer as a option to consider is that the
Curl_socket_callback function should also be passed a timeout, so If people
use curl_multi_update after they submit the request to Curl, and
curl_socket_callback specifies a timeout, then at least if there no activity
on any of the curl sockets with X seconds (or whatever) we can still call
curl_multi_socket when the timeout expires.

You might be thinking, but the curl_multi_* functions are called on every
loop of the mainloop, well, if you look at at lot of the event libraries,
they wrap up the entire mainloop, and its difficult to get our own functions
included into the mainloop. In the case of libevent, the only way would be
to create a Timer in libevent that curls curl_multi_update every 0(!)
seconds

This avoids the cases in those applications where Curl is not the main *HOG*
on network communications. It will allow us to only call
curl_multi_update/curl_multi_socket when we know there is going to be some
curl activity rather than every loop of the mainloop

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)

Then only when there is socket or a timeout for Curl, we call
curl_multi_socket?

(P.S: I watch the mailing lists via Gname rather than being subscribed to
the list, but thought about posting this to you as I felt it was important.)

Thanks

Justin

Hi

Now we're down to details on the new functions for the multi interface
that'll
allows apps to use other functions than select() and that should enable us
to
build a more high-performance multi libcurl.

We're actually down to two only new functions. See the example app near the
end. As usual, comments are more than welcome!

/* our public socket type */
#ifdef WIN32
typedef SOCKET curl_socket_t;
#else
typedef int curl_socket_t;
#endif

/*
   curl_multi_update()

   Requests an update of the socket (file descriptor) status by getting
none,
   one or multiple calls to the callback. It updates the status with changes
   since the previous time this function was used.

   The "what" argument has one of five values:

    0 CURL_POLL_NONE (0) - register, not interested in
readiness
    1 CURL_POLL_IN - register, interested in read
readiness
    2 CURL_POLL_OUT - register, interested in write
readiness
    3 CURL_POLL_IN | CURL_POLL_OUT - register, interested in both
    4 CURL_POLL_REMOVE - deregister

*/
#define CURL_POLL_NONE 0
#define CURL_POLL_IN (1<<0)
#define CURL_POLL_OUT (1<<1)
#define CURL_POLL_REMOVE (1<<2)

typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */
                                     curl_socket_t s, /* socket */
                                     int what, /* see above */
                                     void *userp); /* "private" pointer
*/

CURLMcode curl_multi_update(CURLM *multi_handle,
                             curl_socket_callback callback,
                             void *userp); /* anything you want to pass to
the
                                              callback */

/*
   curl_multi_socket()

   An alternative version of curl_multi_perform() that allows the
application
   to pass in one of the file descriptors that have been detected to have
   "action" on them and let libcurl perform. This allows libcurl to not have
to
   scan through all possible file descriptors to check for this.

   NOTE: with this prototype, libcurl will need an internal hash table to
map
   socket numbers to internal easy handles.

*/
CURLMcode curl_multi_socket(CURLM *multi_handle
                             curl_socket_t s,
                             int what);

/* Example (pseudo) code: */

  while ( still_running ) {

    curl_multi_update() /* get the callback called multiple times so that we
                           know what to wait for */

    /* Wait for action, on libcurl's sockets and on our own set of things.
       This can use select(), poll() or whatever high-performance polling
       function your particular OS provides */

    wait( ); /* with a timeout */

    /* When the wait is done, either by an action or by a timeout */

    while( list of action-sockets ) {

      curl_multi_socket(); /* pass on information to libcurl about what
                              action this file descriptors had */

    }

  }

-- 
      Daniel Stenberg -- http://curl.haxx.se -- http://daniel.haxx.se
       Dedicated custom curl help for hire: http://haxx.se/curl.
Received on 2005-03-09