From: Stephan Bosch Date: Thu, 6 Sep 2018 01:33:59 +0000 (+0200) Subject: lib-http: client: peer: Maintain a list of connections pending on behalf of a peer. X-Git-Tag: 2.3.4~213 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2e410c7cac56f11c556daf4906978a4859a594d8;p=thirdparty%2Fdovecot%2Fcore.git lib-http: client: peer: Maintain a list of connections pending on behalf of a peer. Before, pending connections were only listed in the peer pool. --- diff --git a/src/lib-http/http-client-connection.c b/src/lib-http/http-client-connection.c index abb7bb9223..4411db7b89 100644 --- a/src/lib-http/http-client-connection.c +++ b/src/lib-http/http-client-connection.c @@ -48,11 +48,12 @@ http_client_connection_unref_request(struct http_client_connection *conn, static void http_client_connection_unlist_pending(struct http_client_connection *conn) { + struct http_client_peer *peer = conn->peer; struct http_client_peer_pool *ppool = conn->ppool; ARRAY_TYPE(http_client_connection) *conn_arr; struct http_client_connection *const *conn_idx; - /* remove from pending list */ + /* remove from pending lists */ conn_arr = &ppool->pending_conns; array_foreach(conn_arr, conn_idx) { @@ -62,6 +63,18 @@ http_client_connection_unlist_pending(struct http_client_connection *conn) break; } } + + if (peer == NULL) + return; + + conn_arr = &peer->pending_conns; + array_foreach(conn_arr, conn_idx) { + if (*conn_idx == conn) { + array_delete(conn_arr, + array_foreach_idx(conn_arr, conn_idx), 1); + break; + } + } } static inline void @@ -371,9 +384,16 @@ http_client_connection_detach_peer(struct http_client_connection *conn) break; } } - i_assert(found); + conn_arr = &peer->pending_conns; + array_foreach(conn_arr, conn_idx) { + if (*conn_idx == conn) { + array_delete(conn_arr, array_foreach_idx(conn_arr, conn_idx), 1); + break; + } + } + conn->peer = NULL; e_debug(conn->event, "Detached peer"); @@ -1703,6 +1723,7 @@ http_client_connection_create(struct http_client_peer *peer) array_append(&ppool->pending_conns, &conn, 1); array_append(&ppool->conns, &conn, 1); + array_append(&peer->pending_conns, &conn, 1); array_append(&peer->conns, &conn, 1); http_client_peer_pool_ref(ppool); diff --git a/src/lib-http/http-client-peer.c b/src/lib-http/http-client-peer.c index afa71e94ec..3116fe3456 100644 --- a/src/lib-http/http-client-peer.c +++ b/src/lib-http/http-client-peer.c @@ -569,6 +569,7 @@ http_client_peer_create(struct http_client *client, i_array_init(&peer->queues, 16); i_array_init(&peer->conns, 16); + i_array_init(&peer->pending_conns, 16); DLLIST_PREPEND_FULL (&client->peers_list, peer, client_prev, client_next); @@ -624,6 +625,7 @@ http_client_peer_disconnect(struct http_client_peer *peer) array_foreach_modifiable(&conns, conn) http_client_connection_lost_peer(*conn); i_assert(array_count(&peer->conns) == 0); + array_clear(&peer->pending_conns); timeout_remove(&peer->to_req_handling); @@ -661,6 +663,7 @@ bool http_client_peer_unref(struct http_client_peer **_peer) event_unref(&peer->event); array_free(&peer->conns); + array_free(&peer->pending_conns); array_free(&peer->queues); i_free(peer); @@ -838,6 +841,7 @@ http_client_peer_cancel(struct http_client_peer *peer) if (!http_client_connection_is_active(*conn)) http_client_connection_close(conn); } + i_assert(array_count(&peer->pending_conns) == 0); } static unsigned int @@ -926,7 +930,7 @@ http_client_peer_handle_requests_real(struct http_client_peer *peer) bool conn_lost = FALSE; array_clear(&conns_avail); - connecting = closing = idle = 0; + closing = idle = 0; /* gather connection statistics */ array_foreach(&peer->conns, conn_idx) { @@ -962,8 +966,6 @@ http_client_peer_handle_requests_real(struct http_client_peer *peer) /* count the number of connecting and closing connections */ if (conn->closing) closing++; - else if (!conn->connected) - connecting++; } if (conn_lost) { @@ -1020,6 +1022,7 @@ http_client_peer_handle_requests_real(struct http_client_peer *peer) return; i_assert(idle == 0); + connecting = array_count(&peer->pending_conns); /* determine how many new connections we can set up */ if (pshared->last_failure.tv_sec > 0 && working_conn_count > 0 && @@ -1315,16 +1318,7 @@ http_client_peer_active_connections(struct http_client_peer *peer) unsigned int http_client_peer_pending_connections(struct http_client_peer *peer) { - struct http_client_connection *const *conn_idx; - unsigned int pending = 0; - - /* find idle connections */ - array_foreach(&peer->conns, conn_idx) { - if (!(*conn_idx)->closing && !(*conn_idx)->connected) - pending++; - } - - return pending; + return array_count(&peer->pending_conns); } void http_client_peer_switch_ioloop(struct http_client_peer *peer) diff --git a/src/lib-http/http-client-private.h b/src/lib-http/http-client-private.h index 130807698c..38bc2a6314 100644 --- a/src/lib-http/http-client-private.h +++ b/src/lib-http/http-client-private.h @@ -274,6 +274,8 @@ struct http_client_peer { /* active connections to this peer */ ARRAY_TYPE(http_client_connection) conns; + /* pending connections (not ready connecting) */ + ARRAY_TYPE(http_client_connection) pending_conns; /* zero time-out for consolidating request handling */ struct timeout *to_req_handling;