From a8487dadeb6057418ee29b3ec8d2f1af0c91a42e Mon Sep 17 00:00:00 2001 From: Carlos Amedee Date: Mon, 6 Jan 2025 13:15:51 -0500 Subject: [PATCH] cmd/go: use runtime.AddCleanup instead of runtime.SetFinalizer Replace the usage of runtime.SetFinalizer with runtime.AddCleanup. This changes a test and how when the Go command panics when a file is left locked. Updates #70907 Change-Id: I8d8c56d16486728f9bd4b910b81796ae506bda74 Reviewed-on: https://go-review.googlesource.com/c/go/+/640736 Reviewed-by: Sam Thanawalla LUCI-TryBot-Result: Go LUCI --- src/cmd/go/internal/base/limit.go | 8 ++------ src/cmd/go/internal/lockedfile/lockedfile.go | 12 +++++++----- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/cmd/go/internal/base/limit.go b/src/cmd/go/internal/base/limit.go index b4160bde02..4317432527 100644 --- a/src/cmd/go/internal/base/limit.go +++ b/src/cmd/go/internal/base/limit.go @@ -52,7 +52,7 @@ func AcquireNet() (release func(), err error) { } checker := new(netTokenChecker) - runtime.SetFinalizer(checker, (*netTokenChecker).panicUnreleased) + cleanup := runtime.AddCleanup(checker, func(_ int) { panic("internal error: net token acquired but not released") }, 0) return func() { if checker.released { @@ -62,7 +62,7 @@ func AcquireNet() (release func(), err error) { if hasToken { <-netLimitSem } - runtime.SetFinalizer(checker, nil) + cleanup.Stop() }, nil } @@ -78,7 +78,3 @@ type netTokenChecker struct { // “tiny allocator”. unusedAvoidTinyAllocator string } - -func (c *netTokenChecker) panicUnreleased() { - panic("internal error: net token acquired but not released") -} diff --git a/src/cmd/go/internal/lockedfile/lockedfile.go b/src/cmd/go/internal/lockedfile/lockedfile.go index 82e1a89675..8bd2ffbe8f 100644 --- a/src/cmd/go/internal/lockedfile/lockedfile.go +++ b/src/cmd/go/internal/lockedfile/lockedfile.go @@ -24,6 +24,8 @@ import ( type File struct { osFile closed bool + // cleanup panics when the file is no longer referenced and it has not been closed. + cleanup runtime.Cleanup } // osFile embeds a *os.File while keeping the pointer itself unexported. @@ -48,11 +50,11 @@ func OpenFile(name string, flag int, perm fs.FileMode) (*File, error) { // Although the operating system will drop locks for open files when the go // command exits, we want to hold locks for as little time as possible, and we // especially don't want to leave a file locked after we're done with it. Our - // Close method is what releases the locks, so use a finalizer to report + // Close method is what releases the locks, so use a cleanup to report // missing Close calls on a best-effort basis. - runtime.SetFinalizer(f, func(f *File) { - panic(fmt.Sprintf("lockedfile.File %s became unreachable without a call to Close", f.Name())) - }) + f.cleanup = runtime.AddCleanup(f, func(fileName string) { + panic(fmt.Sprintf("lockedfile.File %s became unreachable without a call to Close", fileName)) + }, f.Name()) return f, nil } @@ -91,7 +93,7 @@ func (f *File) Close() error { f.closed = true err := closeFile(f.osFile.File) - runtime.SetFinalizer(f, nil) + f.cleanup.Stop() return err } -- 2.51.0