On Mon, 6 Jul 2009, Mohun Biswas wrote:

The docs say that curl_multi_perform will "transfer data on all current transfers in the multi stack that are ready to transfer anything". Now, assume a situation where the task is to upload a bunch of files. Each of those files will always be "ready" in select() terms

No they won't. Remember that libcurl deals with the only sockets for uploads and all sockets for upload will certainly not be "ready" at all times. It will depend on your bandwidth and the receiving servers' abilities to suck what you pass to them.

so I'd think that curl_multi_perform would start transfers on all of them.

It will start transfers on all it can, yes.

Meanwhile, CURLM_CALL_MULTI_PERFORM is said to be returned when "there may be more data to send off before it is satisfied".

Yes, if there's more stuff to do before select() gets called again.

As I interpret this, if curl_multi_perform is called in a loop

   while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(...));

the descriptors for the uploadable files will always be ready and this loop won't finish until they're all transferred.

That's incorrect.

The main unclarity is what it means to be "satisfied". Does it mean a buffer has been filled, or all available data has been read from the descriptor, or what? In what circumstances could it be satisfied while there's still unread data in the files?

The whole point with that phrasing is that it isn't specified. And I don't want to specify it either, and it shouldn't matter to the application.

CURLM_CALL_MULTI_PERFORM is simply returned to tell the app that you should call the *perform() function again before you decide to wait for any sockets, as there is more work to do and thus if you instead wait for socket events you risk waiting while there already is pending work in the pipes.

My program services input requests and then sends its output to a remote site using libcurl. The input must be handled in close to real time while output is less time sensitive. Thus the key point is that I don't ever want to be blocked from handing an input request while waiting for an output transfer to finish, and I'm having some trouble figuring out how to achieve such a thing with the multi API.

Just use it as documented and that's how it'll work. Of course, you'll get even less overhead if you instead use the socket_action() API but if you're only using a small amount of transfers the difference will be neglible.

--

 / daniel.haxx.se

Reply via email to