123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- #include "stdinc.h"
- #include "9.h"
- static struct {
- VtLock* lock;
- Excl* head;
- Excl* tail;
- } ebox;
- typedef struct Excl {
- Fsys* fsys;
- uvlong path;
- ulong time;
- Excl* next;
- Excl* prev;
- } Excl;
- enum {
- LifeTime = (5*60),
- };
- int
- exclAlloc(Fid* fid)
- {
- ulong t;
- Excl *excl;
- assert(fid->excl == nil);
- t = time(0L);
- vtLock(ebox.lock);
- for(excl = ebox.head; excl != nil; excl = excl->next){
- if(excl->fsys != fid->fsys || excl->path != fid->qid.path)
- continue;
- /*
- * Found it.
- * Now, check if it's timed out.
- * If not, return error, it's locked.
- * If it has timed out, zap the old
- * one and continue on to allocate a
- * a new one.
- */
- if(excl->time >= t){
- vtUnlock(ebox.lock);
- vtSetError("exclusive lock");
- return 0;
- }
- excl->fsys = nil;
- }
- /*
- * Not found or timed-out.
- * Alloc a new one and initialise.
- */
- excl = vtMemAllocZ(sizeof(Excl));
- excl->fsys = fid->fsys;
- excl->path = fid->qid.path;
- excl->time = t+LifeTime;
- if(ebox.tail != nil){
- excl->prev = ebox.tail;
- ebox.tail->next = excl;
- }
- else{
- ebox.head = excl;
- excl->prev = nil;
- }
- ebox.tail = excl;
- excl->next = nil;
- vtUnlock(ebox.lock);
- fid->excl = excl;
- return 1;
- }
- int
- exclUpdate(Fid* fid)
- {
- ulong t;
- Excl *excl;
- excl = fid->excl;
- t = time(0L);
- vtLock(ebox.lock);
- if(excl->time < t || excl->fsys != fid->fsys){
- vtUnlock(ebox.lock);
- vtSetError("exclusive lock broken");
- return 0;
- }
- excl->time = t+LifeTime;
- vtUnlock(ebox.lock);
- return 1;
- }
- void
- exclFree(Fid* fid)
- {
- Excl *excl;
- if((excl = fid->excl) == nil)
- return;
- fid->excl = nil;
- vtLock(ebox.lock);
- if(excl->prev != nil)
- excl->prev->next = excl->next;
- else
- ebox.head = excl->next;
- if(excl->next != nil)
- excl->next->prev = excl->prev;
- else
- ebox.tail = excl->prev;
- vtUnlock(ebox.lock);
- vtMemFree(excl);
- }
- void
- exclInit(void)
- {
- ebox.lock = vtLockAlloc();
- }
|