libct/utils: use sync.OnceValue

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
Kir Kolyshkin
2026-04-23 11:22:40 -07:00
parent 2ae07a45d6
commit 8d1ebab374
+12 -25
View File
@@ -18,17 +18,11 @@ import (
"github.com/opencontainers/runc/internal/pathrs" "github.com/opencontainers/runc/internal/pathrs"
) )
var ( var haveCloseRangeCloexec = sync.OnceValue(func() bool {
haveCloseRangeCloexecBool bool
haveCloseRangeCloexecOnce sync.Once
)
func haveCloseRangeCloexec() bool {
haveCloseRangeCloexecOnce.Do(func() {
// Make sure we're not closing a random file descriptor. // Make sure we're not closing a random file descriptor.
tmpFd, err := unix.FcntlInt(0, unix.F_DUPFD_CLOEXEC, 0) tmpFd, err := unix.FcntlInt(0, unix.F_DUPFD_CLOEXEC, 0)
if err != nil { if err != nil {
return return false
} }
defer unix.Close(tmpFd) defer unix.Close(tmpFd)
@@ -37,10 +31,8 @@ func haveCloseRangeCloexec() bool {
// -ENOSYS and -EINVAL ultimately mean we don't have support, but any // -ENOSYS and -EINVAL ultimately mean we don't have support, but any
// other potential error would imply that even the most basic close // other potential error would imply that even the most basic close
// operation wouldn't work. // operation wouldn't work.
haveCloseRangeCloexecBool = err == nil return err == nil
}) })
return haveCloseRangeCloexecBool
}
type fdFunc func(fd int) type fdFunc func(fd int)
@@ -162,10 +154,13 @@ func WithProcfdFile(file *os.File, fn func(procfd string) error) error {
type ProcThreadSelfCloser func() type ProcThreadSelfCloser func()
var ( var haveProcThreadSelf = sync.OnceValue(func() bool {
haveProcThreadSelf bool if _, err := os.Stat("/proc/thread-self/"); err != nil {
haveProcThreadSelfOnce sync.Once logrus.Debugf("cannot stat /proc/thread-self (%v), falling back to /proc/self/task/<tid>", err)
) return false
}
return true
})
// ProcThreadSelf returns a string that is equivalent to // ProcThreadSelf returns a string that is equivalent to
// /proc/thread-self/<subpath>, with a graceful fallback on older kernels where // /proc/thread-self/<subpath>, with a graceful fallback on older kernels where
@@ -174,14 +169,6 @@ var (
// the returned procThreadSelfCloser function (which is runtime.UnlockOSThread) // the returned procThreadSelfCloser function (which is runtime.UnlockOSThread)
// *only once* after it has finished using the returned path string. // *only once* after it has finished using the returned path string.
func ProcThreadSelf(subpath string) (string, ProcThreadSelfCloser) { func ProcThreadSelf(subpath string) (string, ProcThreadSelfCloser) {
haveProcThreadSelfOnce.Do(func() {
if _, err := os.Stat("/proc/thread-self/"); err == nil {
haveProcThreadSelf = true
} else {
logrus.Debugf("cannot stat /proc/thread-self (%v), falling back to /proc/self/task/<tid>", err)
}
})
// We need to lock our thread until the caller is done with the path string // We need to lock our thread until the caller is done with the path string
// because any non-atomic operation on the path (such as opening a file, // because any non-atomic operation on the path (such as opening a file,
// then reading it) could be interrupted by the Go runtime where the // then reading it) could be interrupted by the Go runtime where the
@@ -196,7 +183,7 @@ func ProcThreadSelf(subpath string) (string, ProcThreadSelfCloser) {
runtime.LockOSThread() runtime.LockOSThread()
threadSelf := "/proc/thread-self/" threadSelf := "/proc/thread-self/"
if !haveProcThreadSelf { if !haveProcThreadSelf() {
// Pre-3.17 kernels did not have /proc/thread-self, so do it manually. // Pre-3.17 kernels did not have /proc/thread-self, so do it manually.
threadSelf = "/proc/self/task/" + strconv.Itoa(unix.Gettid()) + "/" threadSelf = "/proc/self/task/" + strconv.Itoa(unix.Gettid()) + "/"
if _, err := os.Stat(threadSelf); err != nil { if _, err := os.Stat(threadSelf); err != nil {