提交 431cf1c9 作者: Tommi Virtanen

Remove fsrepo refcounting

No code attempts to open the same repo multiple times.

Error handling is still buggy, but it's starting to get clearer.
上级 543adf91
package counter
import "path"
// TODO this could be made into something more generic.
type Openers struct {
// repos maps repo paths to the number of openers holding an FSRepo handle
// to it
repos map[string]int
}
func NewOpenersCounter() *Openers {
return &Openers{
repos: make(map[string]int),
}
}
// 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 *Openers) 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 *Openers) AddOpener(repoPath string) error {
l.repos[key(repoPath)]++
return nil
}
// 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 *Openers) RemoveOpener(repoPath string) error {
l.repos[key(repoPath)]--
return nil
}
func key(repoPath string) string {
return path.Clean(repoPath)
}
......@@ -14,7 +14,6 @@ import (
repo "github.com/jbenet/go-ipfs/repo"
"github.com/jbenet/go-ipfs/repo/common"
config "github.com/jbenet/go-ipfs/repo/config"
counter "github.com/jbenet/go-ipfs/repo/fsrepo/counter"
lockfile "github.com/jbenet/go-ipfs/repo/fsrepo/lock"
serialize "github.com/jbenet/go-ipfs/repo/fsrepo/serialize"
dir "github.com/jbenet/go-ipfs/thirdparty/dir"
......@@ -33,14 +32,7 @@ var (
// packageLock must be held to while performing any operation that modifies an
// FSRepo's state field. This includes Init, Open, Close, and Remove.
packageLock sync.Mutex // protects openersCounter
// openersCounter 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.
openersCounter *counter.Openers
packageLock sync.Mutex
// onlyOne keeps track of open FSRepo instances.
//
......@@ -57,10 +49,6 @@ var (
onlyOne repo.OnlyOne
)
func init() {
openersCounter = counter.NewOpenersCounter()
}
// FSRepo represents an IPFS FileSystem Repo. It is safe for use by multiple
// callers.
type FSRepo struct {
......@@ -444,27 +432,20 @@ func isInitializedUnsynced(repoPath string) bool {
// the package mutex.
func (r *FSRepo) transitionToOpened() error {
r.state = opened
if countBefore := openersCounter.NumOpeners(r.path); countBefore == 0 { // #first
closer, err := lockfile.Lock(r.path)
if err != nil {
return err
}
r.lockfile = closer
closer, err := lockfile.Lock(r.path)
if err != nil {
return err
}
return openersCounter.AddOpener(r.path)
r.lockfile = closer
return nil
}
// transitionToClosed manages the state transition to |closed|. Caller must
// hold the package mutex.
func (r *FSRepo) transitionToClosed() error {
r.state = closed
if err := openersCounter.RemoveOpener(r.path); err != nil {
if err := r.lockfile.Close(); err != nil {
return err
}
if countAfter := openersCounter.NumOpeners(r.path); countAfter == 0 {
if err := r.lockfile.Close(); err != nil {
return err
}
}
return nil
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论