mbox-lock.c revision 94f9cf3436f949d6450e8cda523979fc1b11f103
/* Copyright (C) 2002 Timo Sirainen */
#include "lib.h"
#include "mbox-index.h"
#include "mbox-lock.h"
#include "mail-index-util.h"
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#ifdef HAVE_FLOCK
#endif
/* 0.1 .. 0.2msec */
/* lock methods to use in wanted order */
#define DEFAULT_LOCK_METHODS "dotlock fcntl"
/* lock timeout */
#define DEFAULT_LOCK_TIMEOUT 300
/* assume stale dotlock if mbox file hasn't changed for n seconds */
#define DEFAULT_DOTLOCK_CHANGE_TIMEOUT 30
struct dotlock_context {
struct mail_index *index;
enum mail_lock_type lock_type;
int last_stale;
};
static int lock_settings_initialized = FALSE;
static void mbox_init_lock_settings(void)
{
const char *str;
const char *const *lock;
use_dotlock = TRUE;
else
}
}
#ifdef HAVE_FLOCK
{
if (lock_type == MAIL_LOCK_EXCLUSIVE)
else if (lock_type == MAIL_LOCK_SHARED)
else
last_notify = 0;
if (errno != EWOULDBLOCK) {
return FALSE;
}
if (max_wait_time == 0)
return FALSE;
if (now >= max_wait_time) {
"release of flock() lock for mbox file "
return FALSE;
}
last_notify = now;
max_wait_time - now,
}
}
return TRUE;
}
#endif
{
int wait_type;
return FALSE;
}
"release of fcntl() lock for mbox file "
return FALSE;
}
max_wait_time - now,
}
}
return TRUE;
}
{
/* now we need to have the file itself locked. open it if needed. */
if (!mbox_file_open(index)) {
(void)mbox_unlock(index);
return FALSE;
}
}
if (use_fcntl_lock && fcntl_before_flock) {
return FALSE;
}
#ifdef HAVE_FLOCK
if (use_flock) {
return FALSE;
}
#endif
if (use_fcntl_lock && !fcntl_before_flock) {
return FALSE;
}
return TRUE;
}
{
#ifdef HAVE_FLOCK
#endif
if (use_fcntl_lock &&
return !failed;
}
{
return FALSE;
}
}
return TRUE;
}
{
int ret;
/* index must be locked before mbox file, to avoid deadlocks */
return TRUE;
/* make .lock file first to protect overwriting the file */
struct dotlock_context ctx;
lock_type == MAIL_LOCK_SHARED &&
&index->mbox_dotlock);
if (ret < 0) {
return FALSE;
}
if (ret == 0) {
"release of dotlock for mbox %s",
return FALSE;
}
}
(void)mbox_unlock(index);
return FALSE;
}
return TRUE;
}
{
int failed;
return TRUE;
if (!mbox_file_unlock(index))
}
&index->mbox_dotlock) <= 0) {
}
}
/* make sure we don't keep mmap() between locks - there could have
been changes to file size which would break things. or actually
it'd break only if file was shrinked+grown back to exact size,
but still possible :) */
return !failed;
}