giteabot backport / giteabot (push) Canceled after 0s
giteabot / giteabot (push) Canceled after 0s
release-nightly / nightly-binary (push) Canceled after 0s
release-nightly / nightly-container (push) Canceled after 0s
cache-seeder / gobuild (push) Canceled after 0s
cache-seeder / lint (bindata, lint-backend) (push) Canceled after 0s
release-nightly-snapcraft / build-and-publish (push) Canceled after 0s
Includes direct password setup links in registration emails. Assisted-by: Codex:GPT-5
52 lines
868 B
Go
52 lines
868 B
Go
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package util
|
|
|
|
import (
|
|
"sync"
|
|
"sync/atomic"
|
|
)
|
|
|
|
type onceValueResult[T any] struct {
|
|
value T
|
|
panic any
|
|
}
|
|
|
|
// OnceValue is similar to Golang's "sync.OnceValue", but can be reset.
|
|
type OnceValue[T any] struct {
|
|
Func func() T
|
|
mu sync.Mutex
|
|
res atomic.Pointer[onceValueResult[T]]
|
|
}
|
|
|
|
func (o *OnceValue[T]) Value() T {
|
|
res := o.res.Load()
|
|
if res == nil {
|
|
o.mu.Lock()
|
|
defer o.mu.Unlock()
|
|
res = o.res.Load()
|
|
if res == nil {
|
|
res = &onceValueResult[T]{}
|
|
defer func() {
|
|
res.panic = recover()
|
|
o.res.Store(res)
|
|
if res.panic != nil {
|
|
panic(res.panic)
|
|
}
|
|
}()
|
|
res.value = o.Func()
|
|
}
|
|
}
|
|
if res.panic != nil {
|
|
panic(res.panic)
|
|
}
|
|
return res.value
|
|
}
|
|
|
|
func (o *OnceValue[T]) Reset() {
|
|
o.mu.Lock()
|
|
defer o.mu.Unlock()
|
|
o.res.Store(nil)
|
|
}
|