changeset 3777:39c293635875 HEAD

Don't crash if client disconnected in IDLE. If mailbox had been changed before IDLE was started, show the changes immediately. If more changes happened to mailbox while we were sending older changes to client, we crashed.
author Timo Sirainen <tss@iki.fi>
date Fri, 30 Dec 2005 21:49:38 +0200
parents 0cae3268c8af
children 91689264d812
files src/imap/cmd-idle.c
diffstat 1 files changed, 17 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/imap/cmd-idle.c	Fri Dec 30 21:34:06 2005 +0200
+++ b/src/imap/cmd-idle.c	Fri Dec 30 21:49:38 2005 +0200
@@ -78,6 +78,7 @@
 	switch (i_stream_read(client->input)) {
 	case -1:
 		/* disconnected */
+		idle_finish(ctx, FALSE);
 		client_destroy(client);
 		return;
 	case -2:
@@ -134,17 +135,23 @@
 	idle_send_expunge(ctx);
 }
 
+static void idle_sync_now(struct mailbox *box, struct cmd_idle_context *ctx)
+{
+	i_assert(ctx->sync_ctx == NULL);
+
+	ctx->sync_pending = FALSE;
+	ctx->sync_ctx = imap_sync_init(ctx->client, box, 0, 0);
+	cmd_idle_continue(ctx->cmd);
+}
+
 static void idle_callback(struct mailbox *box, void *context)
 {
         struct cmd_idle_context *ctx = context;
 
 	if (ctx->sync_ctx != NULL)
 		ctx->sync_pending = TRUE;
-	else {
-		ctx->sync_pending = FALSE;
-		ctx->sync_ctx = imap_sync_init(ctx->client, box, 0, 0);
-		cmd_idle_continue(ctx->cmd);
-	}
+	else
+                idle_sync_now(box, ctx);
 }
 
 static int cmd_idle_continue(struct client_command_context *cmd)
@@ -177,7 +184,7 @@
 	} else if (ctx->sync_pending) {
 		/* more changes occurred while we were sending changes to
 		   client */
-                idle_callback(client->mailbox, client);
+                idle_sync_now(client->mailbox, ctx);
 	}
         client->output_pending = FALSE;
 
@@ -225,5 +232,9 @@
 	client->command_pending = TRUE;
 	cmd->func = cmd_idle_continue;
 	cmd->context = ctx;
+
+	/* check immediately if there are changes. if they came before we
+	   added mailbox-notifier, we wouldn't see them otherwise. */
+	idle_sync_now(client->mailbox, ctx);
 	return FALSE;
 }