mirror of
https://github.com/moparisthebest/curl
synced 2024-12-24 09:08:49 -05:00
unpause: trigger a timeout for event-based transfers
... so that timeouts or other state machine actions get going again after a changing pause state. For example, if the last delivery was paused there's no pending socket activity. Reported-by: sstruchtrup on github Fixes #3994 Closes #4001
This commit is contained in:
parent
cf1ec70e72
commit
680f141332
@ -1038,8 +1038,11 @@ CURLcode curl_easy_pause(struct Curl_easy *data, int action)
|
|||||||
to have this handle checked soon */
|
to have this handle checked soon */
|
||||||
if(!result &&
|
if(!result &&
|
||||||
((newstate&(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) !=
|
((newstate&(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) !=
|
||||||
(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) )
|
(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) ) {
|
||||||
Curl_expire(data, 0, EXPIRE_RUN_NOW); /* get this handle going again */
|
Curl_expire(data, 0, EXPIRE_RUN_NOW); /* get this handle going again */
|
||||||
|
if(data->multi)
|
||||||
|
Curl_update_timer(data->multi);
|
||||||
|
}
|
||||||
|
|
||||||
/* This transfer may have been moved in or out of the bundle, update
|
/* This transfer may have been moved in or out of the bundle, update
|
||||||
the corresponding socket callback, if used */
|
the corresponding socket callback, if used */
|
||||||
|
52
lib/multi.c
52
lib/multi.c
@ -71,8 +71,6 @@
|
|||||||
|
|
||||||
static CURLMcode singlesocket(struct Curl_multi *multi,
|
static CURLMcode singlesocket(struct Curl_multi *multi,
|
||||||
struct Curl_easy *data);
|
struct Curl_easy *data);
|
||||||
static int update_timer(struct Curl_multi *multi);
|
|
||||||
|
|
||||||
static CURLMcode add_next_timeout(struct curltime now,
|
static CURLMcode add_next_timeout(struct curltime now,
|
||||||
struct Curl_multi *multi,
|
struct Curl_multi *multi,
|
||||||
struct Curl_easy *d);
|
struct Curl_easy *d);
|
||||||
@ -462,16 +460,16 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
|
|||||||
/* increase the alive-counter */
|
/* increase the alive-counter */
|
||||||
multi->num_alive++;
|
multi->num_alive++;
|
||||||
|
|
||||||
/* A somewhat crude work-around for a little glitch in update_timer() that
|
/* A somewhat crude work-around for a little glitch in Curl_update_timer()
|
||||||
happens if the lastcall time is set to the same time when the handle is
|
that happens if the lastcall time is set to the same time when the handle
|
||||||
removed as when the next handle is added, as then the check in
|
is removed as when the next handle is added, as then the check in
|
||||||
update_timer() that prevents calling the application multiple times with
|
Curl_update_timer() that prevents calling the application multiple times
|
||||||
the same timer info will not trigger and then the new handle's timeout
|
with the same timer info will not trigger and then the new handle's
|
||||||
will not be notified to the app.
|
timeout will not be notified to the app.
|
||||||
|
|
||||||
The work-around is thus simply to clear the 'lastcall' variable to force
|
The work-around is thus simply to clear the 'lastcall' variable to force
|
||||||
update_timer() to always trigger a callback to the app when a new easy
|
Curl_update_timer() to always trigger a callback to the app when a new
|
||||||
handle is added */
|
easy handle is added */
|
||||||
memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
|
memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
|
||||||
|
|
||||||
/* The closure handle only ever has default timeouts set. To improve the
|
/* The closure handle only ever has default timeouts set. To improve the
|
||||||
@ -484,7 +482,7 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
|
|||||||
data->state.conn_cache->closure_handle->set.no_signal =
|
data->state.conn_cache->closure_handle->set.no_signal =
|
||||||
data->set.no_signal;
|
data->set.no_signal;
|
||||||
|
|
||||||
update_timer(multi);
|
Curl_update_timer(multi);
|
||||||
return CURLM_OK;
|
return CURLM_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -774,7 +772,7 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
|
|||||||
We do not touch the easy handle here! */
|
We do not touch the easy handle here! */
|
||||||
multi->num_easy--; /* one less to care about now */
|
multi->num_easy--; /* one less to care about now */
|
||||||
|
|
||||||
update_timer(multi);
|
Curl_update_timer(multi);
|
||||||
return CURLM_OK;
|
return CURLM_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2107,7 +2105,7 @@ CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles)
|
|||||||
*running_handles = multi->num_alive;
|
*running_handles = multi->num_alive;
|
||||||
|
|
||||||
if(CURLM_OK >= returncode)
|
if(CURLM_OK >= returncode)
|
||||||
update_timer(multi);
|
Curl_update_timer(multi);
|
||||||
|
|
||||||
return returncode;
|
return returncode;
|
||||||
}
|
}
|
||||||
@ -2544,9 +2542,10 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Asked to run due to time-out. Clear the 'lastcall' variable to force
|
/* 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
|
Curl_update_timer() to trigger a callback to the app again even if the
|
||||||
timeout is still the one to run after this call. That handles the case
|
same timeout is still the one to run after this call. That handles the
|
||||||
when the application asks libcurl to run the timeout prematurely. */
|
case when the application asks libcurl to run the timeout
|
||||||
|
prematurely. */
|
||||||
memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
|
memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2664,7 +2663,7 @@ CURLMcode curl_multi_socket(struct Curl_multi *multi, curl_socket_t s,
|
|||||||
return CURLM_RECURSIVE_API_CALL;
|
return CURLM_RECURSIVE_API_CALL;
|
||||||
result = multi_socket(multi, FALSE, s, 0, running_handles);
|
result = multi_socket(multi, FALSE, s, 0, running_handles);
|
||||||
if(CURLM_OK >= result)
|
if(CURLM_OK >= result)
|
||||||
update_timer(multi);
|
Curl_update_timer(multi);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2676,7 +2675,7 @@ CURLMcode curl_multi_socket_action(struct Curl_multi *multi, curl_socket_t s,
|
|||||||
return CURLM_RECURSIVE_API_CALL;
|
return CURLM_RECURSIVE_API_CALL;
|
||||||
result = multi_socket(multi, FALSE, s, ev_bitmask, running_handles);
|
result = multi_socket(multi, FALSE, s, ev_bitmask, running_handles);
|
||||||
if(CURLM_OK >= result)
|
if(CURLM_OK >= result)
|
||||||
update_timer(multi);
|
Curl_update_timer(multi);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2688,7 +2687,7 @@ CURLMcode curl_multi_socket_all(struct Curl_multi *multi, int *running_handles)
|
|||||||
return CURLM_RECURSIVE_API_CALL;
|
return CURLM_RECURSIVE_API_CALL;
|
||||||
result = multi_socket(multi, TRUE, CURL_SOCKET_BAD, 0, running_handles);
|
result = multi_socket(multi, TRUE, CURL_SOCKET_BAD, 0, running_handles);
|
||||||
if(CURLM_OK >= result)
|
if(CURLM_OK >= result)
|
||||||
update_timer(multi);
|
Curl_update_timer(multi);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2748,14 +2747,14 @@ CURLMcode curl_multi_timeout(struct Curl_multi *multi,
|
|||||||
* Tell the application it should update its timers, if it subscribes to the
|
* Tell the application it should update its timers, if it subscribes to the
|
||||||
* update timer callback.
|
* update timer callback.
|
||||||
*/
|
*/
|
||||||
static int update_timer(struct Curl_multi *multi)
|
void Curl_update_timer(struct Curl_multi *multi)
|
||||||
{
|
{
|
||||||
long timeout_ms;
|
long timeout_ms;
|
||||||
|
|
||||||
if(!multi->timer_cb)
|
if(!multi->timer_cb)
|
||||||
return 0;
|
return;
|
||||||
if(multi_timeout(multi, &timeout_ms)) {
|
if(multi_timeout(multi, &timeout_ms)) {
|
||||||
return -1;
|
return;
|
||||||
}
|
}
|
||||||
if(timeout_ms < 0) {
|
if(timeout_ms < 0) {
|
||||||
static const struct curltime none = {0, 0};
|
static const struct curltime none = {0, 0};
|
||||||
@ -2763,9 +2762,10 @@ static int update_timer(struct Curl_multi *multi)
|
|||||||
multi->timer_lastcall = none;
|
multi->timer_lastcall = none;
|
||||||
/* there's no timeout now but there was one previously, tell the app to
|
/* there's no timeout now but there was one previously, tell the app to
|
||||||
disable it */
|
disable it */
|
||||||
return multi->timer_cb(multi, -1, multi->timer_userp);
|
multi->timer_cb(multi, -1, multi->timer_userp);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* When multi_timeout() is done, multi->timetree points to the node with the
|
/* When multi_timeout() is done, multi->timetree points to the node with the
|
||||||
@ -2773,11 +2773,11 @@ static int update_timer(struct Curl_multi *multi)
|
|||||||
* if this is the same (fixed) time as we got in a previous call and then
|
* if this is the same (fixed) time as we got in a previous call and then
|
||||||
* avoid calling the callback again. */
|
* avoid calling the callback again. */
|
||||||
if(Curl_splaycomparekeys(multi->timetree->key, multi->timer_lastcall) == 0)
|
if(Curl_splaycomparekeys(multi->timetree->key, multi->timer_lastcall) == 0)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
multi->timer_lastcall = multi->timetree->key;
|
multi->timer_lastcall = multi->timetree->key;
|
||||||
|
|
||||||
return multi->timer_cb(multi, timeout_ms, multi->timer_userp);
|
multi->timer_cb(multi, timeout_ms, multi->timer_userp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -30,6 +30,7 @@ void Curl_updatesocket(struct Curl_easy *data);
|
|||||||
void Curl_expire(struct Curl_easy *data, time_t milli, expire_id);
|
void Curl_expire(struct Curl_easy *data, time_t milli, expire_id);
|
||||||
void Curl_expire_clear(struct Curl_easy *data);
|
void Curl_expire_clear(struct Curl_easy *data);
|
||||||
void Curl_expire_done(struct Curl_easy *data, expire_id id);
|
void Curl_expire_done(struct Curl_easy *data, expire_id id);
|
||||||
|
void Curl_update_timer(struct Curl_multi *multi);
|
||||||
void Curl_detach_connnection(struct Curl_easy *data);
|
void Curl_detach_connnection(struct Curl_easy *data);
|
||||||
void Curl_attach_connnection(struct Curl_easy *data,
|
void Curl_attach_connnection(struct Curl_easy *data,
|
||||||
struct connectdata *conn);
|
struct connectdata *conn);
|
||||||
|
Loading…
Reference in New Issue
Block a user