From: Stephan Bosch Date: Thu, 15 Sep 2016 00:09:47 +0000 (+0200) Subject: lib-http: client: Unlink all queues from peer when it is disconnected. X-Git-Tag: 2.2.27~233 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0c43fc213abb050ca43f7c97bda391c4d3113664;p=thirdparty%2Fdovecot%2Fcore.git lib-http: client: Unlink all queues from peer when it is disconnected. Before, queues were only destroyed when the whole client was destroyed. This change and subsequent changes prepare for being able to destroy a queue when it becomes unused. --- diff --git a/src/lib-http/http-client-peer.c b/src/lib-http/http-client-peer.c index 2a5b9d1196..c20a1e89cb 100644 --- a/src/lib-http/http-client-peer.c +++ b/src/lib-http/http-client-peer.c @@ -538,6 +538,7 @@ http_client_peer_disconnect(struct http_client_peer *peer) { struct http_client_connection **conn; ARRAY_TYPE(http_client_connection) conns; + struct http_client_queue *const *queue; if (peer->disconnected) return; @@ -558,9 +559,15 @@ http_client_peer_disconnect(struct http_client_peer *peer) if (peer->to_backoff != NULL) timeout_remove(&peer->to_backoff); + /* unlist in client */ hash_table_remove (peer->client->peers, (const struct http_client_peer_addr *)&peer->addr); DLLIST_REMOVE(&peer->client->peers_list, peer); + + /* unlink all queues */ + array_foreach(&peer->queues, queue) + http_client_queue_peer_disconnected(*queue, peer); + array_clear(&peer->queues); } void http_client_peer_ref(struct http_client_peer *peer) @@ -583,6 +590,8 @@ bool http_client_peer_unref(struct http_client_peer **_peer) http_client_peer_disconnect(peer); + i_assert(array_count(&peer->queues) == 0); + array_free(&peer->conns); array_free(&peer->queues); i_free(peer->addr_name); diff --git a/src/lib-http/http-client-private.h b/src/lib-http/http-client-private.h index 332f69501b..876be910a4 100644 --- a/src/lib-http/http-client-private.h +++ b/src/lib-http/http-client-private.h @@ -399,6 +399,8 @@ http_client_queue_connection_success(struct http_client_queue *queue, const struct http_client_peer_addr *addr); void http_client_queue_connection_failure(struct http_client_queue *queue, const struct http_client_peer_addr *addr, const char *reason); +void http_client_queue_peer_disconnected(struct http_client_queue *queue, + struct http_client_peer *peer); void http_client_queue_switch_ioloop(struct http_client_queue *queue); struct http_client_host * diff --git a/src/lib-http/http-client-queue.c b/src/lib-http/http-client-queue.c index 7b7e921b13..56e6499c98 100644 --- a/src/lib-http/http-client-queue.c +++ b/src/lib-http/http-client-queue.c @@ -422,6 +422,24 @@ http_client_queue_connection_failure(struct http_client_queue *queue, return; } +void +http_client_queue_peer_disconnected(struct http_client_queue *queue, + struct http_client_peer *peer) +{ + struct http_client_peer *const *peer_idx; + + if (!array_is_created(&queue->pending_peers)) + return; + + array_foreach(&queue->pending_peers, peer_idx) { + if (*peer_idx == peer) { + array_delete(&queue->pending_peers, + array_foreach_idx(&queue->pending_peers, peer_idx), 1); + break; + } + } +} + /* * Main request queue */