multi_socket: remind app if timeout didn't run
BACKGROUND: We have learned that on some systems timeout timers are inaccurate and might occasionally fire off too early. To make the multi_socket API work with this, we made libcurl execute timeout actions a bit early too if they are within our MULTI_TIMEOUT_INACCURACY. (added in commit2c72732ebf
, present since 7.21.0) Switching everything to the multi API made this inaccuracy problem slightly more notable as now everyone can be affected. Recently (commit21091549c0
) we tweaked that inaccuracy value to make timeouts more accurate and made it platform specific. We also figured out that we have code at places that check for fixed timeout values so they MUST NOT run too early as then they will not trigger at all (see commitbe28223f35
anda691e04470
) - so there are definitately problems with running timeouts before they're supposed to run. (We've handled that so far by adding the inaccuracy margin to those specific timeouts.) The libcurl multi_socket API tells the application with a callback that a timeout expires in N milliseconds (and it explicitly will not tell it again for the same timeout), and the application is then supposed to call libcurl when that timeout expires. When libcurl subsequently gets called with curl_multi_socket_action(...CURL_SOCKET_TIMEOUT...), it knows that the application thinks the timeout expired - and alas, if it is within the inaccuracy level libcurl will run code handling that handle. If the application says CURL_SOCKET_TIMEOUT to libcurl and _isn't_ within the inaccuracy level, libcurl will not consider the timeout expired and it will not tell the application again since the timeout value is still the same. NOW: This change introduces a modified behavior here. If the application says CURL_SOCKET_TIMEOUT and libcurl finds no timeout code to run, it will inform the application about the timeout value - *again* even if it is the same timeout that it already told about before (although libcurl will of course tell it the updated time so that it'll still get the correct remaining time). This way, we will not risk that the application believes it has done its job and libcurl thinks the time hasn't come yet to run any code and both just sit waiting. This also allows us to decrease the MULTI_TIMEOUT_INACCURACY margin, but that will be handled in a separate commit. A repeated timeout update to the application risk that the timeout will then fire again immediately and we have what basically is a busy-loop until the time is fine even for libcurl. If that becomes a problem, we need to address it.
This commit is contained in:
parent
041d1e14d6
commit
980659a2ca
@ -2233,6 +2233,13 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
|
||||
multi_runsingle() in case there's no need to */
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Asked to run due to time-out. Clear the 'lastcall' variable to force
|
||||
update_timer() to trigger a callback to the app again even if the same
|
||||
timeout is still the one to run after this call. That handles the case
|
||||
when the application asks libcurl to run the timeout prematurely. */
|
||||
memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
|
||||
}
|
||||
|
||||
/* Compensate for bad precision timers that might've triggered too early.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user