1 --- cyrus-imapd-2.1.3/lib/lock_flock.c Tue Oct 2 16:08:13 2001
2 +++ cyrus-imapd-2.1.3-patched/lib/lock_flock.c Tue Apr 16 09:44:58 2002
9 +/* Locking timeout parameter */
12 const char *lock_method_desc = "flock";
15 * 'failaction' is provided, it is filled in with a pointer to a fixed
16 * string naming the action that failed.
18 + * Modified by jwade 4/16/2002 to work around seen file locking problem
19 + * Added locking timeout parameter to allow processes that are
20 + * waiting for a lock to eventually time out
22 + * Calls flock() in non-blocking fashion and then retries until a
23 + * maximum delay is reached or the lock succeeds.
25 + * As written, uses a quadratic backoff on retries with MAXTIME being
26 + * the longest interval delay. Total delay time is the sum of the squares
27 + * of all integers whose square is less than MAXTIME. In the case of
28 + * MAXTIME = 99 this is 0+1+4+9+16+25+36+49+64+81= 285 Seconds
29 + * This time is arbitrary and can be adjusted
31 int lock_reopen(fd, filename, sbuf, failaction)
35 struct stat sbuffile, sbufspare;
39 if (!sbuf) sbuf = &sbufspare;
42 - r = flock(fd, LOCK_EX);
43 + for(i=0,delay=0;;) {
44 + r = flock(fd, LOCK_EX|LOCK_NB);
46 - if (errno == EINTR) continue;
47 - if (failaction) *failaction = "locking";
48 + if (errno == EINTR) {
51 + else if ((errno == EWOULDBLOCK) && (delay < MAXTIME)) {
52 + syslog(LOG_DEBUG, "lock: reopen-blocked sleeping for %d on interval %d (%d, %s)" , delay, i, fd, filename);
59 + if (delay >= MAXTIME) *failaction = "locking_timeout";
60 + else *failaction = "locking";
66 r = stat(filename, &sbuffile);
73 if (sbuf->st_ino == sbuffile.st_ino) return 0;
75 newfd = open(filename, O_RDWR);
77 if (failaction) *failaction = "opening";