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.3.0.rc1~2718 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c1423bdba971228a283653222ed0367f84ab6402;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 ea0283938d..f4d14e573d 100644 --- a/src/lib-http/http-client-peer.c +++ b/src/lib-http/http-client-peer.c @@ -555,6 +555,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; @@ -575,9 +576,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) @@ -600,6 +607,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 1c1ec8aa7a..f01820d5dd 100644 --- a/src/lib-http/http-client-private.h +++ b/src/lib-http/http-client-private.h @@ -491,6 +491,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); /* 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 */