diff --git a/sync/locker.go b/sync/locker.go new file mode 100644 index 0000000..ff691da --- /dev/null +++ b/sync/locker.go @@ -0,0 +1,36 @@ +package usync + +import "sync" + +// Locker guards access to a value +type Locker[T any] struct { + value T + mutex sync.Mutex +} + +// NewLocker creates a new locker with the specified value. +func NewLocker[T any] (value T) Locker[T] { + return Locker[T] { + value: value, + } +} + +// Set sets the value of the locker. +func (this *Locker[T]) Set (value T) { + this.mutex.Lock() + defer this.mutex.Unlock() + this.value = value +} + +// Borrow borrows the value from the locker, and returns a function that must +// immediately be deferred, like this: +// +// value, done := locker.Borrow() +// defer done() +// +// From the time Borrow is called to the time the done function is called, it is +// safe to access the locked object from within the current goroutine. +func (this *Locker[T]) Borrow () (T, func ()) { + this.mutex.Lock() + return this.value, this.mutex.Unlock +}