plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

9excl.c (1833B)


      1 #include "stdinc.h"
      2 
      3 #include "9.h"
      4 
      5 static struct {
      6 	QLock	lock;
      7 
      8 	Excl*	head;
      9 	Excl*	tail;
     10 } ebox;
     11 
     12 struct Excl {
     13 	Fsys*	fsys;
     14 	uvlong	path;
     15 	ulong	time;
     16 
     17 	Excl*	next;
     18 	Excl*	prev;
     19 };
     20 
     21 enum {
     22 	LifeTime	= (5*60),
     23 };
     24 
     25 int
     26 exclAlloc(Fid* fid)
     27 {
     28 	ulong t;
     29 	Excl *excl;
     30 
     31 	assert(fid->excl == nil);
     32 
     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 	}
     53 
     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);
     73 
     74 	fid->excl = excl;
     75 	return 1;
     76 }
     77 
     78 int
     79 exclUpdate(Fid* fid)
     80 {
     81 	ulong t;
     82 	Excl *excl;
     83 
     84 	excl = fid->excl;
     85 
     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);
     95 
     96 	return 1;
     97 }
     98 
     99 void
    100 exclFree(Fid* fid)
    101 {
    102 	Excl *excl;
    103 
    104 	if((excl = fid->excl) == nil)
    105 		return;
    106 	fid->excl = nil;
    107 
    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);
    118 
    119 	vtfree(excl);
    120 }
    121 
    122 void
    123 exclInit(void)
    124 {
    125 }