You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
My immediate impression is that there's a missing Zero-init of its. I think it's supposed to be covering the default case. I will investigate further and try to recall.
I see that just below you actually test the value of timeout and set its accordingly, before calling timerfd_settime. So it seems to me that this line 156 is not wanted, but then again I'm not familiar with libcurl yet, so maybe I'm missing something.
Yeah it looks fishy. I think you might be right. I think it might be leftovers of some code that was moved into the else block. I feel like the timer should be disarmed in the ==0 case too though...
I seem to recall having to iterate on this function a few times. I think there was some trickiness in here where I didn't fully understand the semantics of timeout_ms==0. Based on the description of CURLMOPT_TIMERFUNCTION
A timeout_ms value of -1 passed to this callback means you should delete the timer. All other values are valid expire times in number of milliseconds.
I think it's a little ambiguous what to do in a timout_ms == 0 case. I'm pretty sure we need to service curl_multi_socket_action in this case. Perhaps we also want to disarm the timer. So should we disarm if timeout_ms <= 0 instead of just < 0? It's not a big deal either way, we'll just service the curl_multi_socket_action one time more than it wanted to in the worst case.
Anyhow, I think that yes, line 156 should be removed.
In the timout_ms == 0 case, that's a valid timer expiry meaning "now". But unless the event system needs it, there's no need to special-case the zero. In fact, I've updated other examples to avoid the recursive call back into libcurl from within the callback itself so I would prefer if we could rewrite the callback (including your above mentioned bug-fix) to look like this:
/* Update the timer after curl_multi library does it's thing. Curl will * inform us through this callback what it wants the new timeout to be, * after it does some work. */staticintmulti_timer_cb(CURLM*multi, longtimeout_ms, GlobalInfo*g)
{
structitimerspecits;
CURLMcoderc;
fprintf(MSG_OUT, "multi_timer_cb: Setting timeout to %ld ms\n", timeout_ms);
if(timeout_ms >= 0) {
its.it_interval.tv_sec=1;
its.it_interval.tv_nsec=0;
its.it_value.tv_sec=timeout_ms / 1000;
its.it_value.tv_nsec= (timeout_ms % 1000) *1000;
timerfd_settime(g->tfd, /*flags=*/0, &its, NULL);
}
else {
memset(&its, 0, sizeof(structitimerspec));
timerfd_settime(g->tfd, /*flags=*/0, &its, NULL);
}
return0;
}
Activity
cheshirekow commentedon Mar 1, 2019
My immediate impression is that there's a missing Zero-init of
its. I think it's supposed to be covering the default case. I will investigate further and try to recall.elboulangero commentedon Mar 1, 2019
I see that just below you actually test the value of
timeoutand setitsaccordingly, before callingtimerfd_settime. So it seems to me that this line 156 is not wanted, but then again I'm not familiar with libcurl yet, so maybe I'm missing something.cheshirekow commentedon Mar 1, 2019
Yeah it looks fishy. I think you might be right. I think it might be leftovers of some code that was moved into the else block. I feel like the timer should be disarmed in the
==0case too though...cheshirekow commentedon Mar 1, 2019
I seem to recall having to iterate on this function a few times. I think there was some trickiness in here where I didn't fully understand the semantics of
timeout_ms==0. Based on the description ofCURLMOPT_TIMERFUNCTIONI think it's a little ambiguous what to do in a
timout_ms == 0case. I'm pretty sure we need to servicecurl_multi_socket_actionin this case. Perhaps we also want to disarm the timer. So should we disarm iftimeout_ms <= 0instead of just< 0? It's not a big deal either way, we'll just service thecurl_multi_socket_actionone time more than it wanted to in the worst case.Anyhow, I think that yes, line 156 should be removed.
bagder commentedon Mar 1, 2019
In the
timout_ms == 0case, that's a valid timer expiry meaning "now". But unless the event system needs it, there's no need to special-case the zero. In fact, I've updated other examples to avoid the recursive call back into libcurl from within the callback itself so I would prefer if we could rewrite the callback (including your above mentioned bug-fix) to look like this:elboulangero commentedon Mar 1, 2019
Actually you need a special case here, because from
timerfd_create(2):Setting both fields of new_value.it_value to zero disarms the timer.One possible way is to to set
its.it_value.tv_nsec = 1, i've seen that insystemdevent loop for example:https://github.com/systemd/systemd/blob/8e4fbe3f2dbbe1a358976316057e52145e102b64/src/libsystemd/sd-event/sd-event.c#L2990-L2997
On the other hand,
libeventhandles it as a special case:https://github.com/libevent/libevent/blob/master/epoll.c#L434-L438