if you have a slow upstream link, mailing multi-megabyte files can take minutes, and the C. DMEXCL lock can go stale, and running the queues can cause other smtps to start up trying to resend it. presotto acknowledged that this is a potential problem and that another process would be needed to keep the lock alive, but then left the labs. this fix recycles existing upas machinery to start a process to keep the lock alive until the file is sent. Notes: Sun Apr 17 08:46:34 EDT 2005 rsc Reference: /n/sources/patch/applied/runq-keep-lock-alive Date: Thu Apr 14 07:03:49 CES 2005 Reviewed-by: rsc --- /sys/src/cmd/upas/q/runq.c Thu Apr 14 07:01:15 2005 +++ /sys/src/cmd/upas/q/runq.c Thu Apr 14 07:01:12 2005 @@ -282,6 +282,39 @@ } /* + * like trylock, but we've already got the lock on fd, + * and don't want an L. lock file. + */ +static Mlock * +keeplockalive(char *path, int fd) +{ + char buf[1]; + Mlock *l; + + l = malloc(sizeof(Mlock)); + if(l == 0) + return 0; + l->fd = fd; + l->name = s_new(); + s_append(l->name, path); + + /* fork process to keep lock alive until sysunlock(l) */ + switch(l->pid = rfork(RFPROC)){ + default: + break; + case 0: + fd = l->fd; + for(;;){ + sleep(1000*60); + if(pread(fd, buf, 1, 0) < 0) + break; + } + _exits(0); + } + return l; +} + +/* * try a message */ void @@ -292,6 +325,7 @@ char *buf, *cp, **av; Waitmsg *wm; Biobuf *b; + Mlock *l = nil; if(debug) fprint(2, "dofile %s\n", dp->name); @@ -331,7 +365,7 @@ if(time(0) - etime < 60*60) return; } - + } /* @@ -424,11 +458,18 @@ } /* + * Ken's fs, for example, gives us 5 minutes of inactivity before + * the lock goes stale, so we have to keep reading it. + */ + l = keeplockalive(file(dp->name, 'C'), Bfildes(b)); + + /* * transfer */ pid = fork(); switch(pid){ case -1: + sysunlock(l); sysunlockfile(Bfildes(b)); syslog(0, runqlog, "out of procs"); exits(0); @@ -491,6 +532,8 @@ } done: + if (l) + sysunlock(l); Bterm(b); sysunlockfile(Bfildes(b)); free(buf); @@ -619,7 +662,7 @@ rerrstr(err, sizeof(err)); snprint(buf, sizeof(buf), f, a); - fprint(2, "runq: %s: %s\n", buf, err); + fprint(2, "runq: %s: %s\n", buf, err); } /* @@ -634,7 +677,7 @@ rerrstr(err, sizeof(err)); snprint(buf, sizeof(buf), f, a); fprint(2, "runq: %s: %s\n", buf, err); - exits(buf); + exits(buf); } void