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 [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/golang-nuts/a0df1e83-2e25-4de2-89b5-25de4e892670n%40googlegroups.com.