From 77813bdc13118fd08bbff7a68c9d5268080a2a15 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sun, 29 May 2016 22:40:05 +0200 Subject: [PATCH] fusefrontend: simplify wlockMap mapMutex can be anonymous and using an RWMutex is overkill because the lock protects very short sections. --- internal/fusefrontend/write_lock.go | 88 ++++++++++++++++------------- 1 file changed, 50 insertions(+), 38 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 -} - -func (w *wlockMap) register(ino uint64) { - w.mapMutex.Lock() - r := w.m[ino] - if r == nil { - r = &refCntMutex{} - w.m[ino] = r - } - r.refCnt++ // this must happen inside the mapMutex lock - w.mapMutex.Unlock() -} - -func (w *wlockMap) unregister(ino uint64) { - w.mapMutex.Lock() - r := w.m[ino] - r.refCnt-- - if r.refCnt == 0 { - delete(w.m, ino) - } - w.mapMutex.Unlock() -} - -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 -} - -func (w *wlockMap) unlock(ino uint64) { - w.mapMutex.RLock() - r := w.m[ino] - w.mapMutex.RUnlock() - r.Unlock() + // 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.Lock() + defer w.Unlock() + + r := w.inodeLocks[ino] + if r == nil { + r = &refCntMutex{} + w.inodeLocks[ino] = r + } + 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.Lock() + defer w.Unlock() + + r := w.inodeLocks[ino] + r.refCnt-- + if r.refCnt == 0 { + delete(w.inodeLocks, ino) + } +} + +// lock retrieves the entry for "ino" and locks it. +func (w *wlockMap) lock(ino uint64) { + 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.Lock() + r := w.inodeLocks[ino] + w.Unlock() + r.Unlock() +}