106 lines
3.7 KiB
Diff
106 lines
3.7 KiB
Diff
From 1a27cfa8e337b7e3298ba230059e766cdbc1123d Mon Sep 17 00:00:00 2001
|
|
From: Timo Sirainen <timo.sirainen@open-xchange.com>
|
|
Date: Mon, 24 Aug 2020 19:10:43 +0300
|
|
Subject: [PATCH] imap: imap_client_hibernate() - Return reason string on
|
|
failure
|
|
|
|
This helps writing a unit test for it.
|
|
---
|
|
src/imap/cmd-idle.c | 3 ++-
|
|
src/imap/imap-client-hibernate.c | 10 +++++++++-
|
|
src/imap/imap-client.h | 5 +++--
|
|
3 files changed, 14 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/src/imap/cmd-idle.c b/src/imap/cmd-idle.c
|
|
index 8a05582d03..2b31dc714e 100644
|
|
--- a/src/imap/cmd-idle.c
|
|
+++ b/src/imap/cmd-idle.c
|
|
@@ -175,11 +175,12 @@ static void idle_add_keepalive_timeout(struct cmd_idle_context *ctx)
|
|
static void idle_hibernate_timeout(struct cmd_idle_context *ctx)
|
|
{
|
|
struct client *client = ctx->client;
|
|
+ const char *reason;
|
|
|
|
i_assert(ctx->sync_ctx == NULL);
|
|
i_assert(!ctx->sync_pending);
|
|
|
|
- if (imap_client_hibernate(&client)) {
|
|
+ if (imap_client_hibernate(&client, &reason)) {
|
|
/* client may be destroyed now */
|
|
} else {
|
|
/* failed - don't bother retrying */
|
|
diff --git a/src/imap/imap-client-hibernate.c b/src/imap/imap-client-hibernate.c
|
|
index d3451b1bf6..0709e4a244 100644
|
|
--- a/src/imap/imap-client-hibernate.c
|
|
+++ b/src/imap/imap-client-hibernate.c
|
|
@@ -203,19 +203,23 @@ imap_hibernate_process_send(struct client *client, const buffer_t *state,
|
|
return 0;
|
|
}
|
|
|
|
-bool imap_client_hibernate(struct client **_client)
|
|
+bool imap_client_hibernate(struct client **_client, const char **reason_r)
|
|
{
|
|
struct client *client = *_client;
|
|
buffer_t *state;
|
|
const char *error;
|
|
int ret, fd_notify = -1, fd_hibernate = -1;
|
|
|
|
+ *reason_r = NULL;
|
|
+
|
|
if (client->fd_in != client->fd_out) {
|
|
/* we won't try to hibernate stdio clients */
|
|
+ *reason_r = "stdio clients can't be hibernated";
|
|
return FALSE;
|
|
}
|
|
if (o_stream_get_buffer_used_size(client->output) > 0) {
|
|
/* wait until we've sent the pending output to client */
|
|
+ *reason_r = "output pending to client";
|
|
return FALSE;
|
|
}
|
|
|
|
@@ -233,11 +237,13 @@ bool imap_client_hibernate(struct client **_client)
|
|
"Couldn't export state: %s (mailbox=%s)", error,
|
|
client->mailbox == NULL ? "" :
|
|
mailbox_get_vname(client->mailbox));
|
|
+ *reason_r = error;
|
|
} else if (ret == 0) {
|
|
e_debug(client->event, "Couldn't hibernate imap client: "
|
|
"Couldn't export state: %s (mailbox=%s)", error,
|
|
client->mailbox == NULL ? "" :
|
|
mailbox_get_vname(client->mailbox));
|
|
+ *reason_r = error;
|
|
}
|
|
if (ret > 0 && client->mailbox != NULL) {
|
|
fd_notify = mailbox_watch_extract_notify_fd(client->mailbox,
|
|
@@ -248,6 +254,7 @@ bool imap_client_hibernate(struct client **_client)
|
|
e_debug(client->event, "Couldn't hibernate imap client: "
|
|
"Couldn't extract notifications fd: %s",
|
|
error);
|
|
+ *reason_r = error;
|
|
ret = -1;
|
|
}
|
|
}
|
|
@@ -257,5 +264,6 @@ bool imap_client_hibernate(struct client **_client)
|
|
e_error(client->event,
|
|
"Couldn't hibernate imap client: %s", error);
|
|
+ *reason_r = error;
|
|
ret = -1;
|
|
}
|
|
}
|
|
diff --git a/src/imap/imap-client.h b/src/imap/imap-client.h
|
|
index f2ffe0d7c9..4e591d5c7c 100644
|
|
--- a/src/imap/imap-client.h
|
|
+++ b/src/imap/imap-client.h
|
|
@@ -323,8 +323,9 @@ enum mailbox_feature client_enabled_mailbox_features(struct client *client);
|
|
const char *const *client_enabled_features(struct client *client);
|
|
|
|
/* Send client processing to imap-idle process. If successful, returns TRUE
|
|
- and destroys the client. */
|
|
-bool imap_client_hibernate(struct client **client);
|
|
+ and destroys the client. If hibernation failed, the exact reason is
|
|
+ returned (mainly for unit tests). */
|
|
+bool imap_client_hibernate(struct client **client, const char **reason_r);
|
|
|
|
struct imap_search_update *
|
|
client_search_update_lookup(struct client *client, const char *tag,
|