Source File
hooks.go
Belonging Package
internal/runtime/exithook
// Copyright 2024 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.
// Package exithook provides limited support for on-exit cleanup.
//
// CAREFUL! The expectation is that Add should only be called
// from a safe context (e.g. not an error/panic path or signal
// handler, preemption enabled, allocation allowed, write barriers
// allowed, etc), and that the exit function F will be invoked under
// similar circumstances. That is the say, we are expecting that F
// uses normal / high-level Go code as opposed to one of the more
// restricted dialects used for the trickier parts of the runtime.
package exithook
import (
_ // for linkname
)
// A Hook is a function to be run at program termination
// (when someone invokes os.Exit, or when main.main returns).
// Hooks are run in reverse order of registration:
// the first hook added is the last one run.
type Hook struct {
F func() // func to run
RunOnFailure bool // whether to run on non-zero exit code
}
var (
locked atomic.Int32
runGoid atomic.Uint64
hooks []Hook
running bool
// runtime sets these for us
Gosched func()
Goid func() uint64
Throw func(string)
)
// Add adds a new exit hook.
func ( Hook) {
for !locked.CompareAndSwap(0, 1) {
Gosched()
}
hooks = append(hooks, )
locked.Store(0)
}
// Run runs the exit hooks.
//
// If an exit hook panics, Run will throw with the panic on the stack.
// If an exit hook invokes exit in the same goroutine, the goroutine will throw.
// If an exit hook invokes exit in another goroutine, that exit will block.
func ( int) {
for !locked.CompareAndSwap(0, 1) {
if Goid() == runGoid.Load() {
Throw("exit hook invoked exit")
}
Gosched()
}
defer locked.Store(0)
runGoid.Store(Goid())
defer runGoid.Store(0)
defer func() {
if := recover(); != nil {
Throw("exit hook invoked panic")
}
}()
for len(hooks) > 0 {
:= hooks[len(hooks)-1]
hooks = hooks[:len(hooks)-1]
if != 0 && !.RunOnFailure {
continue
}
.F()
}
}
type exitError string
func ( exitError) () string { return string() }
The pages are generated with Golds v0.7.0-preview. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds. |