9excl.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #include "stdinc.h"
  2. #include "9.h"
  3. static struct {
  4. VtLock* lock;
  5. Excl* head;
  6. Excl* tail;
  7. } ebox;
  8. typedef struct Excl {
  9. Fsys* fsys;
  10. uvlong path;
  11. ulong time;
  12. Excl* next;
  13. Excl* prev;
  14. } Excl;
  15. enum {
  16. LifeTime = (5*60),
  17. };
  18. int
  19. exclAlloc(Fid* fid)
  20. {
  21. ulong t;
  22. Excl *excl;
  23. assert(fid->excl == nil);
  24. t = time(0L);
  25. vtLock(ebox.lock);
  26. for(excl = ebox.head; excl != nil; excl = excl->next){
  27. if(excl->fsys != fid->fsys || excl->path != fid->qid.path)
  28. continue;
  29. /*
  30. * Found it.
  31. * Now, check if it's timed out.
  32. * If not, return error, it's locked.
  33. * If it has timed out, zap the old
  34. * one and continue on to allocate a
  35. * a new one.
  36. */
  37. if(excl->time >= t){
  38. vtUnlock(ebox.lock);
  39. vtSetError("exclusive lock");
  40. return 0;
  41. }
  42. excl->fsys = nil;
  43. }
  44. /*
  45. * Not found or timed-out.
  46. * Alloc a new one and initialise.
  47. */
  48. excl = vtMemAllocZ(sizeof(Excl));
  49. excl->fsys = fid->fsys;
  50. excl->path = fid->qid.path;
  51. excl->time = t+LifeTime;
  52. if(ebox.tail != nil){
  53. excl->prev = ebox.tail;
  54. ebox.tail->next = excl;
  55. }
  56. else{
  57. ebox.head = excl;
  58. excl->prev = nil;
  59. }
  60. ebox.tail = excl;
  61. excl->next = nil;
  62. vtUnlock(ebox.lock);
  63. fid->excl = excl;
  64. return 1;
  65. }
  66. int
  67. exclUpdate(Fid* fid)
  68. {
  69. ulong t;
  70. Excl *excl;
  71. excl = fid->excl;
  72. t = time(0L);
  73. vtLock(ebox.lock);
  74. if(excl->time < t || excl->fsys != fid->fsys){
  75. vtUnlock(ebox.lock);
  76. vtSetError("exclusive lock broken");
  77. return 0;
  78. }
  79. excl->time = t+LifeTime;
  80. vtUnlock(ebox.lock);
  81. return 1;
  82. }
  83. void
  84. exclFree(Fid* fid)
  85. {
  86. Excl *excl;
  87. if((excl = fid->excl) == nil)
  88. return;
  89. fid->excl = nil;
  90. vtLock(ebox.lock);
  91. if(excl->prev != nil)
  92. excl->prev->next = excl->next;
  93. else
  94. ebox.head = excl->next;
  95. if(excl->next != nil)
  96. excl->next->prev = excl->prev;
  97. else
  98. ebox.tail = excl->prev;
  99. vtUnlock(ebox.lock);
  100. vtMemFree(excl);
  101. }
  102. void
  103. exclInit(void)
  104. {
  105. ebox.lock = vtLockAlloc();
  106. }