-
Notifications
You must be signed in to change notification settings - Fork 17.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sync: Once keeps the function to be executed alive #55854
Comments
I don't see any way to change this. Any arbitrary call to the |
FWIW I also don't see simple ways to change this without API changes. Maybe the compiler could notice that once Or we could maybe document that if this is a concern, people should manually nil out references (as already done in e.g. some places in the standard library). Adding a |
Is it really even worth documenting as a concern? It seems intuitive to me that the argument to That is: I think that if you reason about ¹ With the possible exception of methods that are trivial to inline and unconditionally ignore their arguments. |
The current behavior is what I would expect from the current API of One way to solve this would be to change the API of // NewOnceV2 returns a new OnceV2 where f
// is called upon the first call to OnceV2.Do.
func NewOnceV2(f func()) *OnceV2
// OnceV2.Do executes the function passed to NewOnceV2 at most once.
func (*OnceV2) Do() // internal implementation drops reference to f after first call While the API could allow the function to be garbage collected, I think it has worse properties. In particular, the compiler may not be able to prove that |
It seems to me like there may be nothing we can do about this. Closing this for now, but feel free to reopen if that changes! |
The idiomatic usage of
Once.Do
keeps the function to be executed once (and everything said function transitively references) alive even after the first call toDo
has completed.As an example, on go tip this never completes, as even if the
runtime.KeepAlive
can never be reached after the first iteration, the compiler/runtime is not able to notice this fact:This is clearly not a problem specific to
sync.Once
(as it can happen in many other cases, including cases not involving function calls at all) but it is particularly visible in this case given the semantics and common use cases ofsync.Once
.I am not sure whether this is something that needs fixing, and if so whether it should be fixed in
sync
or in the compiler/runtime, or if it is just something we should document.The text was updated successfully, but these errors were encountered: