package graphdriver // import "github.com/docker/docker/daemon/graphdriver" import "sync" type minfo struct { check bool count int } // RefCounter is a generic counter for use by graphdriver Get/Put calls type RefCounter struct { counts map[string]*minfo mu sync.Mutex checker Checker } // NewRefCounter returns a new RefCounter func NewRefCounter(c Checker) *RefCounter { return &RefCounter{ checker: c, counts: make(map[string]*minfo), } } // Increment increases the ref count for the given id and returns the current count func (c *RefCounter) Increment(path string) int { return c.incdec(path, func(minfo *minfo) { minfo.count++ }) } // Decrement decreases the ref count for the given id and returns the current count func (c *RefCounter) Decrement(path string) int { return c.incdec(path, func(minfo *minfo) { minfo.count-- }) } func (c *RefCounter) incdec(path string, infoOp func(minfo *minfo)) int { c.mu.Lock() m := c.counts[path] if m == nil { m = &minfo{} c.counts[path] = m } // if we are checking this path for the first time check to make sure // if it was already mounted on the system and make sure we have a correct ref // count if it is mounted as it is in use. if !m.check { m.check = true if c.checker.IsMounted(path) { m.count++ } } infoOp(m) count := m.count if count <= 0 { delete(c.counts, path) } c.mu.Unlock() return count }