9
// Mutex holds a single mutex and whether it has been allocated.
16
// ID retrieves the ID of the mutex
17
func (m *Mutex) ID() uint32 {
21
// Lock locks the mutex
22
func (m *Mutex) Lock() {
26
// Unlock unlocks the mutex
27
func (m *Mutex) Unlock() {
31
// Free deallocates the mutex to allow its reuse
32
func (m *Mutex) Free() error {
38
// InMemoryManager is a lock manager that allocates and retrieves local-only
39
// locks - that is, they are not multiprocess. This lock manager is intended
40
// purely for unit and integration testing and should not be used in production
42
type InMemoryManager struct {
48
// NewInMemoryManager creates a new in-memory lock manager with the given number
50
func NewInMemoryManager(numLocks uint32) (Manager, error) {
52
return nil, errors.New("must provide a non-zero number of locks")
55
manager := new(InMemoryManager)
56
manager.numLocks = numLocks
57
manager.locks = make([]*Mutex, numLocks)
60
for i = 0; i < numLocks; i++ {
63
manager.locks[i] = lock
69
// AllocateLock allocates a lock from the manager.
70
func (m *InMemoryManager) AllocateLock() (Locker, error) {
72
defer m.localLock.Unlock()
74
for _, lock := range m.locks {
81
return nil, errors.New("all locks have been allocated")
84
// RetrieveLock retrieves a lock from the manager.
85
func (m *InMemoryManager) RetrieveLock(id uint32) (Locker, error) {
87
return nil, fmt.Errorf("given lock ID %d is too large - this manager only supports lock indexes up to %d", id, m.numLocks-1)
90
return m.locks[id], nil
93
// AllocateAndRetrieveLock allocates a lock with the given ID (if not already in
94
// use) and returns it.
95
func (m *InMemoryManager) AllocateAndRetrieveLock(id uint32) (Locker, error) {
97
return nil, fmt.Errorf("given lock ID %d is too large - this manager only supports lock indexes up to %d", id, m.numLocks)
100
if m.locks[id].allocated {
101
return nil, fmt.Errorf("given lock ID %d is already in use, cannot reallocate", id)
104
m.locks[id].allocated = true
106
return m.locks[id], nil
109
// FreeAllLocks frees all locks.
110
// This function is DANGEROUS. Please read the full comment in locks.go before
112
func (m *InMemoryManager) FreeAllLocks() error {
113
for _, lock := range m.locks {
114
lock.allocated = false
120
// Get number of available locks
121
func (m *InMemoryManager) AvailableLocks() (*uint32, error) {
124
for _, lock := range m.locks {
133
// Get any locks that are presently being held.
134
// Useful for debugging deadlocks.
135
func (m *InMemoryManager) LocksHeld() ([]uint32, error) {
139
for _, lock := range m.locks {
140
if lock.lock.TryLock() {
144
locks = append(locks, lock.ID())