John Dennis 38f226
--- cyrus-imapd-2.1.3/lib/lock_flock.c	Tue Oct  2 16:08:13 2001
John Dennis 38f226
+++ cyrus-imapd-2.1.3-patched/lib/lock_flock.c	Tue Apr 16 09:44:58 2002
John Dennis 38f226
@@ -51,6 +51,10 @@
John Dennis 38f226
 #endif
John Dennis 38f226
 
John Dennis 38f226
 #include "lock.h"
John Dennis 38f226
+#include <syslog.h>
John Dennis 38f226
+
John Dennis 38f226
+/* Locking timeout parameter */
John Dennis 38f226
+#define MAXTIME 99
John Dennis 38f226
 
John Dennis 38f226
 const char *lock_method_desc = "flock";
John Dennis 38f226
 
John Dennis 38f226
@@ -69,6 +73,18 @@
John Dennis 38f226
  * 'failaction' is provided, it is filled in with a pointer to a fixed
John Dennis 38f226
  * string naming the action that failed.
John Dennis 38f226
  *
John Dennis 38f226
+ *  Modified by jwade 4/16/2002 to work around seen file locking problem
John Dennis 38f226
+ *  Added locking timeout parameter to allow processes that are  
John Dennis 38f226
+ *  waiting for a lock to eventually time out
John Dennis 38f226
+ *
John Dennis 38f226
+ *  Calls flock() in non-blocking fashion and then retries until a 
John Dennis 38f226
+ *  maximum delay is reached or the lock succeeds.
John Dennis 38f226
+ *  
John Dennis 38f226
+ *  As written, uses a quadratic backoff on retries with MAXTIME being
John Dennis 38f226
+ *  the longest interval delay.   Total delay time is the sum of the squares
John Dennis 38f226
+ *  of all integers whose square is less than MAXTIME.  In the case of 
John Dennis 38f226
+ *  MAXTIME = 99 this is 0+1+4+9+16+25+36+49+64+81= 285 Seconds   
John Dennis 38f226
+ *  This time is arbitrary and can be adjusted
John Dennis 38f226
  */
John Dennis 38f226
 int lock_reopen(fd, filename, sbuf, failaction)
John Dennis 38f226
 int fd;
John Dennis 38f226
@@ -79,17 +95,29 @@
John Dennis 38f226
     int r;
John Dennis 38f226
     struct stat sbuffile, sbufspare;
John Dennis 38f226
     int newfd;
John Dennis 38f226
+    int delay=0, i=0;
John Dennis 38f226
 
John Dennis 38f226
     if (!sbuf) sbuf = &sbufspare;
John Dennis 38f226
 
John Dennis 38f226
-    for (;;) {
John Dennis 38f226
-	r = flock(fd, LOCK_EX);
John Dennis 38f226
+    for(i=0,delay=0;;) {
John Dennis 38f226
+	r = flock(fd, LOCK_EX|LOCK_NB);
John Dennis 38f226
 	if (r == -1) {
John Dennis 38f226
-	    if (errno == EINTR) continue;
John Dennis 38f226
-	    if (failaction) *failaction = "locking";
John Dennis 38f226
+	    if (errno == EINTR) {
John Dennis 38f226
+                 continue;
John Dennis 38f226
+            }
John Dennis 38f226
+            else if ((errno == EWOULDBLOCK) && (delay < MAXTIME)) {
John Dennis 38f226
+                syslog(LOG_DEBUG, "lock: reopen-blocked sleeping for %d on interval %d (%d, %s)" , delay, i, fd, filename);
John Dennis 38f226
+                sleep(delay);
John Dennis 38f226
+                i++;
John Dennis 38f226
+                delay = i*i;
John Dennis 38f226
+                continue;
John Dennis 38f226
+            }
John Dennis 38f226
+	    if (failaction) {
John Dennis 38f226
+                if (delay >= MAXTIME) *failaction = "locking_timeout";
John Dennis 38f226
+                else *failaction = "locking";
John Dennis 38f226
+            }
John Dennis 38f226
 	    return -1;
John Dennis 38f226
 	}
John Dennis 38f226
-
John Dennis 38f226
 	fstat(fd, sbuf);
John Dennis 38f226
 	r = stat(filename, &sbuffile);
John Dennis 38f226
 	if (r == -1) {
John Dennis 38f226
@@ -97,9 +125,7 @@
John Dennis 38f226
 	    flock(fd, LOCK_UN);
John Dennis 38f226
 	    return -1;
John Dennis 38f226
 	}
John Dennis 38f226
-
John Dennis 38f226
 	if (sbuf->st_ino == sbuffile.st_ino) return 0;
John Dennis 38f226
-
John Dennis 38f226
 	newfd = open(filename, O_RDWR);
John Dennis 38f226
 	if (newfd == -1) {
John Dennis 38f226
 	    if (failaction) *failaction = "opening";