And as Sean pointed out, the reason it is never run is that the object being cleaned up is still referenced (I didn’t verify this)

On Apr 3, 2025, at 5:28 PM, Yaroslav Brustinov <y.brusti...@gmail.com> wrote:


I was sure the doc means the case when a program exits too quickly, before cleanup has a chance to run, or am I wrong?
Otherwise, why need to specify "not guaranteed to run before program exit."? It obviously can't run after program exits :)

In the code example above, I can wait indefinitely for cleanup to run, it will not trigger:

for range 20 { // <-- can increase this arbitrary
runtime.GC()
if releaseFlag.Load() {
fmt.Println("released, cond:", goexit)
return
}
time.Sleep(10 * time.Millisecond)
}
 

On Thursday, April 3, 2025 at 8:50:24 PM UTC+3 robert engels wrote:
It states this in the API docs:

"The cleanup(arg) call is not always guaranteed to run; in particular it is not guaranteed to run before program exit."

On Apr 3, 2025, at 10:23 AM, Yaroslav Brustinov <y.bru...@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...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/golang-nuts/a0df1e83-2e25-4de2-89b5-25de4e892670n%40googlegroups.com.

--
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/d4f12d3c-bf22-4710-bafd-2df9429cb727n%40googlegroups.com.

--
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/0477A507-EB27-4320-BC16-D773F78899F3%40ix.netcom.com.

Reply via email to