Blob
- Date:
- Message:
- acme: check file content before declaring file "modified since last read" Bad remote file systems can change mtime unexpectedly, and then there is the problem that git rebase and similar operations like to change the files and then change them back, modifying the mtimes but not the content. Avoid spurious Put errors on both of those by checking file content. (False positive "modified since last read" make the real ones difficult to notice.)
- Actions:
- History | Blame | Raw File
1 #include <u.h>2 #include <libc.h>3 #include <draw.h>4 #include <thread.h>5 #include <cursor.h>6 #include <mouse.h>7 #include <keyboard.h>8 #include <frame.h>9 #include <fcall.h>10 #include <plumb.h>11 #include <libsec.h>12 #include "dat.h"13 #include "fns.h"15 static Channel* ctimer; /* chan(Timer*)[100] */16 static Timer *timer;18 static19 uint20 msec(void)21 {22 return nsec()/1000000;23 }25 void26 timerstop(Timer *t)27 {28 t->next = timer;29 timer = t;30 }32 void33 timercancel(Timer *t)34 {35 t->cancel = TRUE;36 }38 static39 void40 timerproc(void *v)41 {42 int i, nt, na, dt, del;43 Timer **t, *x;44 uint old, new;46 USED(v);47 threadsetname("timerproc");48 rfork(RFFDG);49 t = nil;50 na = 0;51 nt = 0;52 old = msec();53 for(;;){54 sleep(10); /* longer sleeps here delay recv on ctimer, but 10ms should not be noticeable */55 new = msec();56 dt = new-old;57 old = new;58 if(dt < 0) /* timer wrapped; go around, losing a tick */59 continue;60 for(i=0; i<nt; i++){61 x = t[i];62 x->dt -= dt;63 del = FALSE;64 if(x->cancel){65 timerstop(x);66 del = TRUE;67 }else if(x->dt <= 0){68 /*69 * avoid possible deadlock if client is70 * now sending on ctimer71 */72 if(nbsendul(x->c, 0) > 0)73 del = TRUE;74 }75 if(del){76 memmove(&t[i], &t[i+1], (nt-i-1)*sizeof t[0]);77 --nt;78 --i;79 }80 }81 if(nt == 0){82 x = recvp(ctimer);83 gotit:84 if(nt == na){85 na += 10;86 t = realloc(t, na*sizeof(Timer*));87 if(t == nil)88 error("timer realloc failed");89 }90 t[nt++] = x;91 old = msec();92 }93 if(nbrecv(ctimer, &x) > 0)94 goto gotit;95 }96 }98 void99 timerinit(void)100 {101 ctimer = chancreate(sizeof(Timer*), 100);102 chansetname(ctimer, "ctimer");103 proccreate(timerproc, nil, STACK);104 }106 Timer*107 timerstart(int dt)108 {109 Timer *t;111 t = timer;112 if(t)113 timer = timer->next;114 else{115 t = emalloc(sizeof(Timer));116 t->c = chancreate(sizeof(int), 0);117 chansetname(t->c, "tc%p", t->c);118 }119 t->next = nil;120 t->dt = dt;121 t->cancel = FALSE;122 sendp(ctimer, t);123 return t;124 }