dovecot-2.2: Mailbox list notify API changed to return multiple ...
dovecot at dovecot.org
dovecot at dovecot.org
Mon Sep 7 20:56:38 UTC 2015
details: http://hg.dovecot.org/dovecot-2.2/rev/fa979ccfa34c
changeset: 19117:fa979ccfa34c
user: Timo Sirainen <tss at iki.fi>
date: Mon Sep 07 23:55:31 2015 +0300
description:
Mailbox list notify API changed to return multiple events at once.
This fixes some issues where a single event could actually trigger multiple
different kinds of events.
diffstat:
src/imap/imap-notify.c | 156 ++++++++++------------
src/lib-storage/list/mailbox-list-index-notify.c | 35 ++--
src/lib-storage/mailbox-list-notify.h | 3 +-
3 files changed, 93 insertions(+), 101 deletions(-)
diffs (truncated from 303 to 300 lines):
diff -r 73acc7075146 -r fa979ccfa34c src/imap/imap-notify.c
--- a/src/imap/imap-notify.c Mon Sep 07 23:08:44 2015 +0300
+++ b/src/imap/imap-notify.c Mon Sep 07 23:55:31 2015 +0300
@@ -57,27 +57,17 @@
items.status |= STATUS_HIGHESTMODSEQ;
box = mailbox_alloc(notify_ns->ns->list, rec->vname, 0);
- switch (rec->event) {
- case MAILBOX_LIST_NOTIFY_UIDVALIDITY:
+ if ((rec->events & MAILBOX_LIST_NOTIFY_UIDVALIDITY) != 0) {
items.status |= STATUS_UIDVALIDITY | STATUS_UIDNEXT |
STATUS_MESSAGES | STATUS_UNSEEN;
- break;
- case MAILBOX_LIST_NOTIFY_APPENDS:
- case MAILBOX_LIST_NOTIFY_EXPUNGES:
+ }
+ if ((rec->events & (MAILBOX_LIST_NOTIFY_APPENDS |
+ MAILBOX_LIST_NOTIFY_EXPUNGES)) != 0)
items.status |= STATUS_UIDNEXT | STATUS_MESSAGES | STATUS_UNSEEN;
- break;
- case MAILBOX_LIST_NOTIFY_SEEN_CHANGES:
+ if ((rec->events & MAILBOX_LIST_NOTIFY_SEEN_CHANGES) != 0)
items.status |= STATUS_UNSEEN;
- break;
- case MAILBOX_LIST_NOTIFY_MODSEQ_CHANGES:
+ if ((rec->events & MAILBOX_LIST_NOTIFY_MODSEQ_CHANGES) != 0) {
/* if HIGHESTMODSEQ isn't being sent, don't send anything */
- break;
- case MAILBOX_LIST_NOTIFY_CREATE:
- case MAILBOX_LIST_NOTIFY_DELETE:
- case MAILBOX_LIST_NOTIFY_RENAME:
- case MAILBOX_LIST_NOTIFY_SUBSCRIBE:
- case MAILBOX_LIST_NOTIFY_UNSUBSCRIBE:
- i_unreached();
}
if (items.status == 0) {
/* don't send anything */
@@ -100,46 +90,50 @@
const struct mailbox_list_notify_rec *rec)
{
enum mailbox_info_flags mailbox_flags;
- int ret = 1;
+ int ret;
- switch (rec->event) {
- case MAILBOX_LIST_NOTIFY_CREATE:
+ if ((rec->events & MAILBOX_LIST_NOTIFY_CREATE) != 0) {
if (mailbox_list_mailbox(notify_ns->ns->list, rec->storage_name,
&mailbox_flags) < 0)
mailbox_flags = 0;
- ret = imap_notify_list(notify_ns, rec, mailbox_flags);
- break;
- case MAILBOX_LIST_NOTIFY_DELETE:
- ret = imap_notify_list(notify_ns, rec, MAILBOX_NONEXISTENT);
- break;
- case MAILBOX_LIST_NOTIFY_RENAME:
+ if ((ret = imap_notify_list(notify_ns, rec, mailbox_flags)) <= 0)
+ return ret;
+ }
+ if ((rec->events & MAILBOX_LIST_NOTIFY_DELETE) != 0) {
+ if ((ret = imap_notify_list(notify_ns, rec, MAILBOX_NONEXISTENT)) < 0)
+ return ret;
+ }
+ if ((rec->events & MAILBOX_LIST_NOTIFY_RENAME) != 0) {
if (mailbox_list_mailbox(notify_ns->ns->list, rec->storage_name,
&mailbox_flags) < 0)
mailbox_flags = 0;
- ret = imap_notify_list(notify_ns, rec, mailbox_flags);
- break;
- case MAILBOX_LIST_NOTIFY_SUBSCRIBE:
+ if ((ret = imap_notify_list(notify_ns, rec, mailbox_flags)) < 0)
+ return ret;
+ }
+ if ((rec->events & MAILBOX_LIST_NOTIFY_SUBSCRIBE) != 0) {
if (mailbox_list_mailbox(notify_ns->ns->list, rec->storage_name,
&mailbox_flags) < 0)
mailbox_flags = 0;
- ret = imap_notify_list(notify_ns, rec,
- mailbox_flags | MAILBOX_SUBSCRIBED);
- break;
- case MAILBOX_LIST_NOTIFY_UNSUBSCRIBE:
+ if ((ret = imap_notify_list(notify_ns, rec,
+ mailbox_flags | MAILBOX_SUBSCRIBED)) < 0)
+ return ret;
+ }
+ if ((rec->events & MAILBOX_LIST_NOTIFY_UNSUBSCRIBE) != 0) {
if (mailbox_list_mailbox(notify_ns->ns->list, rec->storage_name,
&mailbox_flags) < 0)
mailbox_flags = 0;
- ret = imap_notify_list(notify_ns, rec, mailbox_flags);
- break;
- case MAILBOX_LIST_NOTIFY_UIDVALIDITY:
- case MAILBOX_LIST_NOTIFY_APPENDS:
- case MAILBOX_LIST_NOTIFY_EXPUNGES:
- case MAILBOX_LIST_NOTIFY_SEEN_CHANGES:
- case MAILBOX_LIST_NOTIFY_MODSEQ_CHANGES:
- ret = imap_notify_status(notify_ns, rec);
- break;
+ if ((ret = imap_notify_list(notify_ns, rec, mailbox_flags)) < 0)
+ return ret;
}
- return ret;
+ if ((rec->events & (MAILBOX_LIST_NOTIFY_UIDVALIDITY |
+ MAILBOX_LIST_NOTIFY_APPENDS |
+ MAILBOX_LIST_NOTIFY_EXPUNGES |
+ MAILBOX_LIST_NOTIFY_SEEN_CHANGES |
+ MAILBOX_LIST_NOTIFY_MODSEQ_CHANGES)) != 0) {
+ if ((ret = imap_notify_status(notify_ns, rec)) < 0)
+ return ret;
+ }
+ return 1;
}
static bool
@@ -149,53 +143,45 @@
{
enum imap_notify_event wanted_events = notify_boxes->events;
struct mailbox *box;
- bool mailbox_event = FALSE;
- switch (rec->event) {
- case MAILBOX_LIST_NOTIFY_CREATE:
- case MAILBOX_LIST_NOTIFY_DELETE:
- case MAILBOX_LIST_NOTIFY_RENAME:
- if ((wanted_events & IMAP_NOTIFY_EVENT_MAILBOX_NAME) == 0)
- return FALSE;
- break;
- case MAILBOX_LIST_NOTIFY_SUBSCRIBE:
- case MAILBOX_LIST_NOTIFY_UNSUBSCRIBE:
- if ((wanted_events & IMAP_NOTIFY_EVENT_SUBSCRIPTION_CHANGE) == 0)
- return FALSE;
- break;
- case MAILBOX_LIST_NOTIFY_UIDVALIDITY:
- if ((wanted_events & (IMAP_NOTIFY_EVENT_MESSAGE_NEW |
- IMAP_NOTIFY_EVENT_MESSAGE_EXPUNGE |
- IMAP_NOTIFY_EVENT_FLAG_CHANGE)) == 0)
- return FALSE;
- mailbox_event = TRUE;
- break;
- case MAILBOX_LIST_NOTIFY_APPENDS:
- if ((wanted_events & IMAP_NOTIFY_EVENT_MESSAGE_NEW) == 0)
- return FALSE;
- mailbox_event = TRUE;
- break;
- case MAILBOX_LIST_NOTIFY_EXPUNGES:
- if ((wanted_events & IMAP_NOTIFY_EVENT_MESSAGE_EXPUNGE) == 0)
- return FALSE;
- mailbox_event = TRUE;
- break;
- case MAILBOX_LIST_NOTIFY_SEEN_CHANGES:
- case MAILBOX_LIST_NOTIFY_MODSEQ_CHANGES:
- if ((wanted_events & IMAP_NOTIFY_EVENT_FLAG_CHANGE) == 0)
- return FALSE;
- mailbox_event = TRUE;
- break;
+ /* check for mailbox list events first */
+ if ((wanted_events & IMAP_NOTIFY_EVENT_MAILBOX_NAME) != 0) {
+ if ((rec->events & (MAILBOX_LIST_NOTIFY_CREATE |
+ MAILBOX_LIST_NOTIFY_DELETE |
+ MAILBOX_LIST_NOTIFY_RENAME)) != 0)
+ return TRUE;
+ }
+ if ((wanted_events & IMAP_NOTIFY_EVENT_SUBSCRIPTION_CHANGE) != 0) {
+ if ((rec->events & (MAILBOX_LIST_NOTIFY_SUBSCRIBE |
+ MAILBOX_LIST_NOTIFY_UNSUBSCRIBE)) != 0)
+ return TRUE;
}
- if (mailbox_event) {
- /* if this is an even for selected mailbox, ignore it */
- box = notify_ns->ctx->client->mailbox;
- if (box != NULL &&
- mailbox_equals(box, notify_ns->ns, rec->vname))
- return FALSE;
+ /* if this is an event for the selected mailbox, ignore it */
+ box = notify_ns->ctx->client->mailbox;
+ if (box != NULL && mailbox_equals(box, notify_ns->ns, rec->vname))
+ return FALSE;
+
+ if ((wanted_events & (IMAP_NOTIFY_EVENT_MESSAGE_NEW |
+ IMAP_NOTIFY_EVENT_MESSAGE_EXPUNGE |
+ IMAP_NOTIFY_EVENT_FLAG_CHANGE)) != 0) {
+ if ((rec->events & MAILBOX_LIST_NOTIFY_UIDVALIDITY) != 0)
+ return TRUE;
}
- return TRUE;
+ if ((wanted_events & IMAP_NOTIFY_EVENT_MESSAGE_NEW) != 0) {
+ if ((rec->events & MAILBOX_LIST_NOTIFY_APPENDS) != 0)
+ return TRUE;
+ }
+ if ((wanted_events & IMAP_NOTIFY_EVENT_MESSAGE_EXPUNGE) != 0) {
+ if ((rec->events & MAILBOX_LIST_NOTIFY_EXPUNGES) != 0)
+ return TRUE;
+ }
+ if ((wanted_events & IMAP_NOTIFY_EVENT_FLAG_CHANGE) != 0) {
+ if ((rec->events & (MAILBOX_LIST_NOTIFY_SEEN_CHANGES |
+ MAILBOX_LIST_NOTIFY_MODSEQ_CHANGES)) != 0)
+ return TRUE;
+ }
+ return FALSE;
}
bool imap_notify_match_mailbox(struct imap_notify_namespace *notify_ns,
diff -r 73acc7075146 -r fa979ccfa34c src/lib-storage/list/mailbox-list-index-notify.c
--- a/src/lib-storage/list/mailbox-list-index-notify.c Mon Sep 07 23:08:44 2015 +0300
+++ b/src/lib-storage/list/mailbox-list-index-notify.c Mon Sep 07 23:55:31 2015 +0300
@@ -591,7 +591,7 @@
return FALSE;
rec->old_vname = old_vname;
- rec->event = MAILBOX_LIST_NOTIFY_RENAME;
+ rec->events = MAILBOX_LIST_NOTIFY_RENAME;
return TRUE;
}
@@ -607,7 +607,7 @@
rec->vname = *vnamep;
rec->storage_name = mailbox_list_get_storage_name(inotify->notify.list,
rec->vname);
- rec->event = MAILBOX_LIST_NOTIFY_SUBSCRIBE;
+ rec->events = MAILBOX_LIST_NOTIFY_SUBSCRIBE;
return TRUE;
}
@@ -623,7 +623,7 @@
rec->vname = *vnamep;
rec->storage_name = mailbox_list_get_storage_name(inotify->notify.list,
rec->vname);
- rec->event = MAILBOX_LIST_NOTIFY_UNSUBSCRIBE;
+ rec->events = MAILBOX_LIST_NOTIFY_UNSUBSCRIBE;
return TRUE;
}
@@ -637,7 +637,7 @@
if (!mailbox_list_index_notify_lookup(inotify, inotify->old_view,
uid, 0, &status, &rec))
return FALSE;
- rec->event = MAILBOX_LIST_NOTIFY_DELETE;
+ rec->events = MAILBOX_LIST_NOTIFY_DELETE;
return TRUE;
}
@@ -651,7 +651,7 @@
if (!mailbox_list_index_notify_lookup(inotify, inotify->view,
uid, 0, &status, &rec))
i_unreached();
- rec->event = MAILBOX_LIST_NOTIFY_CREATE;
+ rec->events = MAILBOX_LIST_NOTIFY_CREATE;
return TRUE;
}
@@ -674,15 +674,20 @@
nnode = mailbox_list_notify_tree_lookup(inotify->tree,
rec->storage_name);
if (nnode == NULL || nnode->uidvalidity != status.uidvalidity)
- rec->event = MAILBOX_LIST_NOTIFY_UIDVALIDITY;
- else if (nnode->uidnext != status.uidnext)
- rec->event = MAILBOX_LIST_NOTIFY_APPENDS;
- else if (nnode->messages > status.messages)
- rec->event = MAILBOX_LIST_NOTIFY_EXPUNGES;
- else if (nnode->unseen != status.unseen)
- rec->event = MAILBOX_LIST_NOTIFY_SEEN_CHANGES;
- else if (nnode->highest_modseq < status.highest_modseq)
- rec->event = MAILBOX_LIST_NOTIFY_MODSEQ_CHANGES;
+ rec->events |= MAILBOX_LIST_NOTIFY_UIDVALIDITY;
+ if (nnode->uidnext != status.uidnext)
+ rec->events |= MAILBOX_LIST_NOTIFY_APPENDS;
+ if (nnode->messages > status.messages) {
+ /* NOTE: not entirely reliable, since there could be both
+ expunges and appends.. but it shouldn't make any difference
+ in practise, since anybody interested in expunges is most
+ likely also interested in appends. */
+ rec->events |= MAILBOX_LIST_NOTIFY_EXPUNGES;
+ }
+ if (nnode->unseen != status.unseen)
+ rec->events |= MAILBOX_LIST_NOTIFY_SEEN_CHANGES;
+ if (nnode->highest_modseq < status.highest_modseq)
+ rec->events |= MAILBOX_LIST_NOTIFY_MODSEQ_CHANGES;
else {
/* nothing changed */
return FALSE;
@@ -748,7 +753,7 @@
if (!inotify->initialized)
mailbox_list_index_notify_read_init(inotify);
while (mailbox_list_index_notify_try_next(inotify)) {
- if ((inotify->notify_rec.event & inotify->notify.mask) != 0) {
+ if ((inotify->notify_rec.events & inotify->notify.mask) != 0) {
*rec_r = &inotify->notify_rec;
return 1;
} else {
diff -r 73acc7075146 -r fa979ccfa34c src/lib-storage/mailbox-list-notify.h
--- a/src/lib-storage/mailbox-list-notify.h Mon Sep 07 23:08:44 2015 +0300
+++ b/src/lib-storage/mailbox-list-notify.h Mon Sep 07 23:55:31 2015 +0300
@@ -30,7 +30,8 @@
};
struct mailbox_list_notify_rec {
- enum mailbox_list_notify_event event;
+ /* Each record can contain multiple events */
+ enum mailbox_list_notify_event events;
More information about the dovecot-cvs
mailing list