cshutdown: make it smaller
No binary (build failed)
—
(log yok)
| @@ -182,7 +182,6 @@ static void cpool_discard_conn(struct cpool *cpool, | |
| struct connectdata *conn, | |
| bool aborted) | |
| { | |
| - | struct cshutdn *cshutdn; |
| struct Curl_easy *admin; | |
| bool done = FALSE; | |
| @@ -221,11 +220,19 @@ static void cpool_discard_conn(struct cpool *cpool, | |
| Curl_conn_shutdown_once(admin, conn, &done); | |
| } | |
| - | cshutdn = Curl_cshutdn_get(data); |
| - | if(done || !cshutdn) |
| + | if(done || !data->multi) |
| Curl_conn_terminate(admin, conn, FALSE); | |
| - | else |
| - | Curl_cshutdn_add(cshutdn, conn, cpool->num_conn); |
| + | else { |
| + | struct Curl_multi *multi = data->multi; |
| + | size_t max_shutdowns = multi->max_total_connections; |
| + | if(cpool->num_conn < max_shutdowns) |
| + | max_shutdowns -= cpool->num_conn; |
| + | else if(max_shutdowns) |
| + | max_shutdowns = 1; |
| + | else /* no connection limit set, let's restrict growth nevertheless */ |
| + | max_shutdowns = CURLMAX(cpool->num_conn / 4, 128); |
| + | Curl_cshutdn_add(&multi->cshutdn, multi, conn, max_shutdowns); |
| + | } |
| } | |
| void Curl_cpool_destroy(struct cpool *cpool, struct Curl_easy *admin) | |
| @@ -454,7 +461,7 @@ int Curl_cpool_check_limits(struct Curl_easy *data, | |
| const struct curltime *pnow) | |
| { | |
| struct cpool *cpool = cpool_get_instance(data); | |
| - | struct cshutdn *cshutdn = Curl_cshutdn_get(data); |
| + | struct Curl_multi *multi = data->multi; |
| struct Curl_easy *admin; | |
| struct cpool_bundle *bundle; | |
| size_t dest_limit = 0; | |
| @@ -466,9 +473,9 @@ int Curl_cpool_check_limits(struct Curl_easy *data, | |
| return CPOOL_LIMIT_OK; | |
| /* multi determines the limits, no matter who owns the pool */ | |
| - | if(data->multi) { |
| - | dest_limit = data->multi->max_host_connections; |
| - | total_limit = data->multi->max_total_connections; |
| + | if(multi) { |
| + | dest_limit = multi->max_host_connections; |
| + | total_limit = multi->max_total_connections; |
| } | |
| if(!dest_limit && !total_limit) | |
| @@ -481,11 +488,13 @@ int Curl_cpool_check_limits(struct Curl_easy *data, | |
| bundle = cpool_find_bundle(cpool, conn); | |
| live = bundle ? Curl_llist_count(&bundle->conns) : 0; | |
| - | shutdowns = Curl_cshutdn_dest_count(cshutdn, conn->destination); |
| + | shutdowns = |
| + | multi ? Curl_cshutdn_dest_count(&multi->cshutdn, conn->destination) : 0; |
| while((live + shutdowns) >= dest_limit) { | |
| if(shutdowns) { | |
| /* close one connection in shutdown right away, if we can */ | |
| - | if(!Curl_cshutdn_close_oldest(cshutdn, conn->destination)) |
| + | if(!Curl_cshutdn_close_oldest(&multi->cshutdn, multi->admin, |
| + | conn->destination)) |
| break; | |
| } | |
| else if(!bundle) | |
| @@ -508,7 +517,8 @@ int Curl_cpool_check_limits(struct Curl_easy *data, | |
| bundle = cpool_find_bundle(cpool, conn); | |
| live = bundle ? Curl_llist_count(&bundle->conns) : 0; | |
| } | |
| - | shutdowns = Curl_cshutdn_dest_count(cshutdn, conn->destination); |
| + | shutdowns = multi ? |
| + | Curl_cshutdn_dest_count(&multi->cshutdn, conn->destination) : 0; |
| } | |
| if((live + shutdowns) >= dest_limit) { | |
| res = CPOOL_LIMIT_DEST; | |
| @@ -517,11 +527,11 @@ int Curl_cpool_check_limits(struct Curl_easy *data, | |
| } | |
| if(total_limit) { | |
| - | shutdowns = Curl_cshutdn_count(cshutdn); |
| + | shutdowns = multi ? Curl_cshutdn_count(&multi->cshutdn) : 0; |
| while((cpool->num_conn + shutdowns) >= total_limit) { | |
| if(shutdowns) { | |
| /* close one connection in shutdown right away, if we can */ | |
| - | if(!Curl_cshutdn_close_oldest(cshutdn, NULL)) |
| + | if(!Curl_cshutdn_close_oldest(&multi->cshutdn, multi->admin, NULL)) |
| break; | |
| } | |
| else { | |
| @@ -536,7 +546,7 @@ int Curl_cpool_check_limits(struct Curl_easy *data, | |
| oldest_idle->connection_id, cpool->num_conn, total_limit); | |
| cpool_evict_conn(cpool, admin, oldest_idle); | |
| } | |
| - | shutdowns = Curl_cshutdn_count(cshutdn); |
| + | shutdowns = multi ? Curl_cshutdn_count(&multi->cshutdn) : 0; |
| } | |
| if((cpool->num_conn + shutdowns) >= total_limit) { | |
| res = CPOOL_LIMIT_TOTAL; | |
| @@ -38,13 +38,6 @@ | |
| #include "curlx/strparse.h" | |
| - | struct cshutdn *Curl_cshutdn_get(struct Curl_easy *data) |
| - | { |
| - | if(data && data->multi) |
| - | return &data->multi->cshutdn; |
| - | return NULL; |
| - | } |
| - | |
| static void cshutdn_run_conn_handler(struct Curl_easy *data, | |
| struct connectdata *conn) | |
| { | |
| @@ -166,6 +159,7 @@ void Curl_conn_terminate(struct Curl_easy *admin, | |
| } | |
| static bool cshutdn_destroy_oldest(struct cshutdn *cshutdn, | |
| + | struct Curl_easy *admin, |
| const char *destination) | |
| { | |
| struct Curl_llist_node *e; | |
| @@ -184,8 +178,8 @@ static bool cshutdn_destroy_oldest(struct cshutdn *cshutdn, | |
| conn = Curl_node_elem(e); | |
| Curl_node_remove(e); | |
| sigpipe_init(&sigpipe_ctx); | |
| - | sigpipe_apply(cshutdn->multi->admin, &sigpipe_ctx); |
| - | Curl_conn_terminate(cshutdn->multi->admin, conn, FALSE); |
| + | sigpipe_apply(admin, &sigpipe_ctx); |
| + | Curl_conn_terminate(admin, conn, FALSE); |
| sigpipe_restore(&sigpipe_ctx); | |
| return TRUE; | |
| } | |
| @@ -193,10 +187,11 @@ static bool cshutdn_destroy_oldest(struct cshutdn *cshutdn, | |
| } | |
| bool Curl_cshutdn_close_oldest(struct cshutdn *cshutdn, | |
| + | struct Curl_easy *admin, |
| const char *destination) | |
| { | |
| if(cshutdn) { | |
| - | return cshutdn_destroy_oldest(cshutdn, destination); |
| + | return cshutdn_destroy_oldest(cshutdn, admin, destination); |
| } | |
| return FALSE; | |
| } | |
| @@ -204,6 +199,7 @@ bool Curl_cshutdn_close_oldest(struct cshutdn *cshutdn, | |
| #define NUM_POLLS_ON_STACK 10 | |
| static CURLcode cshutdn_wait(struct cshutdn *cshutdn, | |
| + | struct Curl_easy *admin, |
| int timeout_ms) | |
| { | |
| struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK]; | |
| @@ -212,7 +208,7 @@ static CURLcode cshutdn_wait(struct cshutdn *cshutdn, | |
| Curl_pollfds_init(&cpfds, a_few_on_stack, NUM_POLLS_ON_STACK); | |
| - | result = Curl_cshutdn_add_pollfds(cshutdn, &cpfds); |
| + | result = Curl_cshutdn_add_pollfds(cshutdn, admin, &cpfds); |
| if(result) | |
| goto out; | |
| @@ -224,11 +220,11 @@ out: | |
| } | |
| static void cshutdn_perform(struct cshutdn *cshutdn, | |
| + | struct Curl_easy *admin, |
| struct Curl_sigpipe_ctx *sigpipe_ctx) | |
| { | |
| struct Curl_llist_node *e = Curl_llist_head(&cshutdn->list); | |
| struct Curl_llist_node *enext; | |
| - | struct Curl_easy *admin = cshutdn->multi->admin; |
| struct connectdata *conn; | |
| timediff_t next_expire_ms = 0, ms; | |
| bool done; | |
| @@ -262,9 +258,9 @@ static void cshutdn_perform(struct cshutdn *cshutdn, | |
| } | |
| static void cshutdn_terminate_all(struct cshutdn *cshutdn, | |
| + | struct Curl_easy *admin, |
| int timeout_ms) | |
| { | |
| - | struct Curl_easy *admin = cshutdn->multi->admin; |
| struct curltime started = *Curl_pgrs_now(admin); | |
| struct Curl_llist_node *e; | |
| struct Curl_sigpipe_ctx sigpipe_ctx; | |
| @@ -276,7 +272,7 @@ static void cshutdn_terminate_all(struct cshutdn *cshutdn, | |
| timediff_t spent_ms; | |
| int remain_ms; | |
| - | cshutdn_perform(cshutdn, &sigpipe_ctx); |
| + | cshutdn_perform(cshutdn, admin, &sigpipe_ctx); |
| if(!Curl_llist_head(&cshutdn->list)) { | |
| CURL_TRC_M(admin, "[SHUTDOWN] shutdown finished cleanly"); | |
| @@ -292,7 +288,7 @@ static void cshutdn_terminate_all(struct cshutdn *cshutdn, | |
| } | |
| remain_ms = timeout_ms - (int)spent_ms; | |
| - | if(cshutdn_wait(cshutdn, remain_ms)) { |
| + | if(cshutdn_wait(cshutdn, admin, remain_ms)) { |
| CURL_TRC_M(admin, "[SHUTDOWN] shutdown finished, aborted"); | |
| break; | |
| } | |
| @@ -311,24 +307,18 @@ static void cshutdn_terminate_all(struct cshutdn *cshutdn, | |
| sigpipe_restore(&sigpipe_ctx); | |
| } | |
| - | int Curl_cshutdn_init(struct cshutdn *cshutdn, |
| - | struct Curl_multi *multi) |
| + | void Curl_cshutdn_init(struct cshutdn *cshutdn) |
| { | |
| - | DEBUGASSERT(multi); |
| - | cshutdn->multi = multi; |
| Curl_llist_init(&cshutdn->list, NULL); | |
| - | cshutdn->initialized = TRUE; |
| - | return 0; /* good */ |
| } | |
| void Curl_cshutdn_destroy(struct cshutdn *cshutdn, | |
| struct Curl_easy *admin) | |
| { | |
| - | if(cshutdn->initialized && admin) { |
| + | if(admin) { |
| int timeout_ms = 0; | |
| /* for testing, run graceful shutdown */ | |
| #ifdef DEBUGBUILD | |
| - | DEBUGASSERT(!admin->mid); |
| { | |
| const char *p = getenv("CURL_GRACEFUL_SHUTDOWN"); | |
| if(p) { | |
| @@ -338,13 +328,12 @@ void Curl_cshutdn_destroy(struct cshutdn *cshutdn, | |
| } | |
| } | |
| #endif | |
| - | |
| - | CURL_TRC_M(admin, "[SHUTDOWN] destroy, %zu connections, timeout=%dms", |
| - | Curl_llist_count(&cshutdn->list), timeout_ms); |
| - | cshutdn_terminate_all(cshutdn, timeout_ms); |
| + | if(Curl_llist_count(&cshutdn->list)) { |
| + | CURL_TRC_M(admin, "[SHUTDOWN] destroy, %zu connections, timeout=%dms", |
| + | Curl_llist_count(&cshutdn->list), timeout_ms); |
| + | cshutdn_terminate_all(cshutdn, admin, timeout_ms); |
| + | } |
| } | |
| - | cshutdn->multi = NULL; |
| - | cshutdn->initialized = FALSE; |
| } | |
| size_t Curl_cshutdn_count(struct cshutdn *cshutdn) | |
| @@ -372,38 +361,32 @@ size_t Curl_cshutdn_dest_count(struct cshutdn *cshutdn, | |
| return 0; | |
| } | |
| - | static CURLMcode cshutdn_update_ev(struct cshutdn *cshutdn, |
| + | static CURLMcode cshutdn_update_ev(struct Curl_multi *multi, |
| struct connectdata *conn) | |
| { | |
| - | struct Curl_easy *admin = cshutdn->multi->admin; |
| CURLMcode mresult; | |
| - | |
| - | DEBUGASSERT(cshutdn); |
| - | DEBUGASSERT(cshutdn->multi->socket_cb); |
| - | |
| - | Curl_attach_connection(admin, conn, FALSE); |
| - | mresult = Curl_multi_ev_assess_conn(cshutdn->multi, admin, conn); |
| - | Curl_detach_connection(admin); |
| + | Curl_attach_connection(multi->admin, conn, FALSE); |
| + | mresult = Curl_multi_ev_assess_conn(multi, multi->admin, conn); |
| + | Curl_detach_connection(multi->admin); |
| return mresult; | |
| } | |
| void Curl_cshutdn_add(struct cshutdn *cshutdn, | |
| + | struct Curl_multi *multi, |
| struct connectdata *conn, | |
| - | size_t conns_in_pool) |
| + | size_t max_shutdowns) |
| { | |
| - | struct Curl_easy *admin = cshutdn->multi->admin; |
| - | size_t max_total = cshutdn->multi->max_total_connections; |
| + | struct Curl_easy *admin = multi->admin; |
| /* Add the connection to our shutdown list for non-blocking shutdown | |
| * during multi processing. */ | |
| - | if(max_total > 0 && |
| - | (max_total <= (conns_in_pool + Curl_llist_count(&cshutdn->list)))) { |
| + | if(max_shutdowns <= Curl_llist_count(&cshutdn->list)) { |
| CURL_TRC_M(admin, "[SHUTDOWN] discarding oldest shutdown connection " | |
| - | "due to connection limit of %zu", max_total); |
| - | cshutdn_destroy_oldest(cshutdn, NULL); |
| + | "due to shutdown limit of %zu", max_shutdowns); |
| + | cshutdn_destroy_oldest(cshutdn, admin, NULL); |
| } | |
| - | if(cshutdn->multi->socket_cb && cshutdn_update_ev(cshutdn, conn)) { |
| + | if(multi->socket_cb && cshutdn_update_ev(multi, conn)) { |
| CURL_TRC_M(admin, "[SHUTDOWN] update events failed, discarding #%" | |
| FMT_OFF_T, conn->connection_id); | |
| Curl_conn_terminate(admin, conn, FALSE); | |
| @@ -417,18 +400,19 @@ void Curl_cshutdn_add(struct cshutdn *cshutdn, | |
| } | |
| void Curl_cshutdn_perform(struct cshutdn *cshutdn, | |
| + | struct Curl_easy *admin, |
| struct Curl_sigpipe_ctx *sigpipe_ctx) | |
| { | |
| - | cshutdn_perform(cshutdn, sigpipe_ctx); |
| + | cshutdn_perform(cshutdn, admin, sigpipe_ctx); |
| } | |
| /* return fd_set info about the shutdown connections */ | |
| void Curl_cshutdn_setfds(struct cshutdn *cshutdn, | |
| + | struct Curl_easy *admin, |
| fd_set *read_fd_set, fd_set *write_fd_set, | |
| int *maxfd) | |
| { | |
| if(Curl_llist_head(&cshutdn->list)) { | |
| - | struct Curl_easy *admin = cshutdn->multi->admin; |
| struct Curl_llist_node *e; | |
| struct easy_pollset ps; | |
| @@ -465,13 +449,13 @@ void Curl_cshutdn_setfds(struct cshutdn *cshutdn, | |
| /* return information about the shutdown connections */ | |
| unsigned int Curl_cshutdn_add_waitfds(struct cshutdn *cshutdn, | |
| + | struct Curl_easy *admin, |
| struct Curl_waitfds *cwfds) | |
| { | |
| unsigned int need = 0; | |
| if(Curl_llist_head(&cshutdn->list)) { | |
| struct Curl_llist_node *e; | |
| - | struct Curl_easy *admin = cshutdn->multi->admin; |
| struct easy_pollset ps; | |
| struct connectdata *conn; | |
| CURLcode result; | |
| @@ -493,6 +477,7 @@ unsigned int Curl_cshutdn_add_waitfds(struct cshutdn *cshutdn, | |
| } | |
| CURLcode Curl_cshutdn_add_pollfds(struct cshutdn *cshutdn, | |
| + | struct Curl_easy *admin, |
| struct curl_pollfds *cpfds) | |
| { | |
| CURLcode result = CURLE_OK; | |
| @@ -500,7 +485,6 @@ CURLcode Curl_cshutdn_add_pollfds(struct cshutdn *cshutdn, | |
| if(Curl_llist_head(&cshutdn->list)) { | |
| struct Curl_llist_node *e; | |
| struct easy_pollset ps; | |
| - | struct Curl_easy *admin = cshutdn->multi->admin; |
| struct connectdata *conn; | |
| Curl_pollset_init(&ps); | |
| @@ -53,16 +53,10 @@ void Curl_conn_terminate(struct Curl_easy *admin, | |
| * sockets to monitor via the multi handle. */ | |
| struct cshutdn { | |
| struct Curl_llist list; /* connections being shut down */ | |
| - | struct Curl_multi *multi; /* the multi owning this */ |
| - | BIT(initialized); |
| }; | |
| - | /* Get the cshutdn instance relevant for `data` or NULL if there is none */ |
| - | struct cshutdn *Curl_cshutdn_get(struct Curl_easy *data); |
| - | |
| /* Init as part of the given multi handle. */ | |
| - | int Curl_cshutdn_init(struct cshutdn *cshutdn, |
| - | struct Curl_multi *multi); |
| + | void Curl_cshutdn_init(struct cshutdn *cshutdn); |
| /* Terminate all remaining connections and free resources. */ | |
| void Curl_cshutdn_destroy(struct cshutdn *cshutdn, | |
| @@ -79,27 +73,33 @@ size_t Curl_cshutdn_dest_count(struct cshutdn *cshutdn, | |
| * when destination is NULL for any destination. | |
| * Return TRUE if a connection has been closed. */ | |
| bool Curl_cshutdn_close_oldest(struct cshutdn *cshutdn, | |
| + | struct Curl_easy *admin, |
| const char *destination); | |
| /* Add a connection to have it shut down. Terminate the oldest | |
| - | * connection when total connection limit of multi is being reached. */ |
| + | * connection when shutdowns exceed max_shutdowns. */ |
| void Curl_cshutdn_add(struct cshutdn *cshutdn, | |
| + | struct Curl_multi *multi, |
| struct connectdata *conn, | |
| - | size_t conns_in_pool); |
| + | size_t max_shutdowns); |
| /* Add sockets and POLLIN/OUT flags for connections being shut down. */ | |
| CURLcode Curl_cshutdn_add_pollfds(struct cshutdn *cshutdn, | |
| + | struct Curl_easy *admin, |
| struct curl_pollfds *cpfds); | |
| unsigned int Curl_cshutdn_add_waitfds(struct cshutdn *cshutdn, | |
| + | struct Curl_easy *admin, |
| struct Curl_waitfds *cwfds); | |
| void Curl_cshutdn_setfds(struct cshutdn *cshutdn, | |
| + | struct Curl_easy *admin, |
| fd_set *read_fd_set, fd_set *write_fd_set, | |
| int *maxfd); | |
| /* Run maintenance on all connections. */ | |
| void Curl_cshutdn_perform(struct cshutdn *cshutdn, | |
| + | struct Curl_easy *admin, |
| struct Curl_sigpipe_ctx *sigpipe_ctx); | |
| #endif /* HEADER_CURL_CSHUTDN_H */ | |
| @@ -260,6 +260,7 @@ struct Curl_multi *Curl_multi_handle(uint32_t xfer_table_size, | |
| Curl_uint32_bset_init(&multi->pending); | |
| Curl_uint32_bset_init(&multi->msgsent); | |
| Curl_hash_init(&multi->proto_hash, 23, CURL_HASH_TYPE_BYTES, ph_freeentry); | |
| + | Curl_cshutdn_init(&multi->cshutdn); |
| multi->multiplexing = TRUE; | |
| multi->max_concurrent_streams = 100; | |
| @@ -286,9 +287,6 @@ struct Curl_multi *Curl_multi_handle(uint32_t xfer_table_size, | |
| Curl_uint32_tbl_add(&multi->xfers, multi->admin, &multi->admin->mid); | |
| Curl_uint32_bset_add(&multi->process, multi->admin->mid); | |
| - | if(Curl_cshutdn_init(&multi->cshutdn, multi)) |
| - | goto error; |
| - | |
| Curl_cpool_init(&multi->cpool, NULL, chashsize); | |
| #ifdef USE_SSL | |
| @@ -1279,8 +1277,8 @@ CURLMcode curl_multi_fdset(CURLM *m, | |
| } while(Curl_uint32_bset_next(&multi->process, mid, &mid)); | |
| } | |
| - | Curl_cshutdn_setfds(&multi->cshutdn, read_fd_set, write_fd_set, |
| - | &this_max_fd); |
| + | Curl_cshutdn_setfds(&multi->cshutdn, multi->admin, |
| + | read_fd_set, write_fd_set, &this_max_fd); |
| *max_fd = this_max_fd; | |
| Curl_pollset_cleanup(&ps); | |
| @@ -1328,7 +1326,7 @@ CURLMcode curl_multi_waitfds(CURLM *m, | |
| } while(Curl_uint32_bset_next(&multi->process, mid, &mid)); | |
| } | |
| - | need += Curl_cshutdn_add_waitfds(&multi->cshutdn, &cwfds); |
| + | need += Curl_cshutdn_add_waitfds(&multi->cshutdn, multi->admin, &cwfds); |
| if(need != cwfds.n && ufds) | |
| mresult = CURLM_OUT_OF_MEMORY; | |
| @@ -1563,7 +1561,7 @@ static CURLMcode multi_wait(struct Curl_multi *multi, | |
| } while(Curl_uint32_bset_next(&multi->process, mid, &mid)); | |
| } | |
| - | if(Curl_cshutdn_add_pollfds(&multi->cshutdn, &cpfds)) { |
| + | if(Curl_cshutdn_add_pollfds(&multi->cshutdn, multi->admin, &cpfds)) { |
| mresult = CURLM_OUT_OF_MEMORY; | |
| goto out; | |
| } | |
| @@ -2741,7 +2739,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, | |
| #ifdef USE_RESOLV_THREADED | |
| Curl_async_thrdd_multi_process(multi); | |
| #endif | |
| - | Curl_cshutdn_perform(&multi->cshutdn, sigpipe_ctx); |
| + | Curl_cshutdn_perform(&multi->cshutdn, multi->admin, sigpipe_ctx); |
| goto out; | |
| } | |