CURL *handle as described above, but with the multi interface you also need a multi
CURLM *handle created and use that to drive all the individual transfers. The multi handle can "hold" one or many easy handles:
curl_multi_setopt(), but in the simplest case you might not have anything to set there.
select()call yourself, or you can use the slightly simplified version which does that for us, with
curl_multi_wait. The simplest loop could look like this: (note that a real application would check return codes)
curl_multi_wait, set to 1000 in the example above, is a timeout in milliseconds. It is the longest time the function will wait for any activity before it returns anyway. You do not want to lock up for too long before calling
curl_multi_performagain as there are timeouts, progress callbacks and more that may lose precision if you do so.
curl_multi_info_read(), which will return a pointer to a struct (a "message") if a transfer has ended and you can then find out the result of that transfer using that struct.
curl_multi_performinvocation and then you might need more than one call to
curl_multi_info_readto get info about each completed transfer.