old_mask = umask(cache->index->mode ^ 0666);
fd = file_dotlock_open(&cache->dotlock_settings, cache->filepath,
- 0, &dotlock);
+ DOTLOCK_CREATE_FLAG_NONBLOCK, &dotlock);
umask(old_mask);
if (fd == -1) {
- mail_cache_set_syscall_error(cache, "file_dotlock_open()");
+ if (errno != EAGAIN)
+ mail_cache_set_syscall_error(cache, "file_dotlock_open()");
return -1;
}
FALSE);
}
} else {
- switch (mail_cache_lock(cache, FALSE)) {
+ switch (mail_cache_try_lock(cache)) {
case -1:
return -1;
case 0:
/* Explicitly lock the cache file. Returns -1 if error / timed out,
1 if ok, 0 if cache is broken/doesn't exist */
int mail_cache_lock(struct mail_cache *cache, bool require_same_reset_id);
+int mail_cache_try_lock(struct mail_cache *cache);
/* Returns -1 if cache is / just got corrupted, 0 if ok. */
int mail_cache_unlock(struct mail_cache *cache);
i_free(cache);
}
-static int mail_cache_lock_file(struct mail_cache *cache)
+static int mail_cache_lock_file(struct mail_cache *cache, bool nonblock)
{
int ret;
i_assert(cache->file_lock == NULL);
ret = mail_index_lock_fd(cache->index, cache->filepath,
cache->fd, F_WRLCK,
- MAIL_CACHE_LOCK_TIMEOUT,
+ nonblock ? 0 : MAIL_CACHE_LOCK_TIMEOUT,
&cache->file_lock);
} else {
+ enum dotlock_create_flags flags =
+ nonblock ? DOTLOCK_CREATE_FLAG_NONBLOCK : 0;
+
i_assert(cache->dotlock == NULL);
ret = file_dotlock_create(&cache->dotlock_settings,
- cache->filepath, 0, &cache->dotlock);
+ cache->filepath, flags,
+ &cache->dotlock);
if (ret <= 0) {
mail_cache_set_syscall_error(cache,
"file_dotlock_create()");
(void)file_dotlock_delete(&cache->dotlock);
}
-int mail_cache_lock(struct mail_cache *cache, bool require_same_reset_id)
+static int
+mail_cache_lock_full(struct mail_cache *cache, bool require_same_reset_id,
+ bool nonblock)
{
const struct mail_index_ext *ext;
struct mail_index_view *iview;
break;
}
- if ((ret = mail_cache_lock_file(cache)) <= 0) {
+ if ((ret = mail_cache_lock_file(cache, nonblock)) <= 0) {
ret = -1;
break;
}
return ret;
}
+int mail_cache_lock(struct mail_cache *cache, bool require_same_reset_id)
+{
+ return mail_cache_lock_full(cache, require_same_reset_id, FALSE);
+}
+
+int mail_cache_try_lock(struct mail_cache *cache)
+{
+ return mail_cache_lock_full(cache, FALSE, TRUE);
+}
+
static void mail_cache_update_need_compress(struct mail_cache *cache)
{
const struct mail_cache_header *hdr = cache->hdr;