URI: 
       t9excl.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       t9excl.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 }