Documentation ¶
Index ¶
- type LeveledLocker
- type LeveledMutex
- type LeveledRWMutex
- func (rw LeveledRWMutex) AssertAnyLocked(lockState *LockState)
- func (rw LeveledRWMutex) AssertLocked(lockState *LockState)
- func (rw LeveledRWMutex) AssertRLocked(lockState *LockState)
- func (rw LeveledRWMutex) AssertUnlocked(lockState *LockState)
- func (rw LeveledRWMutex) Lock(lockState *LockState)
- func (rw LeveledRWMutex) RLock(lockState *LockState)
- func (rw LeveledRWMutex) RLocker() LeveledLocker
- func (rw LeveledRWMutex) RUnlock(lockState *LockState)
- func (rw LeveledRWMutex) Unlock(lockState *LockState)
- type LockState
- type MutexLevel
- type RepeatedWaitGroup
- func (rwg *RepeatedWaitGroup) Add(delta int)
- func (rwg *RepeatedWaitGroup) Done()
- func (rwg *RepeatedWaitGroup) Pause()
- func (rwg *RepeatedWaitGroup) Resume()
- func (rwg *RepeatedWaitGroup) Wait(ctx context.Context) error
- func (rwg *RepeatedWaitGroup) WaitUnlessPaused(ctx context.Context) (bool, error)
- type Semaphore
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type LeveledLocker ¶
LeveledLocker represents an object that can be locked and unlocked with a LockState.
type LeveledMutex ¶
type LeveledMutex struct {
// contains filtered or unexported fields
}
LeveledMutex is a mutex with an associated level, which must be unique. Note that unlike sync.Mutex, LeveledMutex is a reference type and not a value type.
func MakeLeveledMutex ¶
func MakeLeveledMutex(level MutexLevel, locker sync.Locker) LeveledMutex
MakeLeveledMutex makes a mutex with the given level, backed by the given locker.
func (LeveledMutex) AssertLocked ¶
func (m LeveledMutex) AssertLocked(lockState *LockState)
AssertLocked does nothing if m is locked with respect to the given LockState. Otherwise, it panics.
func (LeveledMutex) AssertUnlocked ¶
func (m LeveledMutex) AssertUnlocked(lockState *LockState)
AssertUnlocked does nothing if m is unlocked with respect to the given LockState. Otherwise, it panics.
func (LeveledMutex) Lock ¶
func (m LeveledMutex) Lock(lockState *LockState)
Lock locks the associated locker.
func (LeveledMutex) Unlock ¶
func (m LeveledMutex) Unlock(lockState *LockState)
Unlock locks the associated locker.
type LeveledRWMutex ¶
type LeveledRWMutex struct {
// contains filtered or unexported fields
}
LeveledRWMutex is a reader-writer mutex with an associated level, which must be unique. Note that unlike sync.RWMutex, LeveledRWMutex is a reference type and not a value type.
func MakeLeveledRWMutex ¶
func MakeLeveledRWMutex(level MutexLevel, rwLocker rwLocker) LeveledRWMutex
MakeLeveledRWMutex makes a reader-writer mutex with the given level, backed by the given rwLocker.
func (LeveledRWMutex) AssertAnyLocked ¶
func (rw LeveledRWMutex) AssertAnyLocked(lockState *LockState)
AssertAnyLocked does nothing if m is locked or r-locked with respect to the given LockState. Otherwise, it panics.
func (LeveledRWMutex) AssertLocked ¶
func (rw LeveledRWMutex) AssertLocked(lockState *LockState)
AssertLocked does nothing if m is locked with respect to the given LockState. Otherwise, it panics.
func (LeveledRWMutex) AssertRLocked ¶
func (rw LeveledRWMutex) AssertRLocked(lockState *LockState)
AssertRLocked does nothing if m is r-locked with respect to the given LockState. Otherwise, it panics.
func (LeveledRWMutex) AssertUnlocked ¶
func (rw LeveledRWMutex) AssertUnlocked(lockState *LockState)
AssertUnlocked does nothing if m is unlocked with respect to the given LockState. Otherwise, it panics.
func (LeveledRWMutex) Lock ¶
func (rw LeveledRWMutex) Lock(lockState *LockState)
Lock locks the associated locker.
func (LeveledRWMutex) RLock ¶
func (rw LeveledRWMutex) RLock(lockState *LockState)
RLock locks the associated locker for reading.
func (LeveledRWMutex) RLocker ¶
func (rw LeveledRWMutex) RLocker() LeveledLocker
RLocker implements the RWMutex interface for LeveledRMMutex.
func (LeveledRWMutex) RUnlock ¶
func (rw LeveledRWMutex) RUnlock(lockState *LockState)
RUnlock unlocks the associated locker for reading.
func (LeveledRWMutex) Unlock ¶
func (rw LeveledRWMutex) Unlock(lockState *LockState)
Unlock unlocks the associated locker.
type LockState ¶
type LockState struct {
// contains filtered or unexported fields
}
LockState holds the info regarding which level mutexes are held or not for a particular execution flow.
func MakeLevelState ¶
func MakeLevelState(levelToString func(MutexLevel) string) *LockState
MakeLevelState returns a new LockState. This must be called at the start of a new execution flow and passed to any LeveledMutex or LeveledRWMutex operation during that execution flow.
TODO: Consider adding a parameter to set the capacity of exclusionStates.
type MutexLevel ¶
type MutexLevel int
MutexLevel is the level for a mutex, which must be unique to that mutex.
type RepeatedWaitGroup ¶
type RepeatedWaitGroup struct {
// contains filtered or unexported fields
}
RepeatedWaitGroup can be used in place of a sync.WaitGroup when code may need to repeatedly wait for a set of tasks to finish. (sync.WaitGroup requires special mutex usage to make this work properly, which can easily lead to deadlocks.) We use a mutex, int, and channel to track and synchronize on the number of outstanding tasks.
func (*RepeatedWaitGroup) Add ¶
func (rwg *RepeatedWaitGroup) Add(delta int)
Add indicates that a number of tasks have begun.
func (*RepeatedWaitGroup) Done ¶
func (rwg *RepeatedWaitGroup) Done()
Done indicates that one task has completed.
func (*RepeatedWaitGroup) Pause ¶
func (rwg *RepeatedWaitGroup) Pause()
Pause causes any current or future callers of `WaitUnlessPaused` to return immediately.
func (*RepeatedWaitGroup) Resume ¶
func (rwg *RepeatedWaitGroup) Resume()
Resume unpauses the wait group, allowing future callers of `WaitUnlessPaused` to wait until all the outstanding work is completed.
func (*RepeatedWaitGroup) Wait ¶
func (rwg *RepeatedWaitGroup) Wait(ctx context.Context) error
Wait blocks until either the underlying task count goes to 0, or the given context is canceled.
func (*RepeatedWaitGroup) WaitUnlessPaused ¶
func (rwg *RepeatedWaitGroup) WaitUnlessPaused(ctx context.Context) ( bool, error)
WaitUnlessPaused works like Wait, except it can return early if the wait group is paused. It returns whether it was paused with outstanding work still left in the group.
type Semaphore ¶
type Semaphore struct {
// contains filtered or unexported fields
}
Semaphore implements a counting semaphore; it maintains a resource count, and exposes methods for acquiring those resources -- waiting if desired -- and releasing those resources back.
func NewSemaphore ¶
func NewSemaphore() *Semaphore
NewSemaphore returns a new Semaphore with a resource count of 0. Use Release() to set the initial resource count.
func (*Semaphore) Acquire ¶
Acquire blocks until it is possible to atomically subtract n (which must be positive) from the resource count without causing it to go negative, and then returns the updated resource count and nil. If the given context is canceled or times out first, it instead does not change the resource count, and returns the resource count at the time it blocked (which is necessarily less than n), and a wrapped ctx.Err().
func (*Semaphore) ForceAcquire ¶
ForceAcquire atomically subtracts n (which must be positive) from the resource count without waking up any waiting acquirers. It is meant for correcting the initial resource count of the semaphore. It's okay if adding n causes the resource count goes negative, but it must not cause the resource count to underflow. The updated resource count is returned.
func (*Semaphore) Release ¶
Release atomically adds n (which must be positive) to the resource count. It must not cause the resource count to overflow. If there are waiting acquirers, it wakes up at least one of them to make progress, assuming that no new acquirers arrive in the meantime. The updated resource count is returned.
func (*Semaphore) TryAcquire ¶
TryAcquire atomically subtracts n (which must be positive) from the resource count without waking up any waiting acquirers, as long as it wouldn't go negative. If the count would go negative, it doesn't update the count but still returns the difference between the count and n. TryAcquire is successful if the return value is non-negative, and unsuccessful if the return value is negative. If the count would underflow, it panics. Otherwise, TryAcquire returns the updated resource count.