diff options
Diffstat (limited to 'lib/multi.c')
-rw-r--r-- | lib/multi.c | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/lib/multi.c b/lib/multi.c index 20fc372fa..557be06df 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -1491,7 +1491,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, data->set.buffer_size : BUFSIZE); timeout_ms = Curl_sleep_time(data->set.max_send_speed, data->progress.ulspeed, buffersize); - Curl_expire(data, timeout_ms); + Curl_expire_latest(data, timeout_ms); break; } @@ -1507,7 +1507,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, data->set.buffer_size : BUFSIZE); timeout_ms = Curl_sleep_time(data->set.max_recv_speed, data->progress.dlspeed, buffersize); - Curl_expire(data, timeout_ms); + Curl_expire_latest(data, timeout_ms); break; } @@ -1569,7 +1569,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* expire the new receiving pipeline head */ if(data->easy_conn->recv_pipe->head) - Curl_expire(data->easy_conn->recv_pipe->head->ptr, 1); + Curl_expire_latest(data->easy_conn->recv_pipe->head->ptr, 1); /* Check if we can move pending requests to send pipe */ Curl_multi_process_pending_handles(multi); @@ -2682,6 +2682,46 @@ void Curl_expire(struct SessionHandle *data, long milli) #endif } +/* + * Curl_expire_latest() + * + * This is like Curl_expire() but will only add a timeout node to the list of + * timers if there is no timeout that will expire before the given time. + * + * Use this function if the code logic risks calling this function many times + * or if there's no particular conditional wait in the code for this specific + * time-out period to expire. + * + */ +void Curl_expire_latest(struct SessionHandle *data, long milli) +{ + struct timeval *exp = &data->state.expiretime; + + struct timeval set; + + set = Curl_tvnow(); + set.tv_sec += milli/1000; + set.tv_usec += (milli%1000)*1000; + + if(set.tv_usec >= 1000000) { + set.tv_sec++; + set.tv_usec -= 1000000; + } + + if(exp->tv_sec || exp->tv_usec) { + /* This means that the struct is added as a node in the splay tree. + Compare if the new time is earlier, and only remove-old/add-new if it + is. */ + long diff = curlx_tvdiff(set, *exp); + if(diff > 0) + /* the new expire time was later than the top time, so just skip this */ + return; + } + + /* Just add the timeout like normal */ + Curl_expire(data, milli); +} + CURLMcode curl_multi_assign(CURLM *multi_handle, curl_socket_t s, void *hashp) { |