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)
}