|
|
62c494 |
diff -up cyrus-imapd-2.4.6/lib/lock_flock.c.flock cyrus-imapd-2.4.6/lib/lock_flock.c
|
|
|
62c494 |
--- cyrus-imapd-2.4.6/lib/lock_flock.c.flock 2010-12-20 14:15:49.000000000 +0100
|
|
|
62c494 |
+++ cyrus-imapd-2.4.6/lib/lock_flock.c 2011-02-10 12:56:45.262786102 +0100
|
|
|
62c494 |
@@ -52,6 +52,10 @@
|
|
|
62c494 |
#endif
|
|
|
62c494 |
|
|
|
62c494 |
#include "cyr_lock.h"
|
|
|
62c494 |
+#include <syslog.h>
|
|
|
62c494 |
+
|
|
|
62c494 |
+/* Locking timeout parameter */
|
|
|
62c494 |
+#define MAXTIME 99
|
|
|
62c494 |
|
|
|
62c494 |
const char *lock_method_desc = "flock";
|
|
|
62c494 |
|
|
|
62c494 |
@@ -68,6 +72,18 @@ const char *lock_method_desc = "flock";
|
|
|
62c494 |
* 'failaction' is provided, it is filled in with a pointer to a fixed
|
|
|
62c494 |
* string naming the action that failed.
|
|
|
62c494 |
*
|
|
|
62c494 |
+ * Modified by jwade 4/16/2002 to work around seen file locking problem
|
|
|
62c494 |
+ * Added locking timeout parameter to allow processes that are
|
|
|
62c494 |
+ * waiting for a lock to eventually time out
|
|
|
62c494 |
+ *
|
|
|
62c494 |
+ * Calls flock() in non-blocking fashion and then retries until a
|
|
|
62c494 |
+ * maximum delay is reached or the lock succeeds.
|
|
|
62c494 |
+ *
|
|
|
62c494 |
+ * As written, uses a quadratic backoff on retries with MAXTIME being
|
|
|
62c494 |
+ * the longest interval delay. Total delay time is the sum of the squares
|
|
|
62c494 |
+ * of all integers whose square is less than MAXTIME. In the case of
|
|
|
62c494 |
+ * MAXTIME = 99 this is 0+1+4+9+16+25+36+49+64+81= 285 Seconds
|
|
|
62c494 |
+ * This time is arbitrary and can be adjusted
|
|
|
62c494 |
*/
|
|
|
62c494 |
int lock_reopen(fd, filename, sbuf, failaction)
|
|
|
62c494 |
int fd;
|
|
|
62c494 |
@@ -78,17 +94,29 @@ const char **failaction;
|
|
|
62c494 |
int r;
|
|
|
62c494 |
struct stat sbuffile, sbufspare;
|
|
|
62c494 |
int newfd;
|
|
|
62c494 |
+ int delay=0, i=0;
|
|
|
62c494 |
|
|
|
62c494 |
if (!sbuf) sbuf = &sbufspare;
|
|
|
62c494 |
|
|
|
62c494 |
- for (;;) {
|
|
|
62c494 |
- r = flock(fd, LOCK_EX);
|
|
|
62c494 |
+ for(i=0,delay=0;;) {
|
|
|
62c494 |
+ r = flock(fd, LOCK_EX|LOCK_NB);
|
|
|
62c494 |
if (r == -1) {
|
|
|
62c494 |
- if (errno == EINTR) continue;
|
|
|
62c494 |
- if (failaction) *failaction = "locking";
|
|
|
62c494 |
+ if (errno == EINTR) {
|
|
|
62c494 |
+ continue;
|
|
|
62c494 |
+ }
|
|
|
62c494 |
+ else if ((errno == EWOULDBLOCK) && (delay < MAXTIME)) {
|
|
|
62c494 |
+ syslog(LOG_DEBUG, "lock: reopen-blocked sleeping for %d on interval %d (%d, %s)" , delay, i, fd, filename);
|
|
|
62c494 |
+ sleep(delay);
|
|
|
62c494 |
+ i++;
|
|
|
62c494 |
+ delay = i*i;
|
|
|
62c494 |
+ continue;
|
|
|
62c494 |
+ }
|
|
|
62c494 |
+ if (failaction) {
|
|
|
62c494 |
+ if (delay >= MAXTIME) *failaction = "locking_timeout";
|
|
|
62c494 |
+ else *failaction = "locking";
|
|
|
62c494 |
+ }
|
|
|
62c494 |
return -1;
|
|
|
62c494 |
}
|
|
|
62c494 |
-
|
|
|
62c494 |
fstat(fd, sbuf);
|
|
|
62c494 |
r = stat(filename, &sbuffile);
|
|
|
62c494 |
if (r == -1) {
|
|
|
62c494 |
@@ -96,9 +124,7 @@ const char **failaction;
|
|
|
62c494 |
flock(fd, LOCK_UN);
|
|
|
62c494 |
return -1;
|
|
|
62c494 |
}
|
|
|
62c494 |
-
|
|
|
62c494 |
if (sbuf->st_ino == sbuffile.st_ino) return 0;
|
|
|
62c494 |
-
|
|
|
62c494 |
newfd = open(filename, O_RDWR);
|
|
|
62c494 |
if (newfd == -1) {
|
|
|
62c494 |
if (failaction) *failaction = "opening";
|