123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- /*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
- #include "stdinc.h"
- #include "9.h"
- static struct {
- VtLock* lock;
- Excl* head;
- Excl* tail;
- } ebox;
- struct Excl {
- Fsys* fsys;
- uint64_t path;
- uint32_t time;
- Excl* next;
- Excl* prev;
- };
- enum {
- LifeTime = (5*60),
- };
- int
- exclAlloc(Fid* fid)
- {
- uint32_t 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)
- {
- uint32_t 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();
- }
|