Documentation
¶
Overview ¶
Package nsync provides timed and context-aware locks, named locks, semaphores, a bounded goroutine executor, and an atomic flag with an external lock.
Acquisitions use atomic fast paths and park on condition variables, without channels. Waiters queue in arrival order; a released lock may still go to a running goroutine first, until a waiter has waited long enough to receive it directly. Timed and context-aware waits wake only the waiter that gives up.
NamedMutex keeps a lock for each string name while it is held or awaited, plus at most 129 idle locks for reuse, so its memory does not grow with the number of names ever locked. NamedOnceMutex combines overlapping operations for a comparable key and removes completed operations. Semaphore bounds concurrent acquisitions, while ControlWaitGroup bounds concurrently running functions and supports canceling pending submissions.
TryMutex, Semaphore, and ControlWaitGroup require their constructors. The zero values of NamedMutex, OnceMutex, NamedOnceMutex, and SyncFlag are usable.
Index ¶
- Variables
- type ControlWaitGroup
- func (cwg *ControlWaitGroup) Abort()
- func (cwg *ControlWaitGroup) Do(userFunc func()) bool
- func (cwg *ControlWaitGroup) DoContext(ctx context.Context, userFunc func()) error
- func (cwg *ControlWaitGroup) Wait()
- func (cwg *ControlWaitGroup) WaitContext(ctx context.Context) error
- func (cwg *ControlWaitGroup) Waiting() int
- func (cwg *ControlWaitGroup) Working() int
- type NamedMutex
- type NamedOnceMutex
- type OnceMutex
- type Semaphore
- type SyncFlag
- type TryMutex
Constants ¶
This section is empty.
Variables ¶
var ErrAborted = errors.New("nsync: control wait group aborted")
ErrAborted is returned by DoContext when the group has been aborted.
Functions ¶
This section is empty.
Types ¶
type ControlWaitGroup ¶
type ControlWaitGroup struct {
// contains filtered or unexported fields
}
ControlWaitGroup runs tasks with a limit on concurrent goroutines. Use NewControlWaitGroup to initialize it. A ControlWaitGroup must not be copied after first use.
func NewControlWaitGroup ¶
func NewControlWaitGroup(poolSize int) *ControlWaitGroup
NewControlWaitGroup creates a group. It panics unless poolSize is positive.
func (*ControlWaitGroup) Abort ¶
func (cwg *ControlWaitGroup) Abort()
Abort unblocks pending Do calls and permanently rejects new tasks. Already admitted tasks may continue running; use Wait to wait for them. Repeated calls are safe.
func (*ControlWaitGroup) Do ¶
func (cwg *ControlWaitGroup) Do(userFunc func()) bool
Do waits for a free slot and starts userFunc in a new goroutine, returning true. If the group is aborted before admission, Do returns false without running userFunc. Submission to an empty group must precede Wait.
func (*ControlWaitGroup) DoContext ¶
func (cwg *ControlWaitGroup) DoContext(ctx context.Context, userFunc func()) error
DoContext is like Do, but stops waiting for a slot when ctx is done. It returns nil once userFunc has been started, ErrAborted if the group was aborted first, or ctx.Err(). If ctx is already done, DoContext does not start userFunc.
func (*ControlWaitGroup) Wait ¶
func (cwg *ControlWaitGroup) Wait()
Wait waits for all admitted tasks and pending Do calls to finish. Submission to an empty group must precede Wait. Before reusing a group, all previous Wait calls must have returned.
func (*ControlWaitGroup) WaitContext ¶
func (cwg *ControlWaitGroup) WaitContext(ctx context.Context) error
WaitContext is like Wait, but stops waiting when ctx is done. It returns nil once the group is idle, or ctx.Err() if ctx is done first.
func (*ControlWaitGroup) Waiting ¶
func (cwg *ControlWaitGroup) Waiting() int
Waiting returns a snapshot of the number of pending Do calls.
func (*ControlWaitGroup) Working ¶
func (cwg *ControlWaitGroup) Working() int
Working returns a snapshot of the number of occupied worker slots.
type NamedMutex ¶
type NamedMutex struct {
// contains filtered or unexported fields
}
NamedMutex provides independent locks by name. The zero value is ready to use. A NamedMutex must not be copied after first use.
A name's lock exists while a goroutine holds it or waits for it; it is discarded afterwards, so memory does not grow with the number of names ever used. To keep repeated use of the same names allocation-free, an instance retains a bounded number of idle locks: one for the first name it locked, and at most one cached and one spare lock in each of its 64 shards.
func (*NamedMutex) Lock ¶
func (nm *NamedMutex) Lock(name string)
Lock acquires the named lock, creating it if necessary.
func (*NamedMutex) LockContext ¶
func (nm *NamedMutex) LockContext(ctx context.Context, name string) error
LockContext acquires the named lock, blocking until it is available or ctx is done. It returns nil once the lock is acquired, or ctx.Err() without acquiring it. If ctx is already done, LockContext does not try to acquire.
func (*NamedMutex) TryLock ¶
func (nm *NamedMutex) TryLock(name string) bool
TryLock tries to acquire the named lock without waiting.
func (*NamedMutex) TryLockTimeout ¶
func (nm *NamedMutex) TryLockTimeout(name string, timeout time.Duration) bool
TryLockTimeout tries immediately, then waits up to timeout for the named lock. A non-positive timeout is equivalent to TryLock.
func (*NamedMutex) Unlock ¶
func (nm *NamedMutex) Unlock(name string)
Unlock releases the named lock. It panics if the name is not locked.
type NamedOnceMutex ¶
type NamedOnceMutex struct {
// contains filtered or unexported fields
}
NamedOnceMutex combines overlapping operations for the same comparable key. One caller's Lock returns true; concurrent callers wait for its Unlock and return false. After Unlock, a new call may start another operation for the key. The zero value is ready to use and must not be copied after first use. Keys must be comparable and equal to themselves (NaN keys are unsupported).
func NewNamedOnceMutex ¶
func NewNamedOnceMutex() *NamedOnceMutex
NewNamedOnceMutex creates a named once mutex.
func (*NamedOnceMutex) Lock ¶
func (nom *NamedOnceMutex) Lock(key any) bool
Lock starts an operation for key, or waits for the current operation to finish. Only callers receiving true should call Unlock.
func (*NamedOnceMutex) LockContext ¶
LockContext is like Lock, but stops waiting when ctx is done. It returns (true, nil) if the caller must perform the operation and then call Unlock, (false, nil) once the operation in progress has completed, or (false, ctx.Err()) if ctx is done first. A done ctx never starts an operation.
func (*NamedOnceMutex) Unlock ¶
func (nom *NamedOnceMutex) Unlock(key any)
Unlock completes the active operation for key. Unknown keys are ignored. Only unshared entries can be recycled; a shared entry remains alive through the references held by its waiters, independently of later operations.
type OnceMutex ¶
type OnceMutex struct {
// contains filtered or unexported fields
}
OnceMutex admits one operation. The first Lock returns true; other calls wait for Unlock and return false. Its zero value is ready to use. It must not be copied after first use.
func (*OnceMutex) LockContext ¶
LockContext is like Lock, but stops waiting when ctx is done. It returns (true, nil) if the caller must perform the operation and then call Unlock, (false, nil) once another caller's operation has completed, or (false, ctx.Err()) if ctx is done first. A done ctx never starts the operation, but an already completed operation is reported as such.
type Semaphore ¶
type Semaphore struct {
// contains filtered or unexported fields
}
Semaphore limits concurrent acquisitions. Use NewSemaphore to initialize it. A Semaphore must not be copied after first use.
func NewSemaphore ¶
NewSemaphore creates a semaphore. It panics unless value is positive. Capacities above 2^58-1, or 2^26-1 (67,108,863) on 32-bit platforms, are reduced to that maximum.
func (*Semaphore) Acquire ¶
func (s *Semaphore) Acquire()
Acquire acquires a slot, blocking when all slots are occupied.
func (*Semaphore) AcquireContext ¶
AcquireContext acquires a slot, blocking until one is available or ctx is done. It returns nil once a slot is acquired, or ctx.Err() without acquiring one. If ctx is already done, AcquireContext does not try to acquire.
func (*Semaphore) Release ¶
func (s *Semaphore) Release()
Release releases a slot. It panics if no slot is occupied.
func (*Semaphore) TryAcquire ¶
TryAcquire acquires an available slot without waiting.
func (*Semaphore) TryAcquireTimeout ¶
TryAcquireTimeout tries immediately, then waits up to d for a slot. A non-positive duration is equivalent to TryAcquire.
type SyncFlag ¶
SyncFlag implements a boolean flag that can be set or unset atomically. During set/unset SyncFlag locks the mutex, so if anything needs to prevent a flag from being set/unset should acquire a lock. The zero value is unset. A SyncFlag must not be copied after first use. Set and Unset must not be called while the caller holds the embedded mutex.
type TryMutex ¶
type TryMutex struct {
// contains filtered or unexported fields
}
TryMutex provides blocking, nonblocking, timed, and context-aware lock acquisition. Use NewTryMutex to initialize it. Copies refer to the same underlying lock.
func (TryMutex) Lock ¶
func (tm TryMutex) Lock()
Lock acquires the mutex, blocking if it is already locked.
func (TryMutex) LockContext ¶
LockContext acquires the mutex, blocking until it is available or ctx is done. It returns nil once the mutex is acquired, or ctx.Err() without acquiring it. If ctx is already done, LockContext does not try to acquire.
func (TryMutex) TryLockTimeout ¶
TryLockTimeout tries immediately, then waits up to timeout for the mutex. A non-positive timeout is equivalent to TryLock.