-
Notifications
You must be signed in to change notification settings - Fork 65
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e422e3d
commit 7beca62
Showing
3 changed files
with
165 additions
and
87 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
//go:build go1.21 | ||
|
||
package common | ||
|
||
import "sync" | ||
|
||
func OnceFunc(f func()) func() { | ||
return sync.OnceFunc(f) | ||
} | ||
|
||
func OnceValue[T any](f func() T) func() T { | ||
return sync.OnceValue(f) | ||
} | ||
|
||
func OnceValues[T1, T2 any](f func() (T1, T2)) func() (T1, T2) { | ||
return sync.OnceValues(f) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
//go:build !go1.21 | ||
|
||
// Copyright 2022 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
// copied from go1.22.5 | ||
|
||
package common | ||
|
||
import "sync" | ||
|
||
// OnceFunc returns a function that invokes f only once. The returned function | ||
// may be called concurrently. | ||
// | ||
// If f panics, the returned function will panic with the same value on every call. | ||
func OnceFunc(f func()) func() { | ||
var ( | ||
once sync.Once | ||
valid bool | ||
p any | ||
) | ||
// Construct the inner closure just once to reduce costs on the fast path. | ||
g := func() { | ||
defer func() { | ||
p = recover() | ||
if !valid { | ||
// Re-panic immediately so on the first call the user gets a | ||
// complete stack trace into f. | ||
panic(p) | ||
} | ||
}() | ||
f() | ||
f = nil // Do not keep f alive after invoking it. | ||
valid = true // Set only if f does not panic. | ||
} | ||
return func() { | ||
once.Do(g) | ||
if !valid { | ||
panic(p) | ||
} | ||
} | ||
} | ||
|
||
// OnceValue returns a function that invokes f only once and returns the value | ||
// returned by f. The returned function may be called concurrently. | ||
// | ||
// If f panics, the returned function will panic with the same value on every call. | ||
func OnceValue[T any](f func() T) func() T { | ||
var ( | ||
once sync.Once | ||
valid bool | ||
p any | ||
result T | ||
) | ||
g := func() { | ||
defer func() { | ||
p = recover() | ||
if !valid { | ||
panic(p) | ||
} | ||
}() | ||
result = f() | ||
f = nil | ||
valid = true | ||
} | ||
return func() T { | ||
once.Do(g) | ||
if !valid { | ||
panic(p) | ||
} | ||
return result | ||
} | ||
} | ||
|
||
// OnceValues returns a function that invokes f only once and returns the values | ||
// returned by f. The returned function may be called concurrently. | ||
// | ||
// If f panics, the returned function will panic with the same value on every call. | ||
func OnceValues[T1, T2 any](f func() (T1, T2)) func() (T1, T2) { | ||
var ( | ||
once sync.Once | ||
valid bool | ||
p any | ||
r1 T1 | ||
r2 T2 | ||
) | ||
g := func() { | ||
defer func() { | ||
p = recover() | ||
if !valid { | ||
panic(p) | ||
} | ||
}() | ||
r1, r2 = f() | ||
f = nil | ||
valid = true | ||
} | ||
return func() (T1, T2) { | ||
once.Do(g) | ||
if !valid { | ||
panic(p) | ||
} | ||
return r1, r2 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters