summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/fusefrontend/write_lock.go62
1 files changed, 37 insertions, 25 deletions
diff --git a/internal/fusefrontend/write_lock.go b/internal/fusefrontend/write_lock.go
index a8ec6b6..2f8ea4e 100644
--- a/internal/fusefrontend/write_lock.go
+++ b/internal/fusefrontend/write_lock.go
@@ -5,7 +5,7 @@ import (
)
func init() {
- wlock.m = make(map[uint64]*refCntMutex)
+ wlock.inodeLocks = make(map[uint64]*refCntMutex)
}
// wlock - serializes write accesses to each file (identified by inode number)
@@ -20,47 +20,59 @@ var wlock wlockMap
// 2) lock ... unlock ...
// 3) unregister
type wlockMap struct {
- mapMutex sync.RWMutex
- m map[uint64]*refCntMutex
+ // Protects map access
+ sync.Mutex
+ inodeLocks map[uint64]*refCntMutex
+}
+
+// refCntMutex - mutex with reference count
+type refCntMutex struct {
+ // Write lock for this inode
+ sync.Mutex
+ // Reference count
+ refCnt int
}
+// register creates an entry for "ino", or incrementes the reference count
+// if the entry already exists.
func (w *wlockMap) register(ino uint64) {
- w.mapMutex.Lock()
- r := w.m[ino]
+ w.Lock()
+ defer w.Unlock()
+
+ r := w.inodeLocks[ino]
if r == nil {
r = &refCntMutex{}
- w.m[ino] = r
+ w.inodeLocks[ino] = r
}
- r.refCnt++ // this must happen inside the mapMutex lock
- w.mapMutex.Unlock()
+ r.refCnt++
}
+// unregister decrements the reference count for "ino" and deletes the entry if
+// the reference count has reached 0.
func (w *wlockMap) unregister(ino uint64) {
- w.mapMutex.Lock()
- r := w.m[ino]
+ w.Lock()
+ defer w.Unlock()
+
+ r := w.inodeLocks[ino]
r.refCnt--
if r.refCnt == 0 {
- delete(w.m, ino)
+ delete(w.inodeLocks, ino)
}
- w.mapMutex.Unlock()
}
+// lock retrieves the entry for "ino" and locks it.
func (w *wlockMap) lock(ino uint64) {
- w.mapMutex.RLock()
- r := w.m[ino]
- w.mapMutex.RUnlock()
- r.Lock() // this can take a long time - execute outside the mapMutex lock
+ w.Lock()
+ r := w.inodeLocks[ino]
+ w.Unlock()
+ // this can take a long time - execute outside the wlockMap lock
+ r.Lock()
}
+// unlock retrieves the entry for "ino" and unlocks it.
func (w *wlockMap) unlock(ino uint64) {
- w.mapMutex.RLock()
- r := w.m[ino]
- w.mapMutex.RUnlock()
+ w.Lock()
+ r := w.inodeLocks[ino]
+ w.Unlock()
r.Unlock()
}
-
-// refCntMutex - mutex with reference count
-type refCntMutex struct {
- sync.Mutex
- refCnt int
-}