2022-10-14 09:15:43 +00:00
|
|
|
package safety
|
|
|
|
|
|
|
|
import (
|
|
|
|
"sync/atomic"
|
|
|
|
"unsafe"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Var[T any] struct {
|
|
|
|
val T
|
|
|
|
p unsafe.Pointer
|
|
|
|
}
|
|
|
|
|
2024-06-19 08:10:42 +00:00
|
|
|
func NewVar[T any](vals ...T) *Var[T] {
|
|
|
|
var v T
|
|
|
|
if len(vals) > 0 {
|
|
|
|
v = vals[0]
|
|
|
|
}
|
|
|
|
return &Var[T]{val: v, p: unsafe.Pointer(&v)}
|
2022-10-14 09:15:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (r *Var[T]) Load() T {
|
|
|
|
return *(*T)(atomic.LoadPointer(&r.p))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *Var[T]) Delete() {
|
|
|
|
for {
|
|
|
|
px := atomic.LoadPointer(&r.p)
|
|
|
|
if atomic.CompareAndSwapPointer(&r.p, px, nil) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *Var[T]) Store(v T) {
|
|
|
|
for {
|
|
|
|
px := atomic.LoadPointer(&r.p)
|
|
|
|
if atomic.CompareAndSwapPointer(&r.p, px, unsafe.Pointer(&v)) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-02-15 16:32:02 +00:00
|
|
|
|
|
|
|
func (r *Var[T]) Flush() {
|
|
|
|
for {
|
|
|
|
px := atomic.LoadPointer(&r.p)
|
|
|
|
var v T
|
|
|
|
if atomic.CompareAndSwapPointer(&r.p, px, unsafe.Pointer(&v)) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|