[dovecot-cvs] dovecot/src/lib-index mail-index-lock.c, 1.13,
1.14 mail-index-view.c, 1.7, 1.8 mail-index.c, 1.120, 1.121
cras at procontrol.fi
cras at procontrol.fi
Sun May 16 23:20:27 EEST 2004
Update of /home/cvs/dovecot/src/lib-index
In directory talvi:/tmp/cvs-serv1096
Modified Files:
mail-index-lock.c mail-index-view.c mail-index.c
Log Message:
Locking fixes
Index: mail-index-lock.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-lock.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- mail-index-lock.c 3 May 2004 19:53:07 -0000 1.13
+++ mail-index-lock.c 16 May 2004 20:20:24 -0000 1.14
@@ -149,7 +149,7 @@
unsigned int timeout_secs, int update_index,
unsigned int *lock_id_r)
{
- int ret;
+ int ret, ret2;
i_assert(lock_type == F_RDLCK || lock_type == F_WRLCK);
@@ -166,8 +166,11 @@
}
if (update_index && index->excl_lock_count == 0) {
- if (mail_index_has_changed(index) < 0)
+ if ((ret2 = mail_index_has_changed(index)) < 0)
return -1;
+ if (ret > 0 && ret2 == 0)
+ return 1;
+ ret = 0;
}
if (ret > 0)
@@ -192,16 +195,36 @@
return 1;
}
- ret = file_wait_lock_full(index->fd, lock_type, timeout_secs,
- NULL, NULL);
- if (ret <= 0) {
- if (ret == 0 || errno == EDEADLK) {
- /* deadlock equals to timeout */
- return 0;
+ if (lock_type == F_RDLCK || !index->log_locked) {
+ ret = file_wait_lock_full(index->fd, lock_type, timeout_secs,
+ NULL, NULL);
+ if (ret < 0) {
+ mail_index_set_syscall_error(index, "file_wait_lock()");
+ return -1;
+ }
+ } else {
+ /* this is kind of kludgy. we wish to avoid deadlocks while
+ trying to lock transaction log, but it can happen if our
+ process is holding transaction log lock and waiting for
+ index write lock, while the other process is holding index
+ read lock and waiting for transaction log lock.
+
+ we don't have a problem with grabbing read index lock
+ because the only way for it to block is if it's
+ write-locked, which isn't allowed unless transaction log
+ is also locked.
+
+ so, the workaround for this problem is that we simply try
+ locking once. if it doesn't work, just rewrite the file.
+ hopefully there won't be any other deadlocking issues. :) */
+ ret = file_try_lock(index->fd, lock_type);
+ if (ret < 0) {
+ mail_index_set_syscall_error(index, "file_try_lock()");
+ return -1;
}
- mail_index_set_syscall_error(index, "file_wait_lock()");
- return -1;
}
+ if (ret == 0)
+ return 0;
if (index->lock_type == F_UNLCK)
index->lock_id += 2;
@@ -291,7 +314,7 @@
old_lock_type = index->lock_type;
index->lock_type = F_WRLCK;
- index->excl_lock_count++;
+ index->excl_lock_count++;
if (mail_index_reopen(index, fd) < 0) {
i_assert(index->excl_lock_count == 1);
@@ -422,5 +445,10 @@
int mail_index_is_locked(struct mail_index *index, unsigned int lock_id)
{
- return (index->lock_id ^ lock_id) <= 1;
+ if ((index->lock_id ^ lock_id) <= 1) {
+ i_assert(index->lock_type != F_UNLCK);
+ return TRUE;
+ }
+
+ return FALSE;
}
Index: mail-index-view.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-view.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- mail-index-view.c 9 May 2004 23:20:04 -0000 1.7
+++ mail-index-view.c 16 May 2004 20:20:24 -0000 1.8
@@ -50,11 +50,6 @@
{
unsigned int lock_id;
- if (view->map != view->index->map) {
- if (mail_index_view_map_protect(view) < 0)
- return -1;
- }
-
if (!mail_index_is_locked(view->index, view->lock_id)) {
if (mail_index_lock_shared(view->index, update_index,
&view->lock_id) < 0)
@@ -78,6 +73,15 @@
view->lock_id = lock_id;
}
+ i_assert(view->index->lock_type != F_UNLCK);
+
+ /* mail_index_lock_shared() may have reopened the file,
+ so do this after it. */
+ if (view->map != view->index->map) {
+ if (mail_index_view_map_protect(view) < 0)
+ return -1;
+ }
+
return 0;
}
Index: mail-index.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index.c,v
retrieving revision 1.120
retrieving revision 1.121
diff -u -d -r1.120 -r1.121
--- mail-index.c 9 May 2004 23:06:27 -0000 1.120
+++ mail-index.c 16 May 2004 20:20:24 -0000 1.121
@@ -574,6 +574,7 @@
index->shared_lock_count = 0;
index->excl_lock_count = 0;
index->lock_type = F_UNLCK;
+ index->lock_id = 2;
index->nodiskspace = FALSE;
index->index_lock_timeout = FALSE;
More information about the dovecot-cvs
mailing list