mutex.go 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. package graph
  2. import "sync"
  3. // imageMutex provides a lock per image id to protect shared resources in the
  4. // graph. This is only used with registration but should be used when
  5. // manipulating the layer store.
  6. type imageMutex struct {
  7. mus map[string]*sync.Mutex // mutexes by image id.
  8. mu sync.Mutex // protects lock map
  9. // NOTE(stevvooe): The map above will grow to the size of all images ever
  10. // registered during a daemon run. To free these resources, we must
  11. // deallocate after unlock. Doing this safely is non-trivial in the face
  12. // of a very minor leak.
  13. }
  14. // Lock the provided id.
  15. func (im *imageMutex) Lock(id string) {
  16. im.getImageLock(id).Lock()
  17. }
  18. // Unlock the provided id.
  19. func (im *imageMutex) Unlock(id string) {
  20. im.getImageLock(id).Unlock()
  21. }
  22. // getImageLock returns the mutex for the given id. This method will never
  23. // return nil.
  24. func (im *imageMutex) getImageLock(id string) *sync.Mutex {
  25. im.mu.Lock()
  26. defer im.mu.Unlock()
  27. if im.mus == nil { // lazy
  28. im.mus = make(map[string]*sync.Mutex)
  29. }
  30. mu, ok := im.mus[id]
  31. if !ok {
  32. mu = new(sync.Mutex)
  33. im.mus[id] = mu
  34. }
  35. return mu
  36. }