From 89afdabb7e7cecfa04cb9cbb10c10001b4edc555 Mon Sep 17 00:00:00 2001 From: Brian Tiger Chow Date: Tue, 13 Jan 2015 00:34:51 -0800 Subject: [PATCH] refactor(fsrepo): move OpenerCounter --- repo/fsrepo/fsrepo.go | 35 +++++++++++----------- repo/fsrepo/{lock.go => opener/counter.go} | 16 +++++----- 2 files changed, 26 insertions(+), 25 deletions(-) rename repo/fsrepo/{lock.go => opener/counter.go} (77%) diff --git a/repo/fsrepo/fsrepo.go b/repo/fsrepo/fsrepo.go index f57acb118..1857751ef 100644 --- a/repo/fsrepo/fsrepo.go +++ b/repo/fsrepo/fsrepo.go @@ -10,23 +10,24 @@ import ( repo "github.com/jbenet/go-ipfs/repo" common "github.com/jbenet/go-ipfs/repo/common" config "github.com/jbenet/go-ipfs/repo/config" + opener "github.com/jbenet/go-ipfs/repo/fsrepo/opener" util "github.com/jbenet/go-ipfs/util" debugerror "github.com/jbenet/go-ipfs/util/debugerror" ) var ( - // pkgLock prevents the fsrepo from being removed while there exist open + // openerCounter prevents the fsrepo from being removed while there exist open // FSRepo handles. It also ensures that the Init is atomic. // // packageLock also protects numOpenedRepos // // If an operation is used when repo is Open and the operation does not // change the repo's state, the package lock does not need to be acquired. - pkgLock *packageLock + openerCounter *opener.Counter ) func init() { - pkgLock = makePackageLock() + openerCounter = opener.NewCounter() } // FSRepo represents an IPFS FileSystem Repo. It is not thread-safe. @@ -47,8 +48,8 @@ func At(path string) *FSRepo { // Init initializes a new FSRepo at the given path with the provided config. func Init(path string, conf *config.Config) error { - pkgLock.Lock() // lock must be held to ensure atomicity (prevent Removal) - defer pkgLock.Unlock() + openerCounter.Lock() // lock must be held to ensure atomicity (prevent Removal) + defer openerCounter.Unlock() if isInitializedUnsynced(path) { return nil @@ -65,9 +66,9 @@ func Init(path string, conf *config.Config) error { // Remove recursively removes the FSRepo at |path|. func Remove(path string) error { - pkgLock.Lock() - defer pkgLock.Unlock() - if pkgLock.NumOpeners(path) != 0 { + openerCounter.Lock() + defer openerCounter.Unlock() + if openerCounter.NumOpeners(path) != 0 { return errors.New("repo in use") } return os.RemoveAll(path) @@ -75,8 +76,8 @@ func Remove(path string) error { // Open returns an error if the repo is not initialized. func (r *FSRepo) Open() error { - pkgLock.Lock() - defer pkgLock.Unlock() + openerCounter.Lock() + defer openerCounter.Unlock() if r.state != unopened { return debugerror.Errorf("repo is %s", r.state) } @@ -118,7 +119,7 @@ func (r *FSRepo) Open() error { } r.state = opened - pkgLock.AddOpener(r.path) + openerCounter.AddOpener(r.path) return nil } @@ -211,12 +212,12 @@ func (r *FSRepo) SetConfigKey(key string, value interface{}) error { // Close closes the FSRepo, releasing held resources. func (r *FSRepo) Close() error { - pkgLock.Lock() - defer pkgLock.Unlock() + openerCounter.Lock() + defer openerCounter.Unlock() if r.state != opened { return debugerror.Errorf("repo is %s", r.state) } - pkgLock.RemoveOpener(r.path) + openerCounter.RemoveOpener(r.path) return nil // TODO release repo lock } @@ -225,13 +226,13 @@ var _ repo.Interface = &FSRepo{} // IsInitialized returns true if the repo is initialized at provided |path|. func IsInitialized(path string) bool { - pkgLock.Lock() - defer pkgLock.Unlock() + openerCounter.Lock() + defer openerCounter.Unlock() return isInitializedUnsynced(path) } // isInitializedUnsynced reports whether the repo is initialized. Caller must -// hold pkgLock. +// hold openerCounter lock. func isInitializedUnsynced(path string) bool { configFilename, err := config.Filename(path) if err != nil { diff --git a/repo/fsrepo/lock.go b/repo/fsrepo/opener/counter.go similarity index 77% rename from repo/fsrepo/lock.go rename to repo/fsrepo/opener/counter.go index be3653e9a..a9d034329 100644 --- a/repo/fsrepo/lock.go +++ b/repo/fsrepo/opener/counter.go @@ -5,7 +5,7 @@ import ( "sync" ) -type packageLock struct { +type Counter struct { // lock protects repos lock sync.Mutex // repos maps repo paths to the number of openers holding an FSRepo handle @@ -13,39 +13,39 @@ type packageLock struct { repos map[string]int } -func makePackageLock() *packageLock { - return &packageLock{ +func NewCounter() *Counter { + return &Counter{ repos: make(map[string]int), } } // Lock must be held to while performing any operation that modifies an // FSRepo's state field. This includes Init, Open, Close, and Remove. -func (l *packageLock) Lock() { +func (l *Counter) Lock() { l.lock.Lock() } -func (l *packageLock) Unlock() { +func (l *Counter) Unlock() { l.lock.Unlock() } // NumOpeners returns the number of FSRepos holding a handle to the repo at // this path. This method is not thread-safe. The caller must have this object // locked. -func (l *packageLock) NumOpeners(repoPath string) int { +func (l *Counter) NumOpeners(repoPath string) int { return l.repos[key(repoPath)] } // AddOpener messages that an FSRepo holds a handle to the repo at this path. // This method is not thread-safe. The caller must have this object locked. -func (l *packageLock) AddOpener(repoPath string) { +func (l *Counter) AddOpener(repoPath string) { l.repos[key(repoPath)]++ } // RemoveOpener messgaes that an FSRepo no longer holds a handle to the repo at // this path. This method is not thread-safe. The caller must have this object // locked. -func (l *packageLock) RemoveOpener(repoPath string) { +func (l *Counter) RemoveOpener(repoPath string) { l.repos[key(repoPath)]-- }