Skip to content

Commit

Permalink
multi_runsingle: don't timeout completed handles
Browse files Browse the repository at this point in the history
The generic timeout code must not check easy handles that are already
completed. Going to completed (again) within there risked decreasing the
number of alive handles again and thus it could go negative.

This regression bug was added in 7.21.2 in commit ca10e28
  • Loading branch information
bagder committed Dec 13, 2010
1 parent 012f9b7 commit 0fd439e
Showing 1 changed file with 24 additions and 21 deletions.
45 changes: 24 additions & 21 deletions lib/multi.c
Expand Up @@ -68,24 +68,25 @@ struct Curl_message {
well!
*/
typedef enum {
CURLM_STATE_INIT, /* start in this state */
CURLM_STATE_CONNECT, /* resolve/connect has been sent off */
CURLM_STATE_WAITRESOLVE, /* awaiting the resolve to finalize */
CURLM_STATE_WAITCONNECT, /* awaiting the connect to finalize */
CURLM_STATE_WAITPROXYCONNECT, /* awaiting proxy CONNECT to finalize */
CURLM_STATE_PROTOCONNECT, /* completing the protocol-specific connect phase */
CURLM_STATE_WAITDO, /* wait for our turn to send the request */
CURLM_STATE_DO, /* start send off the request (part 1) */
CURLM_STATE_DOING, /* sending off the request (part 1) */
CURLM_STATE_DO_MORE, /* send off the request (part 2) */
CURLM_STATE_DO_DONE, /* done sending off request */
CURLM_STATE_WAITPERFORM, /* wait for our turn to read the response */
CURLM_STATE_PERFORM, /* transfer data */
CURLM_STATE_TOOFAST, /* wait because limit-rate exceeded */
CURLM_STATE_DONE, /* post data transfer operation */
CURLM_STATE_COMPLETED, /* operation complete */
CURLM_STATE_MSGSENT, /* the operation complete message is sent */
CURLM_STATE_LAST /* not a true state, never use this */
CURLM_STATE_INIT, /* 0 - start in this state */
CURLM_STATE_CONNECT, /* 1 - resolve/connect has been sent off */
CURLM_STATE_WAITRESOLVE, /* 2 - awaiting the resolve to finalize */
CURLM_STATE_WAITCONNECT, /* 3 - awaiting the connect to finalize */
CURLM_STATE_WAITPROXYCONNECT, /* 4 - awaiting proxy CONNECT to finalize */
CURLM_STATE_PROTOCONNECT, /* 5 - completing the protocol-specific connect
phase */
CURLM_STATE_WAITDO, /* 6 - wait for our turn to send the request */
CURLM_STATE_DO, /* 7 - start send off the request (part 1) */
CURLM_STATE_DOING, /* 8 - sending off the request (part 1) */
CURLM_STATE_DO_MORE, /* 9 - send off the request (part 2) */
CURLM_STATE_DO_DONE, /* 10 - done sending off request */
CURLM_STATE_WAITPERFORM, /* 11 - wait for our turn to read the response */
CURLM_STATE_PERFORM, /* 12 - transfer data */
CURLM_STATE_TOOFAST, /* 13 - wait because limit-rate exceeded */
CURLM_STATE_DONE, /* 14 - post data transfer operation */
CURLM_STATE_COMPLETED, /* 15 - operation complete */
CURLM_STATE_MSGSENT, /* 16 - the operation complete message is sent */
CURLM_STATE_LAST /* 17 - not a true state, never use this */
} CURLMstate;

/* we support N sockets per easy handle. Set the corresponding bit to what
Expand Down Expand Up @@ -977,9 +978,11 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
/* Make sure we set the connection's current owner */
easy->easy_conn->data = data;

if(easy->easy_conn && (easy->state >= CURLM_STATE_CONNECT)) {
/* we need to wait for the connect state as only then is the
start time stored */
if(easy->easy_conn &&
(easy->state >= CURLM_STATE_CONNECT) &&
(easy->state < CURLM_STATE_COMPLETED)) {
/* we need to wait for the connect state as only then is the start time
stored, but we must not check already completed handles */

timeout_ms = Curl_timeleft(easy->easy_conn, &now,
(easy->state <= CURLM_STATE_WAITDO)?
Expand Down

0 comments on commit 0fd439e

Please sign in to comment.