lock

package
v0.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 1, 2022 License: MIT Imports: 2 Imported by: 0

Documentation

Overview

Package lock provides various locking utilities.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type OneTime

type OneTime struct {
	// contains filtered or unexported fields
}

OneTime is an object that can be locked exactly once.

The zero value is ready to use. A OneTime must not be copied after creation.

The use-case for this object is an alternative to the sync.Once object. sync.Once has two important downsides. First any call to .Do() does not return before the action has been performed. Second it requires a closure to be passed, resulting in additional code complexity. OneTime works around both of these by providing a single Lock() function that returns a boolean.

 type whatever struct { lock OneTime }
 func (w *whatever) DoSomethingOnlyOnce() {
		if !w.lock.Lock() { // if the action has been started elsewhere, return immediatly.
			return
		}
		// ... action to perform ...
	}
Example
// create a new onetime
onetime := &OneTime{}
var someWork uint64

var wg sync.WaitGroup
wg.Add(10)
for i := 0; i < 10; i++ {
	go func() {
		defer wg.Done()

		// if we can't lock, don't do any more work
		if !onetime.Lock() {
			return
		}

		atomic.AddUint64(&someWork, 1)
	}()
}
wg.Wait()

fmt.Println(someWork)
Output:

1

func (*OneTime) Do

func (ol *OneTime) Do(f func()) bool

Do attempts to lock ol and calls f() when successfull. Other calls to Do() or Lock() may return before f has returned.

func (*OneTime) Lock

func (ol *OneTime) Lock() bool

Lock attempts to aquire this lock and returns if it was successfull.

Only the first call to this method will return true, all subsequent calls will return false.

type WorkGroup

type WorkGroup struct {
	// contains filtered or unexported fields
}

WorkGroup is a combination of an sync.Mutex and sync.WaitGroup.

It provides both a sync.Locker and a Add() and Done() methods. When locking the locker, all calls to Add() will block until it is unlocked.

The zero value is ready to use.

Example
wg := &WorkGroup{}

// perform some work
wg.Add(1)
go func() {
	defer wg.Done()

	fmt.Println("... first set of work ...")
}()

// lock the workgroup
wg.Lock()

// schedule some work (which won't happen until Unlock() has been called.
workSched := make(chan struct{}) // closed once the work below has started
go func() {
	wg.Add(1)
	close(workSched) // work has been scheduled!

	defer wg.Done()

	fmt.Println("... second set of work ...")
}()

wg.Wait()
fmt.Println("first set of work done")
wg.Unlock()

<-workSched // wait until the work has been scheduled!

wg.Wait()
fmt.Println("second set of work done")
Output:

... first set of work ...
first set of work done
... second set of work ...
second set of work done

func (*WorkGroup) Add

func (wg *WorkGroup) Add(n int)

Add blocks until all calls to Lock() have been undone and then adds n to the underlying Waitgroup.

func (*WorkGroup) Done

func (wg *WorkGroup) Done()

Done calls Done() on the underlying WaitGroup

func (*WorkGroup) Lock

func (wg *WorkGroup) Lock()

Lock locks all WorkGroup calls and blocks future Add() calls until Unlock() is called. Only a single Lock() call is possible at the same time.

func (*WorkGroup) Unlock

func (wg *WorkGroup) Unlock()

Unlock undoes a call to Lock()

func (*WorkGroup) Wait

func (wg *WorkGroup) Wait()

Wait calls Wait() on the underlying WaitGroup. A typical use of this function is like:

wg.Lock()
defer wg.Unlock()
wg.Wait()

// perform some work that during which no new jobs are added.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL