@cryptotaxi247 / kubo / commits / 89afdabb7

refactor(fsrepo): move OpenerCounter

Brian Tiger Chow committed Jan 13, 2015 at 00:34 UTC 89afdabb7e7cecfa04cb9cbb10c10001b4edc555
2 files changed +26 -25
repo/fsrepo/fsrepo.go
+18 -17
@@ -10,23 +10,24 @@ import (
10 repo "github.com/jbenet/go-ipfs/repo"
11 common "github.com/jbenet/go-ipfs/repo/common"
12 config "github.com/jbenet/go-ipfs/repo/config"
13 + opener "github.com/jbenet/go-ipfs/repo/fsrepo/opener"
14 util "github.com/jbenet/go-ipfs/util"
15 debugerror "github.com/jbenet/go-ipfs/util/debugerror"
16 )
17
18 var (
18 - // pkgLock prevents the fsrepo from being removed while there exist open
19 + // openerCounter prevents the fsrepo from being removed while there exist open
20 // FSRepo handles. It also ensures that the Init is atomic.
21 //
22 // packageLock also protects numOpenedRepos
23 //
24 // If an operation is used when repo is Open and the operation does not
25 // change the repo's state, the package lock does not need to be acquired.
25 - pkgLock *packageLock
26 + openerCounter *opener.Counter
27 )
28
29 func init() {
29 - pkgLock = makePackageLock()
30 + openerCounter = opener.NewCounter()
31 }
32
33 // FSRepo represents an IPFS FileSystem Repo. It is not thread-safe.
@@ -47,8 +48,8 @@ func At(path string) *FSRepo {
48
49 // Init initializes a new FSRepo at the given path with the provided config.
50 func Init(path string, conf *config.Config) error {
50 - pkgLock.Lock() // lock must be held to ensure atomicity (prevent Removal)
51 - defer pkgLock.Unlock()
51 + openerCounter.Lock() // lock must be held to ensure atomicity (prevent Removal)
52 + defer openerCounter.Unlock()
53
54 if isInitializedUnsynced(path) {
55 return nil
@@ -65,9 +66,9 @@ func Init(path string, conf *config.Config) error {
66
67 // Remove recursively removes the FSRepo at |path|.
68 func Remove(path string) error {
68 - pkgLock.Lock()
69 - defer pkgLock.Unlock()
70 - if pkgLock.NumOpeners(path) != 0 {
69 + openerCounter.Lock()
70 + defer openerCounter.Unlock()
71 + if openerCounter.NumOpeners(path) != 0 {
72 return errors.New("repo in use")
73 }
74 return os.RemoveAll(path)
@@ -75,8 +76,8 @@ func Remove(path string) error {
76
77 // Open returns an error if the repo is not initialized.
78 func (r *FSRepo) Open() error {
78 - pkgLock.Lock()
79 - defer pkgLock.Unlock()
79 + openerCounter.Lock()
80 + defer openerCounter.Unlock()
81 if r.state != unopened {
82 return debugerror.Errorf("repo is %s", r.state)
83 }
@@ -118,7 +119,7 @@ func (r *FSRepo) Open() error {
119 }
120
121 r.state = opened
121 - pkgLock.AddOpener(r.path)
122 + openerCounter.AddOpener(r.path)
123 return nil
124 }
125
@@ -211,12 +212,12 @@ func (r *FSRepo) SetConfigKey(key string, value interface{}) error {
212
213 // Close closes the FSRepo, releasing held resources.
214 func (r *FSRepo) Close() error {
214 - pkgLock.Lock()
215 - defer pkgLock.Unlock()
215 + openerCounter.Lock()
216 + defer openerCounter.Unlock()
217 if r.state != opened {
218 return debugerror.Errorf("repo is %s", r.state)
219 }
219 - pkgLock.RemoveOpener(r.path)
220 + openerCounter.RemoveOpener(r.path)
221 return nil // TODO release repo lock
222 }
223
@@ -225,13 +226,13 @@ var _ repo.Interface = &FSRepo{}
226
227 // IsInitialized returns true if the repo is initialized at provided |path|.
228 func IsInitialized(path string) bool {
228 - pkgLock.Lock()
229 - defer pkgLock.Unlock()
229 + openerCounter.Lock()
230 + defer openerCounter.Unlock()
231 return isInitializedUnsynced(path)
232 }
233
234 // isInitializedUnsynced reports whether the repo is initialized. Caller must
234 -// hold pkgLock.
235 +// hold openerCounter lock.
236 func isInitializedUnsynced(path string) bool {
237 configFilename, err := config.Filename(path)
238 if err != nil {
repo/fsrepo/opener/counter.go renamed
+8 -8
@@ -5,7 +5,7 @@ import (
5 "sync"
6 )
7
8 -type packageLock struct {
8 +type Counter struct {
9 // lock protects repos
10 lock sync.Mutex
11 // repos maps repo paths to the number of openers holding an FSRepo handle
@@ -13,39 +13,39 @@ type packageLock struct {
13 repos map[string]int
14 }
15
16 -func makePackageLock() *packageLock {
17 - return &packageLock{
16 +func NewCounter() *Counter {
17 + return &Counter{
18 repos: make(map[string]int),
19 }
20 }
21
22 // Lock must be held to while performing any operation that modifies an
23 // FSRepo's state field. This includes Init, Open, Close, and Remove.
24 -func (l *packageLock) Lock() {
24 +func (l *Counter) Lock() {
25 l.lock.Lock()
26 }
27
28 -func (l *packageLock) Unlock() {
28 +func (l *Counter) Unlock() {
29 l.lock.Unlock()
30 }
31
32 // NumOpeners returns the number of FSRepos holding a handle to the repo at
33 // this path. This method is not thread-safe. The caller must have this object
34 // locked.
35 -func (l *packageLock) NumOpeners(repoPath string) int {
35 +func (l *Counter) NumOpeners(repoPath string) int {
36 return l.repos[key(repoPath)]
37 }
38
39 // AddOpener messages that an FSRepo holds a handle to the repo at this path.
40 // This method is not thread-safe. The caller must have this object locked.
41 -func (l *packageLock) AddOpener(repoPath string) {
41 +func (l *Counter) AddOpener(repoPath string) {
42 l.repos[key(repoPath)]++
43 }
44
45 // RemoveOpener messgaes that an FSRepo no longer holds a handle to the repo at
46 // this path. This method is not thread-safe. The caller must have this object
47 // locked.
48 -func (l *packageLock) RemoveOpener(repoPath string) {
48 +func (l *Counter) RemoveOpener(repoPath string) {
49 l.repos[key(repoPath)]--
50 }
51