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 }