curl / Mailing Lists / curl-library / Single Mail
Buy commercial curl support from WolfSSL. We help you work out your issues, debug your libcurl applications, use the API, port to new platforms, add new features and more. With a team lead by the curl founder himself.

Re: curl_multi_timeout and the multi_socket API

From: Fulup Ar Foll via curl-library <>
Date: Sun, 4 Apr 2021 00:06:30 +0200
I'm not sure to understand your logic. If you have to call curl_multi_timeout() at each iteration of your mainloop your logic should be wrong.

I also mix curl-socket with multiple other classes of sockets and do no call call curl_multi_timeout() at each iteration.

In my sample the eventloop call 'glueOnSocketCB' as soon as a curlsocket is readable. 'glueOnSocketCB' map mainloop event-names to curl-events name before calling 'httpOnSocketCB' that finally call curl_multi_socket_action to do the job. If you do so, you do not have to call curl_multi_socket_action. The secret is to map your main loop event-name to curl-names.

In my code 'glueOnSocketCB' is attached to mainloop within glueSetSocketCB that is called from multiSetSockCB. This last one is call from curl with " curl_multi_setopt(httpPool->multi, CURLMOPT_SOCKETFUNCTION, multiSetSockCB);"

For the timer you do not need an external lib, you may use timerfd and epool is just as find as any other mainloop. In my case I use systemd mainloop, because this what the rest of the application uses. I did libuv to make sure my code was independent of the mainloop, in case app developper would like to change in the future. I did not port for epool/timerfd, but I'm sure that it would not take more that few hours.

On 03/04/2021 23:13, Henrik Holst wrote:

Den lör 3 apr. 2021 kl 22:56 skrev Fulup Ar Foll <>:

I posted this sample on github because I lost too many hours searching for curl logic in the documentation. You have to respect curl_timeout, nevertheless if your mainloop works well, it should be call only once per download. In my case I do not wait 1ms before initial call and everything works perfectly well.
I was not speaking about waiting 1ms before the initial call, it was just an observation that the timer function callback was very often being called with timeout=0, timeout=1, timeout=-1 and that timeout=1 was the cause of my initial troubles since calling epoll_wait with 1ms timeout made it never return 0 to indicate timeout (since some other sockets that I had in the same epoll had recv traffic more often than that). Relying on epoll_wait() returning 0 works flawless if one only have curl sockets in the epoll so it was faulty logic when the application was expanded beyond handling only curl requests.

Anyway I've redone the logic anyway to minimize the overhead penalty of calling curl_multi_timeout() on each iteration of the main event loop and now actually uses the timer callback but instead of relying on epoll_wait() returning 0 I calculate when the timeout have timed out against the wallclock (clock_gettime() + timeout from the callback), and check that instead which I of course should have done from the beginning. That way the overhead is minimized (just a call to clock_gettime() wich for this specific implementation is overhead that I can live with) and there is no need for any external timers or event libs, just bog standard epoll.


Received on 2021-04-04