summaryrefslogtreecommitdiffstats
path: root/src/util/atexit.go
blob: a22a3a96658b7bd08b7c993c0c9eb8f4b14002c0 (plain)
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
package util

import (
	"os"
	"sync"
)

var atExitFuncs []func()

// AtExit registers the function fn to be called on program termination.
// The functions will be called in reverse order they were registered.
func AtExit(fn func()) {
	if fn == nil {
		panic("AtExit called with nil func")
	}
	once := &sync.Once{}
	atExitFuncs = append(atExitFuncs, func() {
		once.Do(fn)
	})
}

// RunAtExitFuncs runs any functions registered with AtExit().
func RunAtExitFuncs() {
	fns := atExitFuncs
	for i := len(fns) - 1; i >= 0; i-- {
		fns[i]()
	}
}

// Exit executes any functions registered with AtExit() then exits the program
// with os.Exit(code).
//
// NOTE: It must be used instead of os.Exit() since calling os.Exit() terminates
// the program before any of the AtExit functions can run.
func Exit(code int) {
	defer os.Exit(code)
	RunAtExitFuncs()
}