From: Timo Sirainen Date: Mon, 9 Sep 2019 13:30:51 +0000 (+0300) Subject: imap-hibernate: Stop listening for IOs while waiting for unhibernate retrying X-Git-Tag: 2.3.10~304 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2a6a95bb76b1ecbae830f4035927d24b4ae90451;p=thirdparty%2Fdovecot%2Fcore.git imap-hibernate: Stop listening for IOs while waiting for unhibernate retrying This avoids excessive CPU usage, because the IOs keep rapidly triggering and trying to get the client unhibernated. --- diff --git a/src/imap-hibernate/imap-client.c b/src/imap-hibernate/imap-client.c index 64348e8b5c..21aa1cd992 100644 --- a/src/imap-hibernate/imap-client.c +++ b/src/imap-hibernate/imap-client.c @@ -88,6 +88,7 @@ static void imap_client_stop(struct imap_client *client); void imap_client_destroy(struct imap_client **_client, const char *reason); static void imap_client_add_idle_keepalive_timeout(struct imap_client *client); static void imap_clients_unhibernate(void *context); +static void imap_client_stop_notify_listening(struct imap_client *client); static void imap_client_disconnected(struct imap_client **_client) { @@ -236,6 +237,13 @@ static bool imap_client_try_move_back(struct imap_client *client) imap_client_destroy(&client, error); return TRUE; } + /* Stop listening for client's IOs while waiting for the next + reconnection attempt. However if we got here because of an external + notification keep waiting to see if client sends any IO, since that + will cause the unhibernation to be aborted earlier. */ + if (client->input_pending) + io_remove(&client->io); + imap_client_stop_notify_listening(client); return FALSE; } @@ -581,21 +589,25 @@ imap_client_create(int fd, const struct imap_client_state *state) return client; } -static void imap_client_stop(struct imap_client *client) +static void imap_client_stop_notify_listening(struct imap_client *client) { struct imap_client_notify *notify; + array_foreach_modifiable(&client->notifys, notify) { + io_remove(¬ify->io); + i_close_fd(¬ify->fd); + } +} + +static void imap_client_stop(struct imap_client *client) +{ if (client->unhibernate_queued) { priorityq_remove(unhibernate_queue, &client->item); client->unhibernate_queued = FALSE; } io_remove(&client->io); timeout_remove(&client->to_keepalive); - - array_foreach_modifiable(&client->notifys, notify) { - io_remove(¬ify->io); - i_close_fd(¬ify->fd); - } + imap_client_stop_notify_listening(client); } void imap_client_destroy(struct imap_client **_client, const char *reason)