Blob
1 #include "stdinc.h"3 #include "9.h"5 static struct {6 QLock lock;8 Excl* head;9 Excl* tail;10 } ebox;12 struct Excl {13 Fsys* fsys;14 uvlong path;15 ulong time;17 Excl* next;18 Excl* prev;19 };21 enum {22 LifeTime = (5*60),23 };25 int26 exclAlloc(Fid* fid)27 {28 ulong t;29 Excl *excl;31 assert(fid->excl == nil);33 t = time(0L);34 qlock(&ebox.lock);35 for(excl = ebox.head; excl != nil; excl = excl->next){36 if(excl->fsys != fid->fsys || excl->path != fid->qid.path)37 continue;38 /*39 * Found it.40 * Now, check if it's timed out.41 * If not, return error, it's locked.42 * If it has timed out, zap the old43 * one and continue on to allocate a44 * a new one.45 */46 if(excl->time >= t){47 qunlock(&ebox.lock);48 werrstr("exclusive lock");49 return 0;50 }51 excl->fsys = nil;52 }54 /*55 * Not found or timed-out.56 * Alloc a new one and initialise.57 */58 excl = vtmallocz(sizeof(Excl));59 excl->fsys = fid->fsys;60 excl->path = fid->qid.path;61 excl->time = t+LifeTime;62 if(ebox.tail != nil){63 excl->prev = ebox.tail;64 ebox.tail->next = excl;65 }66 else{67 ebox.head = excl;68 excl->prev = nil;69 }70 ebox.tail = excl;71 excl->next = nil;72 qunlock(&ebox.lock);74 fid->excl = excl;75 return 1;76 }78 int79 exclUpdate(Fid* fid)80 {81 ulong t;82 Excl *excl;84 excl = fid->excl;86 t = time(0L);87 qlock(&ebox.lock);88 if(excl->time < t || excl->fsys != fid->fsys){89 qunlock(&ebox.lock);90 werrstr("exclusive lock broken");91 return 0;92 }93 excl->time = t+LifeTime;94 qunlock(&ebox.lock);96 return 1;97 }99 void100 exclFree(Fid* fid)101 {102 Excl *excl;104 if((excl = fid->excl) == nil)105 return;106 fid->excl = nil;108 qlock(&ebox.lock);109 if(excl->prev != nil)110 excl->prev->next = excl->next;111 else112 ebox.head = excl->next;113 if(excl->next != nil)114 excl->next->prev = excl->prev;115 else116 ebox.tail = excl->prev;117 qunlock(&ebox.lock);119 vtfree(excl);120 }122 void123 exclInit(void)124 {125 }