void Curl_conncache_close_all_connections(struct conncache *connc) { struct connectdata *conn; conn = Curl_conncache_find_first_connection(connc); while(conn) { SIGPIPE_VARIABLE(pipe_st); conn->data = connc->closure_handle; sigpipe_ignore(conn->data, &pipe_st); conn->data->easy_conn = NULL; /* clear the easy handle's connection pointer */ /* This will remove the connection from the cache */ connclose(conn, "kill all"); (void)Curl_disconnect(connc->closure_handle, conn, FALSE); sigpipe_restore(&pipe_st); conn = Curl_conncache_find_first_connection(connc); } if(connc->closure_handle) { SIGPIPE_VARIABLE(pipe_st); sigpipe_ignore(connc->closure_handle, &pipe_st); Curl_hostcache_clean(connc->closure_handle, connc->closure_handle->dns.hostcache); Curl_close(connc->closure_handle); sigpipe_restore(&pipe_st); } }
/* * easy_perform() is the external interface that performs a blocking * transfer as previously setup. * * CONCEPT: This function creates a multi handle, adds the easy handle to it, * runs curl_multi_perform() until the transfer is done, then detaches the * easy handle, destroys the multi handle and returns the easy handle's return * code. * * REALITY: it can't just create and destroy the multi handle that easily. It * needs to keep it around since if this easy handle is used again by this * function, the same multi handle must be re-used so that the same pools and * caches can be used. * * DEBUG: if 'events' is set TRUE, this function will use a replacement engine * instead of curl_multi_perform() and use curl_multi_socket_action(). */ static CURLcode easy_perform(struct Curl_easy *data, bool events) { struct Curl_multi *multi; CURLMcode mcode; CURLcode result = CURLE_OK; SIGPIPE_VARIABLE(pipe_st); if(!data) return CURLE_BAD_FUNCTION_ARGUMENT; if(data->multi) { failf(data, "easy handle already used in multi handle"); return CURLE_FAILED_INIT; } if(data->multi_easy) multi = data->multi_easy; else { /* this multi handle will only ever have a single easy handled attached to it, so make it use minimal hashes */ multi = Curl_multi_handle(1, 3); if(!multi) return CURLE_OUT_OF_MEMORY; data->multi_easy = multi; } /* Copy the MAXCONNECTS option to the multi handle */ curl_multi_setopt(multi, CURLMOPT_MAXCONNECTS, data->set.maxconnects); mcode = curl_multi_add_handle(multi, data); if(mcode) { curl_multi_cleanup(multi); if(mcode == CURLM_OUT_OF_MEMORY) return CURLE_OUT_OF_MEMORY; else return CURLE_FAILED_INIT; } sigpipe_ignore(data, &pipe_st); /* assign this after curl_multi_add_handle() since that function checks for it and rejects this handle otherwise */ data->multi = multi; /* run the transfer */ result = events ? easy_events(multi) : easy_transfer(multi); /* ignoring the return code isn't nice, but atm we can't really handle a failure here, room for future improvement! */ (void)curl_multi_remove_handle(multi, data); sigpipe_restore(&pipe_st); /* The multi handle is kept alive, owned by the easy handle */ return result; }
/* * curl_easy_cleanup() is the external interface to cleaning/freeing the given * easy handle. */ void curl_easy_cleanup(struct Curl_easy *data) { SIGPIPE_VARIABLE(pipe_st); if(!data) return; sigpipe_ignore(data, &pipe_st); Curl_close(data); sigpipe_restore(&pipe_st); }
/* * curl_easy_cleanup() is the external interface to cleaning/freeing the given * easy handle. */ void curl_easy_cleanup(CURL *curl) { struct SessionHandle *data = (struct SessionHandle *)curl; SIGPIPE_VARIABLE(pipe_st); if(!data) return; sigpipe_ignore(data, &pipe_st); Curl_close(data); sigpipe_restore(&pipe_st); }