#endif
#include "mutt_curses.h"
#include "buffy.h"
+#ifdef USE_INOTIFY
+#include "monitor.h"
+#endif
#include <sys/stat.h>
#include <sys/types.h>
if (!changed)
return 0; /* nothing to do */
- /* update the modification times on the mailbox */
- mutt_get_stat_timespec (&data->mtime_cur, &st_cur, MUTT_STAT_MTIME);
- mutt_get_stat_timespec (&ctx->mtime, &st_new, MUTT_STAT_MTIME);
+ /* Update the modification times on the mailbox.
+ *
+ * The monitor code notices changes in the open mailbox too quickly.
+ * In practice, this sometimes leads to all the new messages not being
+ * noticed during the SAME group of mtime stat updates. To work around
+ * the problem, don't update the stat times for a monitor caused check. */
+#ifdef USE_INOTIFY
+ if (MonitorContextChanged)
+ MonitorContextChanged = 0;
+ else
+#endif
+ {
+ mutt_get_stat_timespec (&data->mtime_cur, &st_cur, MUTT_STAT_MTIME);
+ mutt_get_stat_timespec (&ctx->mtime, &st_new, MUTT_STAT_MTIME);
+ }
/* do a fast scan of just the filenames in
* the subdirectories that have changed.
if (!modified)
return 0;
- mutt_get_stat_timespec (&data->mtime_cur, &st_cur, MUTT_STAT_MTIME);
- mutt_get_stat_timespec (&ctx->mtime, &st, MUTT_STAT_MTIME);
+ /* Update the modification times on the mailbox.
+ *
+ * The monitor code notices changes in the open mailbox too quickly.
+ * In practice, this sometimes leads to all the new messages not being
+ * noticed during the SAME group of mtime stat updates. To work around
+ * the problem, don't update the stat times for a monitor caused check. */
+#ifdef USE_INOTIFY
+ if (MonitorContextChanged)
+ MonitorContextChanged = 0;
+ else
+#endif
+ {
+ mutt_get_stat_timespec (&data->mtime_cur, &st_cur, MUTT_STAT_MTIME);
+ mutt_get_stat_timespec (&ctx->mtime, &st, MUTT_STAT_MTIME);
+ }
memset (&mhs, 0, sizeof (mhs));
static size_t PollFdsLen = 0;
static struct pollfd *PollFds;
+static int MonitorContextDescriptor = -1;
+
typedef struct monitorinfo_t
{
short magic;
dprint (3, (debugfile, "monitor: cleanup watch (implicitly removed) - descriptor=%d\n", descr));
}
+ if (MonitorContextDescriptor == descr)
+ MonitorContextDescriptor = new_descr;
+
if (new_descr == -1)
{
monitor_delete (iter);
event->wd, event->mask));
if (event->mask & IN_IGNORED)
monitor_handle_ignore (event->wd);
+ else if (event->wd == MonitorContextDescriptor)
+ MonitorContextChanged = 1;
ptr += sizeof(struct inotify_event) + event->len;
}
}
descr = monitor_resolve (&info, buffy);
if (descr != RESOLVERES_OK_NOTEXISTING)
+ {
+ if (!buffy && (descr == RESOLVERES_OK_EXISTING))
+ MonitorContextDescriptor = info.monitor->descr;
return descr == RESOLVERES_OK_EXISTING ? 0 : -1;
+ }
mask = info.isdir ? INOTIFY_MASK_DIR : INOTIFY_MASK_FILE;
if ((INotifyFd == -1 && monitor_init () == -1)
}
dprint (3, (debugfile, "monitor: inotify_add_watch descriptor=%d for '%s'\n", descr, info.path));
+ if (!buffy)
+ MonitorContextDescriptor = descr;
+
monitor_create (&info, descr);
return 0;
}
inotify_rm_watch(info.monitor->descr, INotifyFd);
dprint (3, (debugfile, "monitor: inotify_rm_watch for '%s' descriptor=%d\n", info.path, info.monitor->descr));
+ if (!buffy && (MonitorContextDescriptor == info.monitor->descr))
+ MonitorContextDescriptor = -1;
+
monitor_delete (info.monitor);
monitor_check_free ();
return 0;