/
atexit.go
45 lines (37 loc) · 1014 Bytes
/
atexit.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package process
import (
"os"
"sync"
)
var atExit struct {
sync.Mutex
f []func()
}
// AtExit registers a function to be called when `process.Exit` from this package is called.
//
// Subsequent calls to AtExit do not overwrite previous calls,
// and registered functions are executed in stack order,
// in order to mimic the behavior of `defer`.
//
// Since AtExit does not hook into the standard-library `os.Exit`,
// you must avoid using any function that calls `os.Exit` (most often `Fatal`-type logging methods).
func AtExit(f func()) {
atExit.Lock()
defer atExit.Unlock()
atExit.f = append(atExit.f, f)
}
func runExitFuncs() {
atExit.Lock()
// intentionally do not unlock.
for i := len(atExit.f) - 1; i >= 0; i-- {
atExit.f[i]()
}
}
// Exit causes the current program to exit with the given status code.
//
// Exit runs the sequence of functions established by `process.AtExit`,
// and then calls `os.Exit` with the given status.
func Exit(status int) {
runExitFuncs()
os.Exit(status)
}