2015-10-19 16:43:56 -04:00
|
|
|
Locker
|
|
|
|
=====
|
|
|
|
|
|
|
|
locker provides a mechanism for creating finer-grained locking to help
|
|
|
|
free up more global locks to handle other tasks.
|
|
|
|
|
2016-12-25 23:49:37 -05:00
|
|
|
The implementation looks close to a sync.Mutex, however, the user must provide a
|
2015-10-19 16:43:56 -04:00
|
|
|
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
|
|
|
|
|
|
|
|
```go
|
|
|
|
package important
|
|
|
|
|
|
|
|
import (
|
|
|
|
"sync"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/docker/docker/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)
|
2017-09-10 05:33:08 -04:00
|
|
|
return i.data[name]
|
2015-10-19 16:43:56 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
func (i *important) Create(name string, data interface{}) {
|
|
|
|
i.locks.Lock(name)
|
|
|
|
defer i.locks.Unlock(name)
|
|
|
|
|
2015-11-14 17:44:18 -05:00
|
|
|
i.createImportant(data)
|
2015-10-19 16:43:56 -04:00
|
|
|
|
2017-09-10 05:33:08 -04:00
|
|
|
i.mu.Lock()
|
2015-10-19 16:43:56 -04:00
|
|
|
i.data[name] = data
|
2017-09-10 05:33:08 -04:00
|
|
|
i.mu.Unlock()
|
2015-10-19 16:43:56 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
2016-12-20 22:03:39 -05:00
|
|
|
else is modifying it at the same time.
|
2015-10-19 16:43:56 -04:00
|
|
|
Since name lock is already in place, no reads will occur while the modification
|
|
|
|
is being performed.
|
|
|
|
|