mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-21 07:55:10 +02:00
A nicer implementation of sync.Once
Doesnt require storing the result of the function in a dedicated global variable with a dedicated getter function
This commit is contained in:
35
tools/utils/once.go
Normal file
35
tools/utils/once.go
Normal file
@@ -0,0 +1,35 @@
|
||||
// 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()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user