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 int
26 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 old
43 * one and continue on to allocate a
44 * 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 int
79 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 void
100 exclFree(Fid* fid)
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 else
112 ebox.head = excl->next;
113 if(excl->next != nil)
114 excl->next->prev = excl->prev;
115 else
116 ebox.tail = excl->prev;
117 qunlock(&ebox.lock);
119 vtfree(excl);
122 void
123 exclInit(void)