counter.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. package graphdriver // import "github.com/docker/docker/daemon/graphdriver"
  2. import "sync"
  3. type minfo struct {
  4. check bool
  5. count int
  6. }
  7. // RefCounter is a generic counter for use by graphdriver Get/Put calls
  8. type RefCounter struct {
  9. counts map[string]*minfo
  10. mu sync.Mutex
  11. checker Checker
  12. }
  13. // NewRefCounter returns a new RefCounter
  14. func NewRefCounter(c Checker) *RefCounter {
  15. return &RefCounter{
  16. checker: c,
  17. counts: make(map[string]*minfo),
  18. }
  19. }
  20. // Increment increases the ref count for the given id and returns the current count
  21. func (c *RefCounter) Increment(path string) int {
  22. return c.incdec(path, func(minfo *minfo) {
  23. minfo.count++
  24. })
  25. }
  26. // Decrement decreases the ref count for the given id and returns the current count
  27. func (c *RefCounter) Decrement(path string) int {
  28. return c.incdec(path, func(minfo *minfo) {
  29. minfo.count--
  30. })
  31. }
  32. func (c *RefCounter) incdec(path string, infoOp func(minfo *minfo)) int {
  33. c.mu.Lock()
  34. m := c.counts[path]
  35. if m == nil {
  36. m = &minfo{}
  37. c.counts[path] = m
  38. }
  39. // if we are checking this path for the first time check to make sure
  40. // if it was already mounted on the system and make sure we have a correct ref
  41. // count if it is mounted as it is in use.
  42. if !m.check {
  43. m.check = true
  44. if c.checker.IsMounted(path) {
  45. m.count++
  46. }
  47. }
  48. infoOp(m)
  49. count := m.count
  50. if count <= 0 {
  51. delete(c.counts, path)
  52. }
  53. c.mu.Unlock()
  54. return count
  55. }