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.

Reply via email to