From cdfa0beafb3942ef8a9c2c295b6de1ed4678c039 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Wed, 22 Mar 2023 10:44:47 +0000 Subject: [PATCH] lib/atexit: ensure OnError only calls cancel function once Before this change the cancelFunc could be called twice, once while handling the interrupt (CTRL-C) and once while unwinding the stack if the function happened to finish. This change ensure the cancelFunc is only called once by wrapping it in a sync.Once --- lib/atexit/atexit.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/atexit/atexit.go b/lib/atexit/atexit.go index 363d3267b..fa1dcc8b7 100644 --- a/lib/atexit/atexit.go +++ b/lib/atexit/atexit.go @@ -115,12 +115,18 @@ func Run() { // // So cancelFunc will be run if the function exits with an error or // at exit. +// +// cancelFunc will only be run once. func OnError(perr *error, fn func()) func() { - handle := Register(fn) + var once sync.Once + onceFn := func() { + once.Do(fn) + } + handle := Register(onceFn) return func() { defer Unregister(handle) if *perr != nil { - fn() + onceFn() } }