dovecot-1.2: imap: IDLE now sends "Still here" notifications to ...

dovecot at dovecot.org dovecot at dovecot.org
Fri Oct 16 01:31:20 EEST 2009


details:   http://hg.dovecot.org/dovecot-1.2/rev/373b22cbabac
changeset: 9434:373b22cbabac
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Oct 15 18:27:16 2009 -0400
description:
imap: IDLE now sends "Still here" notifications to same user's connections at the same time.
Perhaps this will save some battery power with mobile clients that open
multiple connections.

diffstat:

1 file changed, 28 insertions(+), 9 deletions(-)
src/imap/cmd-idle.c |   37 ++++++++++++++++++++++++++++---------

diffs (83 lines):

diff -r 6c6460531514 -r 373b22cbabac src/imap/cmd-idle.c
--- a/src/imap/cmd-idle.c	Thu Oct 15 15:56:06 2009 -0400
+++ b/src/imap/cmd-idle.c	Thu Oct 15 18:27:16 2009 -0400
@@ -4,7 +4,9 @@
 #include "ioloop.h"
 #include "istream.h"
 #include "ostream.h"
+#include "crc32.h"
 #include "commands.h"
+#include "mail-user.h"
 #include "imap-sync.h"
 
 #include <stdlib.h>
@@ -25,6 +27,7 @@ struct cmd_idle_context {
 	unsigned int sync_pending:1;
 };
 
+static void idle_add_keepalive_timeout(struct cmd_idle_context *ctx);
 static bool cmd_idle_continue(struct client_command_context *cmd);
 
 static void
@@ -112,6 +115,8 @@ static void keepalive_timeout(struct cmd
 	   several clients that really want to IDLE forever and there's not
 	   much harm in letting them do so. */
 	timeout_reset(ctx->client->to_idle);
+	/* recalculate time for the next keepalive timeout */
+	idle_add_keepalive_timeout(ctx);
 }
 
 static void idle_sync_now(struct mailbox *box, struct cmd_idle_context *ctx)
@@ -131,6 +136,27 @@ static void idle_callback(struct mailbox
 		ctx->manual_cork = TRUE;
 		idle_sync_now(box, ctx);
 	}
+}
+
+static void idle_add_keepalive_timeout(struct cmd_idle_context *ctx)
+{
+	const char *value;
+	unsigned int interval;
+
+	value = getenv("IMAP_IDLE_NOTIFY_INTERVAL");
+	interval = value != NULL ?
+		(unsigned int)strtoul(value, NULL, 10) :
+		DEFAULT_IMAP_IDLE_NOTIFY_INTERVAL;
+	if (interval == 0)
+		return;
+
+	interval -= (time(NULL) +
+		     crc32_str(ctx->client->user->username)) % interval;
+
+	if (ctx->keepalive_to != NULL)
+		timeout_remove(&ctx->keepalive_to);
+	ctx->keepalive_to = timeout_add(interval * 1000,
+					keepalive_timeout, ctx);
 }
 
 static bool cmd_idle_continue(struct client_command_context *cmd)
@@ -170,7 +196,7 @@ static bool cmd_idle_continue(struct cli
 	}
 	if (client->output->offset != orig_offset &&
 	    ctx->keepalive_to != NULL)
-		timeout_reset(ctx->keepalive_to);
+		idle_add_keepalive_timeout(ctx);
 
 	if (ctx->sync_pending) {
 		/* more changes occurred while we were sending changes to
@@ -210,14 +236,7 @@ bool cmd_idle(struct client_command_cont
 	ctx = p_new(cmd->pool, struct cmd_idle_context, 1);
 	ctx->cmd = cmd;
 	ctx->client = client;
-
-	str = getenv("IMAP_IDLE_NOTIFY_INTERVAL");
-	interval = str != NULL ?
-		(unsigned int)strtoul(str, NULL, 10) :
-		DEFAULT_IMAP_IDLE_NOTIFY_INTERVAL;
-	ctx->keepalive_to = interval == 0 ? NULL :
-		timeout_add(interval * 1000,
-			    keepalive_timeout, ctx);
+	idle_add_keepalive_timeout(ctx);
 
 	str = getenv("MAILBOX_IDLE_CHECK_INTERVAL");
 	interval = str == NULL ? 0 : (unsigned int)strtoul(str, NULL, 10);


More information about the dovecot-cvs mailing list