v.io: v.io/x/ref/runtime/internal/lib/sync Index | Files

package sync

import "v.io/x/ref/runtime/internal/lib/sync"

Package sync provides synchronization primitives.


Package Files

doc.go lock.go semaphore.go wait_group.go


var (
    ErrClosed   = errors.New("semaphore is closed")
    ErrCanceled = errors.New("semaphore operation was canceled")
    ErrTryAgain = errors.New("semaphore operation failed, try again")

type DebugMutex Uses

type DebugMutex struct {
    // contains filtered or unexported fields

DebugMutex supports checking whether a mutex is locked.

func (*DebugMutex) CheckLocked Uses

func (m *DebugMutex) CheckLocked()

CheckLocked panics if the lock is not held.

func (*DebugMutex) Lock Uses

func (m *DebugMutex) Lock()

func (*DebugMutex) Unlock Uses

func (m *DebugMutex) Unlock()

type Semaphore Uses

type Semaphore struct {
    // contains filtered or unexported fields

Semaphore is an implementation of unbounded semaphores. Abstractly, a semaphore holds a nonnegative integer value, and supports operations to increment and decrement the value. The semaphore value is not allowed to be negative; decrement operations block until the semaphore value is positive. http://en.wikipedia.org/wiki/Semaphore_%28programming%29

The standard suggestion for implementing semaphores in Go is to use a buffered channel, where the number of elements in the channel is the max value of the semaphore. However, what we implement here is _unbounded_ semaphores (up to a max value of 2^31-1).

A mutex and integer is used to keep track of the numerical value of the and a channel is used for notification of changes. When decrementing, the value of the semaphore is decremented and if not sufficient, DecN will block until it can subtract more.

Because of this looping, the semaphore is not fair. The reason for using a channel for notifications is for cancellation. The Dec(cancel <-chan struct{}) method takes a cancelation channel, so we use a "select" operation to determine whether to perform a semaphore operation or abort because the semaphore is close or the operation was canceled.

NOTE: when the Semaphore is closed, the Dec (or DecN) operations are unblocked, returning an error (ErrClosed) if the semaphore value is 0 (or less than the DecN value), respectively. However, even with the Semaphore closed, if the semaphore value is non-zero (or sufficient to satisfy the DecN value), Dec (or DecN) performs the decrement successfully and returns without an error. Regardless of whether the Semaphore is closed or not, Inc/IncN succeed in incrementing the semaphore value.

func NewSemaphore Uses

func NewSemaphore() *Semaphore

NewSemaphore allocates a semaphore with an initial value.

func (*Semaphore) Close Uses

func (s *Semaphore) Close()

Close closes the semaphore. Subsequent operations do not block.

func (*Semaphore) Dec Uses

func (s *Semaphore) Dec(cancel <-chan struct{}) error

Dec decrements the semaphore by 1.

func (*Semaphore) DecN Uses

func (s *Semaphore) DecN(n uint, cancel <-chan struct{}) error

DecN decrements the semaphore. Blocks until the final value of the semaphore is nonnegative, or the <cancel> channel is closed (or has a value).

func (*Semaphore) Inc Uses

func (s *Semaphore) Inc()

Inc increments the semaphore by 1.

func (*Semaphore) IncN Uses

func (s *Semaphore) IncN(n uint)

IncN increments the semaphore. Wakes any potential waiters.

func (*Semaphore) TryDec Uses

func (s *Semaphore) TryDec() error

TryDec tries to decrement the semaphore by 1.

func (*Semaphore) TryDecN Uses

func (s *Semaphore) TryDecN(n uint) error

TryDecN tries to decrement the semaphore.

type WaitGroup Uses

type WaitGroup struct {
    // contains filtered or unexported fields

WaitGroup implements a sync.WaitGroup-like structure that does not require all calls to Add to be made before Wait, instead calls to Add after Wait will fail.

As a result, WaitGroup cannot be "re-used" in the way that sync.WaitGroup can. In the following example using sync.WaitGroup, Add, Done and Wait behave in the same way in rounds 1 and 2.

var wg sync.WaitGroup

Round #1. wg.Add(1) go wg.Done() wg.Wait()

Round #2. wg.Add(1) go wg.Done() wg.Wait()

However, an equivalent program using WaitGroup would receive an error on the second call to TryAdd.

func (*WaitGroup) Done Uses

func (w *WaitGroup) Done()

Done decrements the counter. If the counter goes negative, Done panics.

func (*WaitGroup) TryAdd Uses

func (w *WaitGroup) TryAdd() (added bool)

TryAdd attempts to increment the counter. If Wait has already been called, TryAdd fails to increment the counter and returns false. If the counter becomes zero, all goroutines blocked on Wait are released.

func (*WaitGroup) Wait Uses

func (w *WaitGroup) Wait()

Wait blocks until the counter is zero.

Package sync imports 2 packages (graph) and is imported by 1 packages. Updated 2020-10-04. Refresh now. Tools for package owners.