kitty/tools/utils/once.go
Kovid Goyal 6f4d89045a
A nicer implementation of sync.Once
Doesnt require storing the result of the function in a dedicated global
variable with a dedicated getter function
2023-02-26 08:01:02 +05:30

36 lines
568 B
Go

// License: GPLv3 Copyright: 2023, Kovid Goyal, <kovid at kovidgoyal.net>
package utils
import (
"fmt"
"sync"
"sync/atomic"
)
var _ = fmt.Print
type Once[T any] struct {
done uint32
mutex sync.Mutex
cached_val T
Run func() T
}
func (self *Once[T]) Get() T {
if atomic.LoadUint32(&self.done) == 0 {
self.do_slow()
}
return self.cached_val
}
func (self *Once[T]) do_slow() {
self.mutex.Lock()
defer self.mutex.Unlock()
if atomic.LoadUint32(&self.done) == 0 {
defer atomic.StoreUint32(&self.done, 1)
self.cached_val = self.Run()
}
}