Hello, experts. Given following code as example:
package main import ( "fmt" "io" "runtime" "sync/atomic" "time" ) type S struct { foo int } var released1 atomic.Bool var released2 atomic.Bool func releaseCb(releaseFlag *atomic.Bool) { fmt.Println("release CB") releaseFlag.Store(true) } func deferredCheckRelease(goexit bool, releaseFlag *atomic.Bool) { for range 20 { runtime.GC() if releaseFlag.Load() { fmt.Println("released, cond:", goexit) return } time.Sleep(10 * time.Millisecond) } fmt.Println("not released, cond:", goexit) } func f(goexit bool, releaseFlag *atomic.Bool) { defer deferredCheckRelease(goexit, releaseFlag) s := &S{1} runtime.AddCleanup(s, releaseCb, releaseFlag) if goexit { // releaseFlag will not be set runtime.Goexit() } // releaseFlag will be set fmt.Fprint(io.Discard, s) } func main() { go f(true, &released1) go f(false, &released2) time.Sleep(time.Second) } As comment inside mentions, release flag is not set if runtime.Goexit() executed. Maybe it's because runtime.AddCleanup is not "guaranteed" to run? In such case would be great to clarify (in docs?) in which cases it might not run. People might rely on the callback... -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/golang-nuts/a0df1e83-2e25-4de2-89b5-25de4e892670n%40googlegroups.com.