Loading lib/ftp.c +1 −6 Original line number Diff line number Diff line Loading @@ -3256,11 +3256,6 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status, const char *path_to_use = data->state.path; if(!ftp) /* When the easy handle is removed from the multi while libcurl is still * trying to resolve the host name, it seems that the ftp struct is not * yet initialized, but the removal action calls Curl_done() which calls * this function. So we simply return success if no ftp pointer is set. */ return CURLE_OK; switch(status) { Loading lib/http.c +2 −2 Original line number Diff line number Diff line Loading @@ -1434,8 +1434,8 @@ static int https_getsock(struct connectdata *conn, #endif /* USE_OPENSSL || USE_GNUTLS || USE_SCHANNEL */ /* * Curl_http_done() gets called from Curl_done() after a single HTTP request * has been performed. * Curl_http_done() gets called after a single HTTP request has been * performed. */ CURLcode Curl_http_done(struct connectdata *conn, Loading lib/imap.c +1 −6 Original line number Diff line number Diff line Loading @@ -1486,10 +1486,6 @@ static CURLcode imap_done(struct connectdata *conn, CURLcode status, (void)premature; if(!imap) /* When the easy handle is removed from the multi interface while libcurl is still trying to resolve the host name, the IMAP struct is not yet initialized. However, the removal action calls Curl_done() which in turn calls this function, so we simply return success. */ return CURLE_OK; if(status) { Loading @@ -1512,8 +1508,7 @@ static CURLcode imap_done(struct connectdata *conn, CURLcode status, TODO: when the multi interface is used, this _really_ should be using the imap_multi_statemach function but we have no general support for non-blocking DONE operations, not in the multi state machine and with Curl_done() invokes on several places in the code! non-blocking DONE operations! */ if(!result) result = imap_block_statemach(conn); Loading lib/multi.c +188 −29 Original line number Diff line number Diff line Loading @@ -484,6 +484,167 @@ static void debug_print_sock_hash(void *p) } #endif /* Mark the connection as 'idle', or close it if the cache is full. Returns TRUE if the connection is kept, or FALSE if it was closed. */ static bool ConnectionDone(struct SessionHandle *data, struct connectdata *conn) { /* data->multi->maxconnects can be negative, deal with it. */ size_t maxconnects = (data->multi->maxconnects < 0) ? data->multi->num_easy * 4: data->multi->maxconnects; struct connectdata *conn_candidate = NULL; /* Mark the current connection as 'unused' */ conn->inuse = FALSE; if(maxconnects > 0 && data->state.conn_cache->num_connections > maxconnects) { infof(data, "Connection cache is full, closing the oldest one.\n"); conn_candidate = Curl_oldest_idle_connection(data); if(conn_candidate) { /* Set the connection's owner correctly */ conn_candidate->data = data; /* the winner gets the honour of being disconnected */ (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE); } } return (conn_candidate == conn) ? FALSE : TRUE; } static CURLcode multi_done(struct connectdata **connp, CURLcode status, /* an error if this is called after an error was detected */ bool premature) { CURLcode result; struct connectdata *conn; struct SessionHandle *data; DEBUGASSERT(*connp); conn = *connp; data = conn->data; DEBUGF(infof(data, "multi_done\n")); if(data->state.done) /* Stop if multi_done() has already been called */ return CURLE_OK; Curl_getoff_all_pipelines(data, conn); /* Cleanup possible redirect junk */ free(data->req.newurl); data->req.newurl = NULL; free(data->req.location); data->req.location = NULL; switch(status) { case CURLE_ABORTED_BY_CALLBACK: case CURLE_READ_ERROR: case CURLE_WRITE_ERROR: /* When we're aborted due to a callback return code it basically have to be counted as premature as there is trouble ahead if we don't. We have many callbacks and protocols work differently, we could potentially do this more fine-grained in the future. */ premature = TRUE; default: break; } /* this calls the protocol-specific function pointer previously set */ if(conn->handler->done) result = conn->handler->done(conn, status, premature); else result = status; if(CURLE_ABORTED_BY_CALLBACK != result) { /* avoid this if we already aborted by callback to avoid this calling another callback */ CURLcode rc = Curl_pgrsDone(conn); if(!result && rc) result = CURLE_ABORTED_BY_CALLBACK; } if((!premature && conn->send_pipe->size + conn->recv_pipe->size != 0 && !data->set.reuse_forbid && !conn->bits.close)) { /* Stop if pipeline is not empty and we do not have to close connection. */ DEBUGF(infof(data, "Connection still in use, no more multi_done now!\n")); return CURLE_OK; } data->state.done = TRUE; /* called just now! */ Curl_resolver_cancel(conn); if(conn->dns_entry) { Curl_resolv_unlock(data, conn->dns_entry); /* done with this */ conn->dns_entry = NULL; } /* if the transfer was completed in a paused state there can be buffered data left to write and then kill */ free(data->state.tempwrite); data->state.tempwrite = NULL; /* if data->set.reuse_forbid is TRUE, it means the libcurl client has forced us to close this connection. This is ignored for requests taking place in a NTLM authentication handshake if conn->bits.close is TRUE, it means that the connection should be closed in spite of all our efforts to be nice, due to protocol restrictions in our or the server's end if premature is TRUE, it means this connection was said to be DONE before the entire request operation is complete and thus we can't know in what state it is for re-using, so we're forced to close it. In a perfect world we can add code that keep track of if we really must close it here or not, but currently we have no such detail knowledge. */ if((data->set.reuse_forbid #if defined(USE_NTLM) && !(conn->ntlm.state == NTLMSTATE_TYPE2 || conn->proxyntlm.state == NTLMSTATE_TYPE2) #endif ) || conn->bits.close || premature) { CURLcode res2 = Curl_disconnect(conn, premature); /* close connection */ /* If we had an error already, make sure we return that one. But if we got a new error, return that. */ if(!result && res2) result = res2; } else { /* the connection is no longer in use */ if(ConnectionDone(data, conn)) { /* remember the most recently used connection */ data->state.lastconnect = conn; infof(data, "Connection #%ld to host %s left intact\n", conn->connection_id, conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname); } else data->state.lastconnect = NULL; } *connp = NULL; /* to make the caller of this function better detect that this was either closed or handed over to the connection cache here, and therefore cannot be used from this point on */ Curl_free_request_state(data); return result; } CURLMcode curl_multi_remove_handle(CURLM *multi_handle, CURL *curl_handle) { Loading Loading @@ -529,8 +690,8 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle, request but not received its response yet, we need to close connection. */ connclose(data->easy_conn, "Removed with partial response"); /* Set connection owner so that Curl_done() closes it. We can safely do this here since connection is killed. */ /* Set connection owner so that the DONE function closes it. We can safely do this here since connection is killed. */ data->easy_conn->data = easy; easy_owns_conn = TRUE; } Loading @@ -548,26 +709,26 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle, if(data->easy_conn) { /* we must call Curl_done() here (if we still "own it") so that we don't leave a half-baked one around */ /* we must call multi_done() here (if we still own the connection) so that we don't leave a half-baked one around */ if(easy_owns_conn) { /* Curl_done() clears the conn->data field to lose the association /* multi_done() clears the conn->data field to lose the association between the easy handle and the connection Note that this ignores the return code simply because there's nothing really useful to do with it anyway! */ (void)Curl_done(&data->easy_conn, data->result, premature); (void)multi_done(&data->easy_conn, data->result, premature); } else /* Clear connection pipelines, if Curl_done above was not called */ /* Clear connection pipelines, if multi_done above was not called */ Curl_getoff_all_pipelines(data, data->easy_conn); } Curl_wildcard_dtor(&data->wildcard); /* destroy the timeout list that is held in the easy handle, do this *after* Curl_done() as that may actuall call Curl_expire that uses this */ multi_done() as that may actually call Curl_expire that uses this */ if(data->state.timeoutlist) { Curl_llist_destroy(data->state.timeoutlist, NULL); data->state.timeoutlist = NULL; Loading Loading @@ -1005,18 +1166,16 @@ static CURLcode multi_reconnect_request(struct connectdata **connp) infof(data, "Re-used connection seems dead, get a new one\n"); connclose(conn, "Reconnect dead connection"); /* enforce close */ result = Curl_done(&conn, result, FALSE); /* we are so done with this */ result = multi_done(&conn, result, FALSE); /* we are so done with this */ /* conn may no longer be a good pointer, clear it to avoid mistakes by parent functions */ *connp = NULL; /* * According to bug report #1330310. We need to check for CURLE_SEND_ERROR * here as well. I figure this could happen when the request failed on a FTP * connection and thus Curl_done() itself tried to use the connection * (again). Slight Lack of feedback in the report, but I don't think this * extra check can do much harm. * We need to check for CURLE_SEND_ERROR here as well. This could happen * when the request failed on a FTP connection and thus multi_done() itself * tried to use the connection (again). */ if(!result || (CURLE_SEND_ERROR == result)) { bool async; Loading Loading @@ -1227,7 +1386,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, disconnect_conn = TRUE; } result = CURLE_OPERATION_TIMEDOUT; (void)Curl_done(&data->easy_conn, result, TRUE); (void)multi_done(&data->easy_conn, result, TRUE); /* Skip the statemachine and go directly to error handling section. */ goto statemachine_end; } Loading Loading @@ -1372,7 +1531,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, rc = CURLM_CALL_MULTI_PERFORM; /* connect back to proxy again */ result = CURLE_OK; Curl_done(&data->easy_conn, CURLE_OK, FALSE); multi_done(&data->easy_conn, CURLE_OK, FALSE); multistate(data, CURLM_STATE_CONNECT); } else if(!result) { Loading Loading @@ -1416,7 +1575,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, else if(result) { /* failure detected */ Curl_posttransfer(data); Curl_done(&data->easy_conn, result, TRUE); multi_done(&data->easy_conn, result, TRUE); disconnect_conn = TRUE; } break; Loading @@ -1433,7 +1592,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, else if(result) { /* failure detected */ Curl_posttransfer(data); Curl_done(&data->easy_conn, result, TRUE); multi_done(&data->easy_conn, result, TRUE); disconnect_conn = TRUE; } break; Loading Loading @@ -1468,7 +1627,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, struct WildcardData *wc = &data->wildcard; if(wc->state == CURLWC_DONE || wc->state == CURLWC_SKIP) { /* skip some states if it is important */ Curl_done(&data->easy_conn, CURLE_OK, FALSE); multi_done(&data->easy_conn, CURLE_OK, FALSE); multistate(data, CURLM_STATE_DONE); rc = CURLM_CALL_MULTI_PERFORM; break; Loading Loading @@ -1515,7 +1674,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, retry = (newurl)?TRUE:FALSE; Curl_posttransfer(data); drc = Curl_done(&data->easy_conn, result, FALSE); drc = multi_done(&data->easy_conn, result, FALSE); /* When set to retry the connection, we must to go back to * the CONNECT state */ Loading Loading @@ -1550,7 +1709,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* failure detected */ Curl_posttransfer(data); if(data->easy_conn) Curl_done(&data->easy_conn, result, FALSE); multi_done(&data->easy_conn, result, FALSE); disconnect_conn = TRUE; } } Loading @@ -1572,7 +1731,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, else { /* failure detected */ Curl_posttransfer(data); Curl_done(&data->easy_conn, result, FALSE); multi_done(&data->easy_conn, result, FALSE); disconnect_conn = TRUE; } break; Loading @@ -1584,7 +1743,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, result = multi_do_more(data->easy_conn, &control); /* No need to remove this handle from the send pipeline here since that is done in Curl_done() */ is done in multi_done() */ if(!result) { if(control) { /* if positive, advance to DO_DONE Loading @@ -1601,7 +1760,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, else { /* failure detected */ Curl_posttransfer(data); Curl_done(&data->easy_conn, result, FALSE); multi_done(&data->easy_conn, result, FALSE); disconnect_conn = TRUE; } break; Loading Loading @@ -1725,7 +1884,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, connclose(data->easy_conn, "Transfer returned error"); Curl_posttransfer(data); Curl_done(&data->easy_conn, result, FALSE); multi_done(&data->easy_conn, result, FALSE); } else if(done) { followtype follow=FOLLOW_NONE; Loading Loading @@ -1756,7 +1915,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } else follow = FOLLOW_RETRY; result = Curl_done(&data->easy_conn, CURLE_OK, FALSE); result = multi_done(&data->easy_conn, CURLE_OK, FALSE); if(!result) { result = Curl_follow(data, newurl, follow); if(!result) { Loading Loading @@ -1806,14 +1965,14 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, Curl_multi_process_pending_handles(multi); /* post-transfer command */ res = Curl_done(&data->easy_conn, result, FALSE); res = multi_done(&data->easy_conn, result, FALSE); /* allow a previously set error code take precedence */ if(!result) result = res; /* * If there are other handles on the pipeline, Curl_done won't set * If there are other handles on the pipeline, multi_done won't set * easy_conn to NULL. In such a case, curl_multi_remove_handle() can * access free'd data, if the connection is free'd and the handle * removed before we perform the processing in CURLM_STATE_COMPLETED Loading @@ -1832,7 +1991,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } /* after we have DONE what we're supposed to do, go COMPLETED, and it doesn't matter what the Curl_done() returned! */ it doesn't matter what the multi_done() returned! */ multistate(data, CURLM_STATE_COMPLETED); break; Loading lib/pop3.c +0 −4 Original line number Diff line number Diff line Loading @@ -1166,10 +1166,6 @@ static CURLcode pop3_done(struct connectdata *conn, CURLcode status, (void)premature; if(!pop3) /* When the easy handle is removed from the multi interface while libcurl is still trying to resolve the host name, the POP3 struct is not yet initialized. However, the removal action calls Curl_done() which in turn calls this function, so we simply return success. */ return CURLE_OK; if(status) { Loading Loading
lib/ftp.c +1 −6 Original line number Diff line number Diff line Loading @@ -3256,11 +3256,6 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status, const char *path_to_use = data->state.path; if(!ftp) /* When the easy handle is removed from the multi while libcurl is still * trying to resolve the host name, it seems that the ftp struct is not * yet initialized, but the removal action calls Curl_done() which calls * this function. So we simply return success if no ftp pointer is set. */ return CURLE_OK; switch(status) { Loading
lib/http.c +2 −2 Original line number Diff line number Diff line Loading @@ -1434,8 +1434,8 @@ static int https_getsock(struct connectdata *conn, #endif /* USE_OPENSSL || USE_GNUTLS || USE_SCHANNEL */ /* * Curl_http_done() gets called from Curl_done() after a single HTTP request * has been performed. * Curl_http_done() gets called after a single HTTP request has been * performed. */ CURLcode Curl_http_done(struct connectdata *conn, Loading
lib/imap.c +1 −6 Original line number Diff line number Diff line Loading @@ -1486,10 +1486,6 @@ static CURLcode imap_done(struct connectdata *conn, CURLcode status, (void)premature; if(!imap) /* When the easy handle is removed from the multi interface while libcurl is still trying to resolve the host name, the IMAP struct is not yet initialized. However, the removal action calls Curl_done() which in turn calls this function, so we simply return success. */ return CURLE_OK; if(status) { Loading @@ -1512,8 +1508,7 @@ static CURLcode imap_done(struct connectdata *conn, CURLcode status, TODO: when the multi interface is used, this _really_ should be using the imap_multi_statemach function but we have no general support for non-blocking DONE operations, not in the multi state machine and with Curl_done() invokes on several places in the code! non-blocking DONE operations! */ if(!result) result = imap_block_statemach(conn); Loading
lib/multi.c +188 −29 Original line number Diff line number Diff line Loading @@ -484,6 +484,167 @@ static void debug_print_sock_hash(void *p) } #endif /* Mark the connection as 'idle', or close it if the cache is full. Returns TRUE if the connection is kept, or FALSE if it was closed. */ static bool ConnectionDone(struct SessionHandle *data, struct connectdata *conn) { /* data->multi->maxconnects can be negative, deal with it. */ size_t maxconnects = (data->multi->maxconnects < 0) ? data->multi->num_easy * 4: data->multi->maxconnects; struct connectdata *conn_candidate = NULL; /* Mark the current connection as 'unused' */ conn->inuse = FALSE; if(maxconnects > 0 && data->state.conn_cache->num_connections > maxconnects) { infof(data, "Connection cache is full, closing the oldest one.\n"); conn_candidate = Curl_oldest_idle_connection(data); if(conn_candidate) { /* Set the connection's owner correctly */ conn_candidate->data = data; /* the winner gets the honour of being disconnected */ (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE); } } return (conn_candidate == conn) ? FALSE : TRUE; } static CURLcode multi_done(struct connectdata **connp, CURLcode status, /* an error if this is called after an error was detected */ bool premature) { CURLcode result; struct connectdata *conn; struct SessionHandle *data; DEBUGASSERT(*connp); conn = *connp; data = conn->data; DEBUGF(infof(data, "multi_done\n")); if(data->state.done) /* Stop if multi_done() has already been called */ return CURLE_OK; Curl_getoff_all_pipelines(data, conn); /* Cleanup possible redirect junk */ free(data->req.newurl); data->req.newurl = NULL; free(data->req.location); data->req.location = NULL; switch(status) { case CURLE_ABORTED_BY_CALLBACK: case CURLE_READ_ERROR: case CURLE_WRITE_ERROR: /* When we're aborted due to a callback return code it basically have to be counted as premature as there is trouble ahead if we don't. We have many callbacks and protocols work differently, we could potentially do this more fine-grained in the future. */ premature = TRUE; default: break; } /* this calls the protocol-specific function pointer previously set */ if(conn->handler->done) result = conn->handler->done(conn, status, premature); else result = status; if(CURLE_ABORTED_BY_CALLBACK != result) { /* avoid this if we already aborted by callback to avoid this calling another callback */ CURLcode rc = Curl_pgrsDone(conn); if(!result && rc) result = CURLE_ABORTED_BY_CALLBACK; } if((!premature && conn->send_pipe->size + conn->recv_pipe->size != 0 && !data->set.reuse_forbid && !conn->bits.close)) { /* Stop if pipeline is not empty and we do not have to close connection. */ DEBUGF(infof(data, "Connection still in use, no more multi_done now!\n")); return CURLE_OK; } data->state.done = TRUE; /* called just now! */ Curl_resolver_cancel(conn); if(conn->dns_entry) { Curl_resolv_unlock(data, conn->dns_entry); /* done with this */ conn->dns_entry = NULL; } /* if the transfer was completed in a paused state there can be buffered data left to write and then kill */ free(data->state.tempwrite); data->state.tempwrite = NULL; /* if data->set.reuse_forbid is TRUE, it means the libcurl client has forced us to close this connection. This is ignored for requests taking place in a NTLM authentication handshake if conn->bits.close is TRUE, it means that the connection should be closed in spite of all our efforts to be nice, due to protocol restrictions in our or the server's end if premature is TRUE, it means this connection was said to be DONE before the entire request operation is complete and thus we can't know in what state it is for re-using, so we're forced to close it. In a perfect world we can add code that keep track of if we really must close it here or not, but currently we have no such detail knowledge. */ if((data->set.reuse_forbid #if defined(USE_NTLM) && !(conn->ntlm.state == NTLMSTATE_TYPE2 || conn->proxyntlm.state == NTLMSTATE_TYPE2) #endif ) || conn->bits.close || premature) { CURLcode res2 = Curl_disconnect(conn, premature); /* close connection */ /* If we had an error already, make sure we return that one. But if we got a new error, return that. */ if(!result && res2) result = res2; } else { /* the connection is no longer in use */ if(ConnectionDone(data, conn)) { /* remember the most recently used connection */ data->state.lastconnect = conn; infof(data, "Connection #%ld to host %s left intact\n", conn->connection_id, conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname); } else data->state.lastconnect = NULL; } *connp = NULL; /* to make the caller of this function better detect that this was either closed or handed over to the connection cache here, and therefore cannot be used from this point on */ Curl_free_request_state(data); return result; } CURLMcode curl_multi_remove_handle(CURLM *multi_handle, CURL *curl_handle) { Loading Loading @@ -529,8 +690,8 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle, request but not received its response yet, we need to close connection. */ connclose(data->easy_conn, "Removed with partial response"); /* Set connection owner so that Curl_done() closes it. We can safely do this here since connection is killed. */ /* Set connection owner so that the DONE function closes it. We can safely do this here since connection is killed. */ data->easy_conn->data = easy; easy_owns_conn = TRUE; } Loading @@ -548,26 +709,26 @@ CURLMcode curl_multi_remove_handle(CURLM *multi_handle, if(data->easy_conn) { /* we must call Curl_done() here (if we still "own it") so that we don't leave a half-baked one around */ /* we must call multi_done() here (if we still own the connection) so that we don't leave a half-baked one around */ if(easy_owns_conn) { /* Curl_done() clears the conn->data field to lose the association /* multi_done() clears the conn->data field to lose the association between the easy handle and the connection Note that this ignores the return code simply because there's nothing really useful to do with it anyway! */ (void)Curl_done(&data->easy_conn, data->result, premature); (void)multi_done(&data->easy_conn, data->result, premature); } else /* Clear connection pipelines, if Curl_done above was not called */ /* Clear connection pipelines, if multi_done above was not called */ Curl_getoff_all_pipelines(data, data->easy_conn); } Curl_wildcard_dtor(&data->wildcard); /* destroy the timeout list that is held in the easy handle, do this *after* Curl_done() as that may actuall call Curl_expire that uses this */ multi_done() as that may actually call Curl_expire that uses this */ if(data->state.timeoutlist) { Curl_llist_destroy(data->state.timeoutlist, NULL); data->state.timeoutlist = NULL; Loading Loading @@ -1005,18 +1166,16 @@ static CURLcode multi_reconnect_request(struct connectdata **connp) infof(data, "Re-used connection seems dead, get a new one\n"); connclose(conn, "Reconnect dead connection"); /* enforce close */ result = Curl_done(&conn, result, FALSE); /* we are so done with this */ result = multi_done(&conn, result, FALSE); /* we are so done with this */ /* conn may no longer be a good pointer, clear it to avoid mistakes by parent functions */ *connp = NULL; /* * According to bug report #1330310. We need to check for CURLE_SEND_ERROR * here as well. I figure this could happen when the request failed on a FTP * connection and thus Curl_done() itself tried to use the connection * (again). Slight Lack of feedback in the report, but I don't think this * extra check can do much harm. * We need to check for CURLE_SEND_ERROR here as well. This could happen * when the request failed on a FTP connection and thus multi_done() itself * tried to use the connection (again). */ if(!result || (CURLE_SEND_ERROR == result)) { bool async; Loading Loading @@ -1227,7 +1386,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, disconnect_conn = TRUE; } result = CURLE_OPERATION_TIMEDOUT; (void)Curl_done(&data->easy_conn, result, TRUE); (void)multi_done(&data->easy_conn, result, TRUE); /* Skip the statemachine and go directly to error handling section. */ goto statemachine_end; } Loading Loading @@ -1372,7 +1531,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, rc = CURLM_CALL_MULTI_PERFORM; /* connect back to proxy again */ result = CURLE_OK; Curl_done(&data->easy_conn, CURLE_OK, FALSE); multi_done(&data->easy_conn, CURLE_OK, FALSE); multistate(data, CURLM_STATE_CONNECT); } else if(!result) { Loading Loading @@ -1416,7 +1575,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, else if(result) { /* failure detected */ Curl_posttransfer(data); Curl_done(&data->easy_conn, result, TRUE); multi_done(&data->easy_conn, result, TRUE); disconnect_conn = TRUE; } break; Loading @@ -1433,7 +1592,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, else if(result) { /* failure detected */ Curl_posttransfer(data); Curl_done(&data->easy_conn, result, TRUE); multi_done(&data->easy_conn, result, TRUE); disconnect_conn = TRUE; } break; Loading Loading @@ -1468,7 +1627,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, struct WildcardData *wc = &data->wildcard; if(wc->state == CURLWC_DONE || wc->state == CURLWC_SKIP) { /* skip some states if it is important */ Curl_done(&data->easy_conn, CURLE_OK, FALSE); multi_done(&data->easy_conn, CURLE_OK, FALSE); multistate(data, CURLM_STATE_DONE); rc = CURLM_CALL_MULTI_PERFORM; break; Loading Loading @@ -1515,7 +1674,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, retry = (newurl)?TRUE:FALSE; Curl_posttransfer(data); drc = Curl_done(&data->easy_conn, result, FALSE); drc = multi_done(&data->easy_conn, result, FALSE); /* When set to retry the connection, we must to go back to * the CONNECT state */ Loading Loading @@ -1550,7 +1709,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, /* failure detected */ Curl_posttransfer(data); if(data->easy_conn) Curl_done(&data->easy_conn, result, FALSE); multi_done(&data->easy_conn, result, FALSE); disconnect_conn = TRUE; } } Loading @@ -1572,7 +1731,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, else { /* failure detected */ Curl_posttransfer(data); Curl_done(&data->easy_conn, result, FALSE); multi_done(&data->easy_conn, result, FALSE); disconnect_conn = TRUE; } break; Loading @@ -1584,7 +1743,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, result = multi_do_more(data->easy_conn, &control); /* No need to remove this handle from the send pipeline here since that is done in Curl_done() */ is done in multi_done() */ if(!result) { if(control) { /* if positive, advance to DO_DONE Loading @@ -1601,7 +1760,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, else { /* failure detected */ Curl_posttransfer(data); Curl_done(&data->easy_conn, result, FALSE); multi_done(&data->easy_conn, result, FALSE); disconnect_conn = TRUE; } break; Loading Loading @@ -1725,7 +1884,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, connclose(data->easy_conn, "Transfer returned error"); Curl_posttransfer(data); Curl_done(&data->easy_conn, result, FALSE); multi_done(&data->easy_conn, result, FALSE); } else if(done) { followtype follow=FOLLOW_NONE; Loading Loading @@ -1756,7 +1915,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } else follow = FOLLOW_RETRY; result = Curl_done(&data->easy_conn, CURLE_OK, FALSE); result = multi_done(&data->easy_conn, CURLE_OK, FALSE); if(!result) { result = Curl_follow(data, newurl, follow); if(!result) { Loading Loading @@ -1806,14 +1965,14 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, Curl_multi_process_pending_handles(multi); /* post-transfer command */ res = Curl_done(&data->easy_conn, result, FALSE); res = multi_done(&data->easy_conn, result, FALSE); /* allow a previously set error code take precedence */ if(!result) result = res; /* * If there are other handles on the pipeline, Curl_done won't set * If there are other handles on the pipeline, multi_done won't set * easy_conn to NULL. In such a case, curl_multi_remove_handle() can * access free'd data, if the connection is free'd and the handle * removed before we perform the processing in CURLM_STATE_COMPLETED Loading @@ -1832,7 +1991,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, } /* after we have DONE what we're supposed to do, go COMPLETED, and it doesn't matter what the Curl_done() returned! */ it doesn't matter what the multi_done() returned! */ multistate(data, CURLM_STATE_COMPLETED); break; Loading
lib/pop3.c +0 −4 Original line number Diff line number Diff line Loading @@ -1166,10 +1166,6 @@ static CURLcode pop3_done(struct connectdata *conn, CURLcode status, (void)premature; if(!pop3) /* When the easy handle is removed from the multi interface while libcurl is still trying to resolve the host name, the POP3 struct is not yet initialized. However, the removal action calls Curl_done() which in turn calls this function, so we simply return success. */ return CURLE_OK; if(status) { Loading