# HG changeset patch # User Timo Sirainen # Date 1296603788 -7200 # Node ID 4fdf3084f74f4f5f209f1569c7b387f81d758386 # Parent 431430c43aec1ba8b1f8af13fd0d4f0acc381f83 imapc: Support IDLE even if remote IMAP server doesn't support it. diff -r 431430c43aec -r 4fdf3084f74f src/lib-storage/index/imapc/imapc-mailbox.c --- 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); } diff -r 431430c43aec -r 4fdf3084f74f src/lib-storage/index/imapc/imapc-storage.c --- 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 = { diff -r 431430c43aec -r 4fdf3084f74f src/lib-storage/index/imapc/imapc-storage.h --- 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;