changeset 12635:4fdf3084f74f

imapc: Support IDLE even if remote IMAP server doesn't support it.
author Timo Sirainen <tss@iki.fi>
date Wed, 02 Feb 2011 01:43:08 +0200
parents 431430c43aec
children fa4b84059ae2
files src/lib-storage/index/imapc/imapc-mailbox.c src/lib-storage/index/imapc/imapc-storage.c src/lib-storage/index/imapc/imapc-storage.h
diffstat 3 files changed, 46 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/imapc/imapc-mailbox.c	Wed Feb 02 01:27:50 2011 +0200
+++ b/src/lib-storage/index/imapc/imapc-mailbox.c	Wed Feb 02 01:43:08 2011 +0200
@@ -67,15 +67,16 @@
 
 static void imapc_mailbox_idle_timeout(struct imapc_mailbox *mbox)
 {
-	timeout_remove(&mbox->to_idle);
+	timeout_remove(&mbox->to_idle_delay);
 	if (mbox->box.notify_callback != NULL)
 		mbox->box.notify_callback(&mbox->box, mbox->box.notify_context);
 }
 
 static void imapc_mailbox_idle_notify(struct imapc_mailbox *mbox)
 {
-	if (mbox->box.notify_callback != NULL && mbox->to_idle == NULL) {
-		mbox->to_idle =
+	if (mbox->box.notify_callback != NULL &&
+	    mbox->to_idle_delay == NULL) {
+		mbox->to_idle_delay =
 			timeout_add(NOTIFY_DELAY_MSECS,
 				    imapc_mailbox_idle_timeout, mbox);
 	}
--- a/src/lib-storage/index/imapc/imapc-storage.c	Wed Feb 02 01:27:50 2011 +0200
+++ b/src/lib-storage/index/imapc/imapc-storage.c	Wed Feb 02 01:43:08 2011 +0200
@@ -112,8 +112,9 @@
 	imapc_client_stop(ctx->storage->client);
 }
 
-void imapc_async_stop_callback(const struct imapc_command_reply *reply,
-			       void *context)
+static void imapc_async_callback(const struct imapc_command_reply *reply,
+				 void *context)
+
 {
 	struct imapc_storage *storage = context;
 
@@ -125,6 +126,14 @@
 		mail_storage_set_critical(&storage->storage,
 			"imapc: Command failed: %s", reply->text_full);
 	}
+}
+
+void imapc_async_stop_callback(const struct imapc_command_reply *reply,
+			       void *context)
+{
+	struct imapc_storage *storage = context;
+
+	imapc_async_callback(reply, context);
 	imapc_client_stop(storage->client);
 }
 
@@ -330,8 +339,10 @@
 		if (mail_index_transaction_commit(&mbox->delayed_sync_trans) < 0)
 			mail_storage_set_index_error(&mbox->box);
 	}
-	if (mbox->to_idle != NULL)
-		timeout_remove(&mbox->to_idle);
+	if (mbox->to_idle_delay != NULL)
+		timeout_remove(&mbox->to_idle_delay);
+	if (mbox->to_idle_check != NULL)
+		timeout_remove(&mbox->to_idle_check);
 	return index_storage_mailbox_close(box);
 }
 
@@ -476,9 +487,33 @@
 	return index_mailbox_get_metadata(box, items, metadata_r);
 }
 
-static void imapc_notify_changes(struct mailbox *box ATTR_UNUSED)
+static void imapc_idle_timeout(struct imapc_mailbox *mbox)
+{
+	imapc_client_mailbox_cmd(mbox->client_box, "NOOP",
+				 imapc_async_callback, mbox->storage);
+}
+
+static void imapc_notify_changes(struct mailbox *box)
 {
-	/* we're doing IDLE all the time anyway - nothing to do here */
+	struct imapc_mailbox *mbox = (struct imapc_mailbox *)box;
+	enum imapc_capability capa;
+
+	if (box->notify_min_interval == 0) {
+		if (mbox->to_idle_check != NULL)
+			timeout_remove(&mbox->to_idle_check);
+		return;
+	}
+
+	capa = imapc_client_get_capabilities(mbox->storage->client);
+	if ((capa & IMAPC_CAPABILITY_IDLE) != 0) {
+		/* we're doing IDLE all the time anyway - nothing to do here */
+	} else {
+		/* remote server doesn't support IDLE.
+		   check for changes with NOOP every once in a while. */
+		mbox->to_idle_check =
+			timeout_add(box->notify_min_interval * 1000,
+				    imapc_idle_timeout, mbox);
+	}
 }
 
 struct mail_storage imapc_storage = {
--- a/src/lib-storage/index/imapc/imapc-storage.h	Wed Feb 02 01:27:50 2011 +0200
+++ b/src/lib-storage/index/imapc/imapc-storage.h	Wed Feb 02 01:43:08 2011 +0200
@@ -46,7 +46,7 @@
 
 	struct mail_index_transaction *delayed_sync_trans;
 	struct mail_index_view *delayed_sync_view;
-	struct timeout *to_idle;
+	struct timeout *to_idle_check, *to_idle_delay;
 
 	struct mail *cur_fetch_mail;