aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2010-12-13 12:51:48 +0100
committerDaniel Stenberg <daniel@haxx.se>2010-12-13 12:51:48 +0100
commit0fd439ebaceed1ff049a4173e98da1ec2b8d0ed0 (patch)
tree62e81b1813fb32bdc54328a023e2ac1ebabc4e68
parent012f9b7f048425c543af44b22eea8c210f269d39 (diff)
multi_runsingle: don't timeout completed handles
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 ca10e28f06f1
-rw-r--r--lib/multi.c45
1 files changed, 24 insertions, 21 deletions
diff --git a/lib/multi.c b/lib/multi.c
index 7be479bd4..ff4bf861b 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -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
@@ -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)?