dovecot-2.2: lib: file_wait/try_lock() treats EINTR differently ...

dovecot at dovecot.org dovecot at dovecot.org
Tue Nov 11 01:15:40 UTC 2014


details:   http://hg.dovecot.org/dovecot-2.2/rev/4cc4d7b03b3b
changeset: 18055:4cc4d7b03b3b
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Nov 11 03:13:16 2014 +0200
description:
lib: file_wait/try_lock() treats EINTR differently now for timeouts and for actual signals.

diffstat:

 src/lib/file-lock.c |  18 +++++++++++++-----
 1 files changed, 13 insertions(+), 5 deletions(-)

diffs (54 lines):

diff -r e5cf0209bc9e -r 4cc4d7b03b3b src/lib/file-lock.c
--- a/src/lib/file-lock.c	Fri Oct 31 04:27:27 2014 +0200
+++ b/src/lib/file-lock.c	Tue Nov 11 03:13:16 2014 +0200
@@ -4,6 +4,7 @@
 #include "istream.h"
 #include "file-lock.h"
 
+#include <time.h>
 #include <sys/stat.h>
 #ifdef HAVE_FLOCK
 #  include <sys/file.h>
@@ -144,11 +145,21 @@
 	return file_lock_find_proc_locks(lock_fd);
 }
 
+static bool err_is_lock_timeout(time_t started, unsigned int timeout_secs)
+{
+	/* if EINTR took at least timeout_secs-1 number of seconds,
+	   assume it was the alarm. otherwise log EINTR failure.
+	   (We most likely don't want to retry EINTR since a signal
+	   means somebody wants us to stop blocking). */
+	return errno == EINTR && time(NULL) - started + 1 >= timeout_secs;
+}
+
 static int file_lock_do(int fd, const char *path, int lock_type,
 			enum file_lock_method lock_method,
 			unsigned int timeout_secs, const char **error_r)
 {
 	const char *lock_type_str;
+	time_t started = time(NULL);
 	int ret;
 
 	i_assert(fd != -1);
@@ -188,10 +199,7 @@
 			return 0;
 		}
 
-		if (errno == EINTR) {
-			/* most likely alarm hit, meaning we timeouted.
-			   even if not, we probably want to be killed
-			   so stop blocking. */
+		if (err_is_lock_timeout(started, timeout_secs)) {
 			errno = EAGAIN;
 			*error_r = t_strdup_printf(
 				"fcntl(%s, %s, F_SETLKW) locking failed: "
@@ -238,7 +246,7 @@
 				"(File is already locked)", path, lock_type_str);
 			return 0;
 		}
-		if (errno == EINTR) {
+		if (err_is_lock_timeout(started, timeout_secs)) {
 			errno = EAGAIN;
 			*error_r = t_strdup_printf("flock(%s, %s) failed: "
 				"Timed out after %u seconds%s",


More information about the dovecot-cvs mailing list