connection: attached transfer count
No binary (build failed)
—
(log yok)
| @@ -620,7 +620,7 @@ static void cpool_discard_conn(struct cpool *cpool, | |
| if(CONN_INUSE(conn) && !aborted) { | |
| CURL_TRC_M(data, "[CPOOL] not discarding #%" FMT_OFF_T | |
| " still in use by %u transfers", conn->connection_id, | |
| - | CONN_ATTACHED(conn)); |
| + | conn->attached_xfers); |
| return; | |
| } | |
| @@ -664,7 +664,7 @@ void Curl_conn_terminate(struct Curl_easy *data, | |
| * are other users of it */ | |
| if(CONN_INUSE(conn) && !aborted) { | |
| DEBUGASSERT(0); /* does this ever happen? */ | |
| - | DEBUGF(infof(data, "Curl_disconnect when inuse: %u", CONN_ATTACHED(conn))); |
| + | DEBUGF(infof(data, "conn terminate when inuse: %u", conn->attached_xfers)); |
| return; | |
| } | |
| @@ -2786,7 +2786,7 @@ static CURLcode cf_h2_query(struct Curl_cfilter *cf, | |
| CF_DATA_SAVE(save, cf, data); | |
| if(!ctx->h2 || !nghttp2_session_check_request_allowed(ctx->h2)) { | |
| /* the limit is what we have in use right now */ | |
| - | effective_max = CONN_ATTACHED(cf->conn); |
| + | effective_max = cf->conn->attached_xfers; |
| } | |
| else { | |
| effective_max = ctx->max_concurrent_streams; | |
| @@ -607,12 +607,11 @@ static void multi_done_locked(struct connectdata *conn, | |
| Curl_detach_connection(data); | |
| - | CURL_TRC_M(data, "multi_done_locked, in use=%u", |
| - | Curl_uint32_spbset_count(&conn->xfers_attached)); |
| + | CURL_TRC_M(data, "multi_done_locked, in use=%u", conn->attached_xfers); |
| if(CONN_INUSE(conn)) { | |
| /* Stop if still used. */ | |
| CURL_TRC_M(data, "Connection still in use %u, no more multi_done now!", | |
| - | Curl_uint32_spbset_count(&conn->xfers_attached)); |
| + | conn->attached_xfers); |
| return; | |
| } | |
| @@ -906,9 +905,13 @@ void Curl_detach_connection(struct Curl_easy *data) | |
| { | |
| struct connectdata *conn = data->conn; | |
| if(conn) { | |
| - | Curl_uint32_spbset_remove(&conn->xfers_attached, data->mid); |
| - | if(Curl_uint32_spbset_empty(&conn->xfers_attached)) |
| - | conn->attached_multi = NULL; |
| + | /* this should never happen, prevent underflow */ |
| + | DEBUGASSERT(conn->attached_xfers); |
| + | if(conn->attached_xfers) { |
| + | conn->attached_xfers--; |
| + | if(!conn->attached_xfers) |
| + | conn->attached_multi = NULL; |
| + | } |
| } | |
| data->conn = NULL; | |
| } | |
| @@ -924,8 +927,9 @@ void Curl_attach_connection(struct Curl_easy *data, | |
| DEBUGASSERT(data); | |
| DEBUGASSERT(!data->conn); | |
| DEBUGASSERT(conn); | |
| + | DEBUGASSERT(conn->attached_xfers < UINT32_MAX); |
| data->conn = conn; | |
| - | Curl_uint32_spbset_add(&conn->xfers_attached, data->mid); |
| + | conn->attached_xfers++; |
| /* all attached transfers must be from the same multi */ | |
| if(!conn->attached_multi) | |
| conn->attached_multi = data->multi; | |
| @@ -61,20 +61,6 @@ uint32_t Curl_uint32_spbset_count(struct uint32_spbset *bset) | |
| return n; | |
| } | |
| - | bool Curl_uint32_spbset_empty(struct uint32_spbset *bset) |
| - | { |
| - | struct uint32_spbset_chunk *chunk; |
| - | uint32_t i; |
| - | |
| - | for(chunk = &bset->head; chunk; chunk = chunk->next) { |
| - | for(i = 0; i < CURL_UINT32_SPBSET_CH_SLOTS; ++i) { |
| - | if(chunk->slots[i]) |
| - | return FALSE; |
| - | } |
| - | } |
| - | return TRUE; |
| - | } |
| - | |
| UNITTEST void Curl_uint32_spbset_clear(struct uint32_spbset *bset) | |
| { | |
| struct uint32_spbset_chunk *next, *chunk; | |
| @@ -61,9 +61,6 @@ void Curl_uint32_spbset_destroy(struct uint32_spbset *bset); | |
| /* Get the cardinality of the bitset, e.g. numbers present in the set. */ | |
| uint32_t Curl_uint32_spbset_count(struct uint32_spbset *bset); | |
| - | /* TRUE of bitset is empty */ |
| - | bool Curl_uint32_spbset_empty(struct uint32_spbset *bset); |
| - | |
| /* Add the number `i` to the bitset. | |
| * Numbers can be added more than once, without making a difference. | |
| * Returns FALSE if allocations failed. */ | |
| @@ -561,7 +561,6 @@ void Curl_conn_free(struct Curl_easy *data, struct connectdata *conn) | |
| Curl_safefree(conn->unix_domain_socket); | |
| #endif | |
| Curl_safefree(conn->destination); | |
| - | Curl_uint32_spbset_destroy(&conn->xfers_attached); |
| Curl_hash_destroy(&conn->meta_hash); | |
| curlx_free(conn); /* free all the connection oriented data */ | |
| @@ -893,16 +892,16 @@ static bool url_match_multiplex_limits(struct connectdata *conn, | |
| if(CONN_INUSE(conn) && m->may_multiplex) { | |
| DEBUGASSERT(conn->bits.multiplex); | |
| /* If multiplexed, make sure we do not go over concurrency limit */ | |
| - | if(CONN_ATTACHED(conn) >= |
| + | if(conn->attached_xfers >= |
| Curl_multi_max_concurrent_streams(m->data->multi)) { | |
| infof(m->data, "client side MAX_CONCURRENT_STREAMS reached" | |
| - | ", skip (%u)", CONN_ATTACHED(conn)); |
| + | ", skip (%u)", conn->attached_xfers); |
| return FALSE; | |
| } | |
| - | if(CONN_ATTACHED(conn) >= |
| + | if(conn->attached_xfers >= |
| Curl_conn_get_max_concurrent(m->data, conn, FIRSTSOCKET)) { | |
| infof(m->data, "MAX_CONCURRENT_STREAMS reached, skip (%u)", | |
| - | CONN_ATTACHED(conn)); |
| + | conn->attached_xfers); |
| return FALSE; | |
| } | |
| /* When not multiplexed, we have a match here! */ | |
| @@ -1343,6 +1342,7 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) | |
| conn->recv_idx = 0; /* default for receiving transfer data */ | |
| conn->send_idx = 0; /* default for sending transfer data */ | |
| conn->connection_id = -1; /* no ID */ | |
| + | conn->attached_xfers = 0; |
| conn->remote_port = -1; /* unknown at this point */ | |
| /* Store creation time to help future close decision making */ | |
| @@ -1382,9 +1382,6 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) | |
| conn->connect_only = data->set.connect_only; | |
| conn->transport_wanted = TRNSPRT_TCP; /* most of them are TCP streams */ | |
| - | /* Initialize the attached xfers bitset */ |
| - | Curl_uint32_spbset_init(&conn->xfers_attached); |
| - | |
| /* Store the local bind parameters that will be used for this connection */ | |
| if(data->set.str[STRING_DEVICE]) { | |
| conn->localdev = curlx_strdup(data->set.str[STRING_DEVICE]); | |
| @@ -3806,7 +3803,7 @@ CURLcode Curl_connect(struct Curl_easy *data, | |
| DEBUGASSERT(conn); | |
| Curl_pgrsTime(data, TIMER_POSTQUEUE); | |
| if(reused) { | |
| - | if(CONN_ATTACHED(conn) > 1) |
| + | if(conn->attached_xfers > 1) |
| /* multiplexed */ | |
| *protocol_done = TRUE; | |
| } | |
| @@ -618,8 +618,7 @@ struct connectdata { | |
| handle is still used by one or more easy handles and can only used by any | |
| other easy handle without careful consideration (== only for | |
| multiplexing) and it cannot be used by another multi handle! */ | |
| - | #define CONN_INUSE(c) (!Curl_uint32_spbset_empty(&(c)->xfers_attached)) |
| - | #define CONN_ATTACHED(c) Curl_uint32_spbset_count(&(c)->xfers_attached) |
| + | #define CONN_INUSE(c) (!!(c)->attached_xfers) |
| /**** Fields set when inited and not modified again */ | |
| curl_off_t connection_id; /* Contains a unique number to make it easier to | |
| @@ -679,7 +678,6 @@ struct connectdata { | |
| was used on this connection. */ | |
| struct curltime keepalive; | |
| - | struct uint32_spbset xfers_attached; /* mids of attached transfers */ |
| /* A connection cache from a SHARE might be used in several multi handles. | |
| * We MUST not reuse connections that are running in another multi, | |
| * for concurrency reasons. That multi might run in another thread. | |
| @@ -721,6 +719,9 @@ struct connectdata { | |
| int remote_port; /* the remote port, not the proxy port! */ | |
| int conn_to_port; /* the remote port to connect to. valid only if | |
| bits.conn_to_port is set */ | |
| + | |
| + | uint32_t attached_xfers; /* # of attached easy handles */ |
| + | |
| #ifdef USE_IPV6 | |
| unsigned int scope_id; /* Scope id for IPv6 */ | |
| #endif | |
| @@ -2718,7 +2718,7 @@ static CURLcode cf_ngtcp2_query(struct Curl_cfilter *cf, | |
| } | |
| else if(ctx->max_bidi_streams) { | |
| uint64_t avail_bidi_streams = 0; | |
| - | uint64_t max_streams = CONN_ATTACHED(cf->conn); |
| + | uint64_t max_streams = cf->conn->attached_xfers; |
| if(ctx->max_bidi_streams > ctx->used_bidi_streams) | |
| avail_bidi_streams = ctx->max_bidi_streams - ctx->used_bidi_streams; | |
| max_streams += avail_bidi_streams; | |
| @@ -2728,7 +2728,7 @@ static CURLcode cf_ngtcp2_query(struct Curl_cfilter *cf, | |
| *pres1 = (int)Curl_multi_max_concurrent_streams(data->multi); | |
| CURL_TRC_CF(data, cf, "query conn[%" FMT_OFF_T "]: " | |
| "MAX_CONCURRENT -> %d (%u in use)", | |
| - | cf->conn->connection_id, *pres1, CONN_ATTACHED(cf->conn)); |
| + | cf->conn->connection_id, *pres1, cf->conn->attached_xfers); |
| CF_DATA_RESTORE(cf, save); | |
| return CURLE_OK; | |
| } | |
| @@ -2323,7 +2323,7 @@ static CURLcode cf_osslq_query(struct Curl_cfilter *cf, | |
| return CURLE_HTTP3; | |
| } | |
| /* we report avail + in_use */ | |
| - | v += CONN_ATTACHED(cf->conn); |
| + | v += cf->conn->attached_xfers; |
| *pres1 = (v > INT_MAX) ? INT_MAX : (int)v; | |
| #else | |
| *pres1 = 100; | |
| @@ -1493,14 +1493,14 @@ static CURLcode cf_quiche_query(struct Curl_cfilter *cf, | |
| switch(query) { | |
| case CF_QUERY_MAX_CONCURRENT: { | |
| - | uint64_t max_streams = CONN_ATTACHED(cf->conn); |
| + | uint64_t max_streams = cf->conn->attached_xfers; |
| if(!ctx->goaway && ctx->qconn) { | |
| max_streams += quiche_conn_peer_streams_left_bidi(ctx->qconn); | |
| } | |
| *pres1 = (max_streams > INT_MAX) ? INT_MAX : (int)max_streams; | |
| CURL_TRC_CF(data, cf, "query conn[%" FMT_OFF_T "]: " | |
| "MAX_CONCURRENT -> %d (%u in use)", | |
| - | cf->conn->connection_id, *pres1, CONN_ATTACHED(cf->conn)); |
| + | cf->conn->connection_id, *pres1, cf->conn->attached_xfers); |
| return CURLE_OK; | |
| } | |
| case CF_QUERY_CONNECT_REPLY_MS: | |