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