Your value of `s` may be on the stack rather than the heap. Cleanup will
run when it goes out of scope, which is when the function returns. Your
deferred function where you're trying to check is preventing that.

You can force heap allocation, or check after the functions return.
Your two cases behave differently because of inlining making the fmt.Fprint
invocation unreachable (usually that forces it's arguments onto the heap).

- sean

On Thu, Apr 3, 2025, 18:45 Yaroslav Brustinov <y.brusti...@gmail.com> wrote:

> 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
> <https://groups.google.com/d/msgid/golang-nuts/a0df1e83-2e25-4de2-89b5-25de4e892670n%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
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/CAGabyPrHJ1OYwTWhPRQn6tiK4mMAVNhDr9sW6TCiZuziTeuFfQ%40mail.gmail.com.

Reply via email to