#define MAIL_CACHE_GROW_PERCENTAGE 10
#define MAIL_CACHE_LOCK_TIMEOUT 120
-#define MAIL_CACHE_LOCK_STALE_TIMEOUT 60
+#define MAIL_CACHE_LOCK_CHANGE_TIMEOUT 60
+#define MAIL_CACHE_LOCK_IMMEDIATE_TIMEOUT (5*60)
#define CACHE_RECORD(cache, offset) \
((struct mail_cache_record *) ((char *) (cache)->mmap_base + offset))
/* maybe a rebuild.. */
fd = file_dotlock_open(cache->filepath, NULL, MAIL_CACHE_LOCK_TIMEOUT,
- MAIL_CACHE_LOCK_STALE_TIMEOUT, NULL, NULL);
+ MAIL_CACHE_LOCK_CHANGE_TIMEOUT,
+ MAIL_CACHE_LOCK_IMMEDIATE_TIMEOUT, NULL, NULL);
if (fd == -1) {
mail_cache_set_syscall_error(cache, "file_dotlock_open()");
return FALSE;
#endif
fd = file_dotlock_open(cache->filepath, NULL, MAIL_CACHE_LOCK_TIMEOUT,
- MAIL_CACHE_LOCK_STALE_TIMEOUT, NULL, NULL);
+ MAIL_CACHE_LOCK_CHANGE_TIMEOUT,
+ MAIL_CACHE_LOCK_IMMEDIATE_TIMEOUT, NULL, NULL);
if (fd == -1) {
mail_cache_set_syscall_error(cache, "file_dotlock_open()");
return FALSE;
return ret > 0;
fd = file_dotlock_open(cache->filepath, NULL, MAIL_CACHE_LOCK_TIMEOUT,
- MAIL_CACHE_LOCK_STALE_TIMEOUT, NULL, NULL);
+ MAIL_CACHE_LOCK_CHANGE_TIMEOUT,
+ MAIL_CACHE_LOCK_IMMEDIATE_TIMEOUT, NULL, NULL);
if (fd == -1) {
mail_cache_set_syscall_error(cache, "file_dotlock_open()");
return FALSE;
return 1;
path = t_strconcat(index->control_dir, "/" MAILDIR_UIDLIST_NAME, NULL);
- fd = file_dotlock_open(path, NULL, 0, UIDLIST_LOCK_STALE_TIMEOUT,
+ fd = file_dotlock_open(path, NULL, 0, 0, UIDLIST_LOCK_STALE_TIMEOUT,
NULL, NULL);
if (fd == -1) {
if (errno == EAGAIN)
ret = file_lock_dotlock(index->mailbox_path, NULL,
lock_type == MAIL_LOCK_SHARED &&
!use_read_dotlock, lock_timeout,
- dotlock_change_timeout,
+ dotlock_change_timeout, 0,
dotlock_callback, &ctx,
&index->mbox_dotlock);
#define MAX_MAILBOX_LENGTH PATH_MAX
#define SUBSCRIPTION_FILE_LOCK_TIMEOUT 120
-#define SUBSCRIPTION_FILE_STALE_TIMEOUT 30
+#define SUBSCRIPTION_FILE_CHANGE_TIMEOUT 30
+#define SUBSCRIPTION_FILE_IMMEDIATE_TIMEOUT (5*60)
struct subsfile_list_context {
pool_t pool;
"/" SUBSCRIPTION_FILE_NAME, NULL);
/* FIXME: set lock notification callback */
fd_out = file_dotlock_open(path, NULL, SUBSCRIPTION_FILE_LOCK_TIMEOUT,
- SUBSCRIPTION_FILE_STALE_TIMEOUT, NULL, NULL);
+ SUBSCRIPTION_FILE_CHANGE_TIMEOUT,
+ SUBSCRIPTION_FILE_IMMEDIATE_TIMEOUT,
+ NULL, NULL);
if (fd_out == -1) {
if (errno == EAGAIN) {
mail_storage_set_error(storage,
struct lock_info {
const char *path, *lock_path, *temp_path;
unsigned int stale_timeout;
+ unsigned int immediate_stale_timeout;
int fd;
dev_t dev;
return 1;
}
+ if (lock_info->immediate_stale_timeout != 0 &&
+ now > st.st_mtime + (time_t)lock_info->immediate_stale_timeout &&
+ now > st.st_ctime + (time_t)lock_info->immediate_stale_timeout) {
+ /* old lock file */
+ if (unlink(lock_info->lock_path) < 0 && errno != ENOENT) {
+ i_error("unlink(%s) failed: %m", lock_info->lock_path);
+ return -1;
+ }
+ return 1;
+ }
+
+ if (lock_info->stale_timeout == 0) {
+ /* no change checking */
+ return 0;
+ }
+
if (lock_info->ino != st.st_ino ||
!CMP_DEV_T(lock_info->dev, st.st_dev) ||
lock_info->ctime != st.st_ctime ||
static int dotlock_create(const char *path, const char *temp_prefix,
int checkonly, int *fd,
unsigned int timeout, unsigned int stale_timeout,
+ unsigned int immediate_stale_timeout,
int (*callback)(unsigned int secs_left, int stale,
void *context),
void *context)
lock_info.path = path;
lock_info.lock_path = lock_path;
lock_info.stale_timeout = stale_timeout;
+ lock_info.immediate_stale_timeout = immediate_stale_timeout;
lock_info.last_change = now;
lock_info.fd = -1;
int file_lock_dotlock(const char *path, const char *temp_prefix, int checkonly,
unsigned int timeout, unsigned int stale_timeout,
+ unsigned int immediate_stale_timeout,
int (*callback)(unsigned int secs_left, int stale,
void *context),
void *context, struct dotlock *dotlock_r)
lock_path = t_strconcat(path, ".lock", NULL);
ret = dotlock_create(path, temp_prefix, checkonly, &fd,
- timeout, stale_timeout, callback, context);
+ timeout, stale_timeout, immediate_stale_timeout,
+ callback, context);
if (ret <= 0 || checkonly)
return ret;
int file_dotlock_open(const char *path, const char *temp_prefix,
unsigned int timeout, unsigned int stale_timeout,
+ unsigned int immediate_stale_timeout,
int (*callback)(unsigned int secs_left, int stale,
void *context),
void *context)
int ret, fd;
ret = dotlock_create(path, temp_prefix, FALSE, &fd,
- timeout, stale_timeout, callback, context);
+ timeout, stale_timeout, immediate_stale_timeout,
+ callback, context);
if (ret <= 0)
return -1;
return fd;
then, the lock will not be overridden. */
int file_lock_dotlock(const char *path, const char *temp_prefix, int checkonly,
unsigned int timeout, unsigned int stale_timeout,
+ unsigned int immediate_stale_timeout,
int (*callback)(unsigned int secs_left, int stale,
void *context),
void *context, struct dotlock *dotlock_r);
If locking timed out, returns -1 and errno = EAGAIN. */
int file_dotlock_open(const char *path, const char *temp_prefix,
unsigned int timeout, unsigned int stale_timeout,
+ unsigned int immediate_stale_timeout,
int (*callback)(unsigned int secs_left, int stale,
void *context),
void *context);