mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-11 06:03:57 +08:00
libct/utils: use sync.OnceValue
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user