Mercurial > dovecot > core-2.2
changeset 1730:8480f945e270 HEAD
IDLE uses now IO_*_NOTIFY to get instant notifying of mails.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 24 Aug 2003 15:45:32 +0300 |
parents | 5bf22d6bb65e |
children | 687a06278ef5 |
files | src/imap/cmd-idle.c src/imap/cmd-select.c src/imap/commands-util.c src/lib-storage/index/index-mailbox-check.c src/lib-storage/index/index-storage.h src/lib-storage/index/index-sync.c src/lib-storage/index/maildir/maildir-storage.c src/lib-storage/index/mbox/mbox-storage.c src/lib-storage/mail-storage.h src/lib-storage/proxy-mailbox.c |
diffstat | 10 files changed, 117 insertions(+), 53 deletions(-) [+] |
line wrap: on
line diff
--- a/src/imap/cmd-idle.c Sun Aug 24 15:43:53 2003 +0300 +++ b/src/imap/cmd-idle.c Sun Aug 24 15:45:32 2003 +0300 @@ -10,6 +10,7 @@ #define DEFAULT_IDLE_CHECK_INTERVAL 30 +#include "imap-fetch.h" static void idle_finish(struct client *client, int done_ok) { if (client->idle_to != NULL) { @@ -31,7 +32,7 @@ if (client->mailbox != NULL) { client->mailbox->auto_sync(client->mailbox, mailbox_check_interval != 0 ? - MAILBOX_SYNC_NO_EXPUNGES : + MAILBOX_SYNC_FLAG_NO_EXPUNGES : MAILBOX_SYNC_NONE, mailbox_check_interval); } @@ -118,7 +119,7 @@ if (client->mailbox != NULL) { client->mailbox->auto_sync(client->mailbox, - MAILBOX_SYNC_ALL, interval); + MAILBOX_SYNC_FULL, interval); } client_send_line(client, "+ idling");
--- a/src/imap/cmd-select.c Sun Aug 24 15:43:53 2003 +0300 +++ b/src/imap/cmd-select.c Sun Aug 24 15:45:32 2003 +0300 @@ -85,7 +85,7 @@ "OK [READ-WRITE] Select completed."); if (mailbox_check_interval != 0) { - box->auto_sync(box, MAILBOX_SYNC_NO_EXPUNGES, + box->auto_sync(box, MAILBOX_SYNC_FLAG_NO_EXPUNGES, mailbox_check_interval); }
--- a/src/imap/commands-util.c Sun Aug 24 15:43:53 2003 +0300 +++ b/src/imap/commands-util.c Sun Aug 24 15:45:32 2003 +0300 @@ -126,7 +126,7 @@ if (client->mailbox == NULL) return; - if (!client->mailbox->sync(client->mailbox, MAIL_SYNC_FLAG_FAST)) { + if (!client->mailbox->sync(client->mailbox, MAILBOX_SYNC_FAST)) { client_send_untagged_storage_error(client, client->mailbox->storage); } @@ -137,8 +137,8 @@ if (client->mailbox == NULL) return; - if (!client->mailbox->sync(client->mailbox, MAIL_SYNC_FLAG_NO_EXPUNGES | - MAIL_SYNC_FLAG_FAST)) { + if (!client->mailbox->sync(client->mailbox, MAILBOX_SYNC_FAST | + MAILBOX_SYNC_FLAG_NO_EXPUNGES)) { client_send_untagged_storage_error(client, client->mailbox->storage); }
--- a/src/lib-storage/index/index-mailbox-check.c Sun Aug 24 15:43:53 2003 +0300 +++ b/src/lib-storage/index/index-mailbox-check.c Sun Aug 24 15:45:32 2003 +0300 @@ -12,7 +12,7 @@ struct index_mailbox *ibox = context; struct index_autosync_file *file; struct stat st; - int synced, sync_expunges; + int sync; /* check changes only when we can also notify of new mail */ if ((unsigned int) (ioloop_time - ibox->sync_last_check) < @@ -21,29 +21,61 @@ ibox->sync_last_check = ioloop_time; - synced = FALSE; - sync_expunges = ibox->autosync_type != MAILBOX_SYNC_NO_EXPUNGES; - + sync = ibox->autosync_pending; for (file = ibox->autosync_files; file != NULL; file = file->next) { if (stat(file->path, &st) == 0 && - file->last_stamp != st.st_mtime) { + file->last_stamp != st.st_mtime) file->last_stamp = st.st_mtime; - if (!synced) { - ibox->box.sync(&ibox->box, sync_expunges); - synced = TRUE; - } - } + } + + if (sync) { + ibox->box.sync(&ibox->box, ibox->autosync_flags); + ibox->autosync_pending = FALSE; + } +} + +static void notify_callback(void *context) +{ + struct index_mailbox *ibox = context; + + if ((unsigned int) (ioloop_time - ibox->sync_last_check) >= + ibox->min_newmail_notify_interval) { + ibox->sync_last_check = ioloop_time; + ibox->box.sync(&ibox->box, ibox->autosync_flags); + ibox->autosync_pending = FALSE; + } else { + ibox->autosync_pending = TRUE; } } -void index_mailbox_check_add(struct index_mailbox *ibox, const char *path) +void index_mailbox_check_add(struct index_mailbox *ibox, + const char *path, int dir) { struct index_autosync_file *file; struct stat st; + struct io *io; + struct index_autosync_io *aio; + int fd; + + fd = open(path, O_RDONLY); + if (fd >= 0) { + io = io_add(fd, dir ? IO_DIR_NOTIFY : IO_FILE_NOTIFY, + notify_callback, ibox); + if (io != NULL) { + aio = i_new(struct index_autosync_io, 1); + aio->io = io; + aio->fd = fd; + aio->next = ibox->autosync_ios; + ibox->autosync_ios = aio; + } + } file = i_new(struct index_autosync_file, 1); file->path = i_strdup(path); - file->last_stamp = stat(path, &st) < 0 ? 0 : st.st_mtime; + if (fd < 0) + file->last_stamp = stat(path, &st) < 0 ? 0 : st.st_mtime; + else + file->last_stamp = fstat(fd, &st) < 0 ? 0 : st.st_mtime; file->next = ibox->autosync_files; ibox->autosync_files = file; @@ -55,6 +87,7 @@ void index_mailbox_check_remove_all(struct index_mailbox *ibox) { struct index_autosync_file *file; + struct index_autosync_io *aio; while (ibox->autosync_files != NULL) { file = ibox->autosync_files; @@ -64,6 +97,16 @@ i_free(file); } + while (ibox->autosync_ios != NULL) { + aio = ibox->autosync_ios; + ibox->autosync_ios = aio->next; + + io_remove(aio->io); + if (close(aio->fd) < 0) + i_error("close(autosync_io) failed: %m"); + i_free(aio); + } + if (ibox->autosync_to != NULL) { timeout_remove(ibox->autosync_to); ibox->autosync_to = NULL;
--- a/src/lib-storage/index/index-storage.h Sun Aug 24 15:43:53 2003 +0300 +++ b/src/lib-storage/index/index-storage.h Sun Aug 24 15:45:32 2003 +0300 @@ -12,6 +12,12 @@ time_t last_stamp; }; +struct index_autosync_io { + struct index_autosync_io *next; + struct io *io; + int fd; +}; + struct index_mailbox { struct mailbox box; @@ -24,8 +30,9 @@ struct mail_cache_transaction_ctx *trans_ctx; struct timeout *autosync_to; - struct index_autosync_file *autosync_files; - enum mailbox_sync_type autosync_type; + struct index_autosync_file *autosync_files; + struct index_autosync_io *autosync_ios; + enum mailbox_sync_flags autosync_flags; time_t sync_last_check; unsigned int min_newmail_notify_interval; @@ -39,6 +46,7 @@ unsigned int inconsistent:1; unsigned int sent_diskspace_warning:1; unsigned int sent_readonly_flags_warning:1; + unsigned int autosync_pending:1; }; int mail_storage_set_index_error(struct index_mailbox *ibox); @@ -76,7 +84,8 @@ unsigned int index_storage_get_recent_count(struct mail_index *index); -void index_mailbox_check_add(struct index_mailbox *ibox, const char *path); +void index_mailbox_check_add(struct index_mailbox *ibox, + const char *path, int dir); void index_mailbox_check_remove_all(struct index_mailbox *ibox); /* mailbox methods: */ @@ -86,7 +95,7 @@ int index_storage_get_status(struct mailbox *box, enum mailbox_status_items items, struct mailbox_status *status); -int index_storage_sync(struct mailbox *box, enum mail_sync_flags flags); +int index_storage_sync(struct mailbox *box, enum mailbox_sync_flags flags); struct mail_fetch_context * index_storage_fetch_init(struct mailbox *box,
--- a/src/lib-storage/index/index-sync.c Sun Aug 24 15:43:53 2003 +0300 +++ b/src/lib-storage/index/index-sync.c Sun Aug 24 15:45:32 2003 +0300 @@ -213,12 +213,12 @@ return TRUE; } -int index_storage_sync(struct mailbox *box, enum mail_sync_flags flags) +int index_storage_sync(struct mailbox *box, enum mailbox_sync_flags flags) { struct index_mailbox *ibox = (struct index_mailbox *) box; int ret; - if ((flags & MAIL_SYNC_FLAG_FAST) == 0 || + if ((flags & MAILBOX_SYNC_FAST) == 0 || ibox->sync_last_check + MAILBOX_FULL_SYNC_INTERVAL <= ioloop_time) { ibox->sync_last_check = ioloop_time; @@ -235,7 +235,7 @@ /* FIXME: we could sync flags always, but expunges in the middle could make it a bit more difficult and slower */ - if ((flags & MAIL_SYNC_FLAG_NO_EXPUNGES) == 0 || + if ((flags & MAILBOX_SYNC_FLAG_NO_EXPUNGES) == 0 || mail_modifylog_get_expunge_count(ibox->index->modifylog) == 0) ret = index_storage_sync_modifylog(ibox, FALSE); else
--- a/src/lib-storage/index/maildir/maildir-storage.c Sun Aug 24 15:43:53 2003 +0300 +++ b/src/lib-storage/index/maildir/maildir-storage.c Sun Aug 24 15:45:32 2003 +0300 @@ -753,21 +753,29 @@ } static void maildir_storage_auto_sync(struct mailbox *box, - enum mailbox_sync_type sync_type, + enum mailbox_sync_flags flags, unsigned int min_newmail_notify_interval) { struct index_mailbox *ibox = (struct index_mailbox *) box; - ibox->autosync_type = sync_type; ibox->min_newmail_notify_interval = min_newmail_notify_interval; - index_mailbox_check_remove_all(ibox); - if (sync_type != MAILBOX_SYNC_NONE) { - index_mailbox_check_add(ibox, - t_strconcat(ibox->index->mailbox_path, "/new", NULL)); - index_mailbox_check_add(ibox, - t_strconcat(ibox->index->mailbox_path, "/cur", NULL)); + if ((ibox->autosync_flags == 0 && flags == 0) || + (ibox->autosync_flags != 0 && flags != 0)) { + /* flags or interval just changed. or nothing. */ + ibox->autosync_flags = flags; } + ibox->autosync_flags = flags; + + if (flags == 0) { + index_mailbox_check_remove_all(ibox); + return; + } + + index_mailbox_check_add(ibox, + t_strconcat(ibox->index->mailbox_path, "/new", NULL), TRUE); + index_mailbox_check_add(ibox, + t_strconcat(ibox->index->mailbox_path, "/cur", NULL), TRUE); } static int maildir_storage_lock(struct mailbox *box,
--- a/src/lib-storage/index/mbox/mbox-storage.c Sun Aug 24 15:43:53 2003 +0300 +++ b/src/lib-storage/index/mbox/mbox-storage.c Sun Aug 24 15:45:32 2003 +0300 @@ -757,17 +757,24 @@ } static void mbox_storage_auto_sync(struct mailbox *box, - enum mailbox_sync_type sync_type, + enum mailbox_sync_flags flags, unsigned int min_newmail_notify_interval) { struct index_mailbox *ibox = (struct index_mailbox *) box; - ibox->autosync_type = sync_type; ibox->min_newmail_notify_interval = min_newmail_notify_interval; - index_mailbox_check_remove_all(ibox); - if (sync_type != MAILBOX_SYNC_NONE) - index_mailbox_check_add(ibox, ibox->index->mailbox_path); + if ((ibox->autosync_flags == 0 && flags == 0) || + (ibox->autosync_flags != 0 && flags != 0)) { + /* flags or interval just changed. or nothing. */ + ibox->autosync_flags = flags; + } + ibox->autosync_flags = flags; + + if (flags == 0) + index_mailbox_check_remove_all(ibox); + else + index_mailbox_check_add(ibox, ibox->index->mailbox_path, FALSE); } static int mbox_storage_lock(struct mailbox *box,
--- a/src/lib-storage/mail-storage.h Sun Aug 24 15:43:53 2003 +0300 +++ b/src/lib-storage/mail-storage.h Sun Aug 24 15:45:32 2003 +0300 @@ -47,12 +47,6 @@ MAILBOX_NAME_NOINFERIORS }; -enum mailbox_sync_type { - MAILBOX_SYNC_NONE, - MAILBOX_SYNC_ALL, - MAILBOX_SYNC_NO_EXPUNGES -}; - enum mailbox_lock_type { MAILBOX_LOCK_UNLOCK = 0x00, MAILBOX_LOCK_READ = 0x01, @@ -101,9 +95,11 @@ MAIL_FETCH_IMAP_ENVELOPE = 0x4000 }; -enum mail_sync_flags { - MAIL_SYNC_FLAG_NO_EXPUNGES = 0x01, - MAIL_SYNC_FLAG_FAST = 0x02 +enum mailbox_sync_flags { + MAILBOX_SYNC_NONE = 0x00, + MAILBOX_SYNC_FULL = 0x01, + MAILBOX_SYNC_FAST = 0x02, + MAILBOX_SYNC_FLAG_NO_EXPUNGES = 0x04 }; enum client_workarounds { @@ -249,11 +245,11 @@ struct mailbox_status *status); /* Synchronize the mailbox. */ - int (*sync)(struct mailbox *box, enum mail_sync_flags flags); + int (*sync)(struct mailbox *box, enum mailbox_sync_flags flags); /* Synchronize mailbox in background. It's done until this function is - called with sync_type = MAILBOX_SYNC_NONE */ - void (*auto_sync)(struct mailbox *box, enum mailbox_sync_type sync_type, + called with flags = MAILBOX_SYNC_NONE. */ + void (*auto_sync)(struct mailbox *box, enum mailbox_sync_flags flags, unsigned int min_newmail_notify_interval); /* Initialize new fetch request. wanted_fields isn't required, but it
--- a/src/lib-storage/proxy-mailbox.c Sun Aug 24 15:43:53 2003 +0300 +++ b/src/lib-storage/proxy-mailbox.c Sun Aug 24 15:45:32 2003 +0300 @@ -39,19 +39,19 @@ return p->box->get_status(p->box, items, status); } -static int _sync(struct mailbox *box, enum mail_sync_flags flags) +static int _sync(struct mailbox *box, enum mailbox_sync_flags flags) { struct proxy_mailbox *p = (struct proxy_mailbox *) box; return p->box->sync(p->box, flags); } -static void _auto_sync(struct mailbox *box, enum mailbox_sync_type sync_type, +static void _auto_sync(struct mailbox *box, enum mailbox_sync_flags flags, unsigned int min_newmail_notify_interval) { struct proxy_mailbox *p = (struct proxy_mailbox *) box; - p->box->auto_sync(p->box, sync_type, min_newmail_notify_interval); + p->box->auto_sync(p->box, flags, min_newmail_notify_interval); } static struct mail_fetch_context *