graph/mutex.go
7eac23cf
 package graph
 
 import "sync"
 
 // imageMutex provides a lock per image id to protect shared resources in the
 // graph. This is only used with registration but should be used when
 // manipulating the layer store.
 type imageMutex struct {
 	mus map[string]*sync.Mutex // mutexes by image id.
 	mu  sync.Mutex             // protects lock map
 
 	// NOTE(stevvooe): The map above will grow to the size of all images ever
 	// registered during a daemon run. To free these resources, we must
 	// deallocate after unlock. Doing this safely is non-trivial in the face
 	// of a very minor leak.
 }
 
 // Lock the provided id.
 func (im *imageMutex) Lock(id string) {
 	im.getImageLock(id).Lock()
 }
 
 // Unlock the provided id.
 func (im *imageMutex) Unlock(id string) {
 	im.getImageLock(id).Unlock()
 }
 
 // getImageLock returns the mutex for the given id. This method will never
 // return nil.
 func (im *imageMutex) getImageLock(id string) *sync.Mutex {
 	im.mu.Lock()
 	defer im.mu.Unlock()
 
 	if im.mus == nil { // lazy
 		im.mus = make(map[string]*sync.Mutex)
 	}
 
 	mu, ok := im.mus[id]
 	if !ok {
 		mu = new(sync.Mutex)
 		im.mus[id] = mu
 	}
 
 	return mu
 }