github.com/puellanivis/breton@v0.2.16/lib/os/process/atexit.go (about)

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