storage/pkg/locker
Daniel J Walsh f39066fe1b Update packages to match latest code in moby/pkg
Had to vendor in a new version of golang.org/x/net to build
Also had to make some changes to drivers to handle
archive.Reader -> io.Reader
archive.Archive -> io.ReadCloser

Also update .gitingore to ignore emacs files, containers-storage.*
and generated man pages.

Also no longer test travis against golang 1.7, cri-o, moby have also
done this.

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
2017-09-12 18:00:29 +00:00
..
README.md Update packages to match latest code in moby/pkg 2017-09-12 18:00:29 +00:00
locker.go Update packages to match latest code in moby/pkg 2017-09-12 18:00:29 +00:00
locker_test.go Update packages to match latest code in moby/pkg 2017-09-12 18:00:29 +00:00

README.md

Locker

locker provides a mechanism for creating finer-grained locking to help free up more global locks to handle other tasks.

The implementation looks close to a sync.Mutex, however, the user must provide a reference to use to refer to the underlying lock when locking and unlocking, and unlock may generate an error.

If a lock with a given name does not exist when Lock is called, one is created. Lock references are automatically cleaned up on Unlock if nothing else is waiting for the lock.

Usage

package important

import (
	"sync"
	"time"

	"github.com/containers/storage/pkg/locker"
)

type important struct {
	locks *locker.Locker
	data  map[string]interface{}
	mu    sync.Mutex
}

func (i *important) Get(name string) interface{} {
	i.locks.Lock(name)
	defer i.locks.Unlock(name)
	return data[name]
}

func (i *important) Create(name string, data interface{}) {
	i.locks.Lock(name)
	defer i.locks.Unlock(name)

	i.createImportant(data)

	s.mu.Lock()
	i.data[name] = data
	s.mu.Unlock()
}

func (i *important) createImportant(data interface{}) {
	time.Sleep(10 * time.Second)
}

For functions dealing with a given name, always lock at the beginning of the function (or before doing anything with the underlying state), this ensures any other function that is dealing with the same name will block.

When needing to modify the underlying data, use the global lock to ensure nothing else is modifying it at the same time. Since name lock is already in place, no reads will occur while the modification is being performed.