-
Notifications
You must be signed in to change notification settings - Fork 21.6k
event, p2p/simulations/adapters: use buffered channel to avoid goroutine leak #20657
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
Conversation
fjl
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice finding!
event/subscription.go
Outdated
|
|
||
| func (s *resubscribeSub) subscribe() Subscription { | ||
| subscribed := make(chan error) | ||
| subscribed := make(chan error, 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be better to fix this case by waiting on the subscribed channel when the subscribe loop exits. This way, Unsubscribe will block until the goroutine running s.fn has exited.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I have now applied the fix myself.
| return n.Cmd.Process.Kill() | ||
| } | ||
| waitErr := make(chan error) | ||
| waitErr := make(chan error, 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This fix is OK as-is.
…0657) Co-authored-by: Felix Lange <[email protected]>
Co-authored-by: Felix Lange <[email protected]>
Co-authored-by: Felix Lange <[email protected]>
(#1541) Co-authored-by: Boqin Qin <[email protected]> Co-authored-by: Felix Lange <[email protected]>
subscribe()in event/subscribe.go andStop()in p2p/simulations/adapters/exec.go share a same problem: some goroutines in these functions will be leaked in certain cases (unsub forsubscribe(), and timeout forStop()).In
subscribe(), the send operationsubscribed <- erron L115 will be blocked forever whenunsubis selected. Thus the child goroutine leaks and always occupies the memory.Adding one buffer to the channel will make the send operation never block the child goroutine,
and it will not change semantic.
The same is true for
Stop().In
Stop(), althoughKill()is called on timeout,I am not sure if the child goroutine will be in the same process or not. Here is the annotation of
Kill(), in /os/exec.go: