Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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
[api] Fix memory leaks in TracerProvider.GetTracer API #4906
[api] Fix memory leaks in TracerProvider.GetTracer API #4906
Changes from 10 commits
5725dda
0bd778c
87a1bbc
31b045f
8afee1b
6d84dec
5951223
988af80
8b4895d
ca19d28
7c1ec50
404df8b
83e550b
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
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 believe we need to set
this.tracers = null
inside the same lock. Else we could still run into a situation where some thread callingDispose
setsthis.tracers
tonull
after thisif
check and before the new entry is added to the dictionary. We would want to return a no-op tracer in that case, but we would end up returning a valid tracer.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 just checked it a couple times. I think it is good! Could be I'm not seeing something though. Can you write out a flow for me that you think is flawed? Here are a couple flows I'm imagining.
Case where Dispose runs in the middle of the writer and gets the lock...
this.tracers
on Line 58. It is valid so it begins its work.this.tracers
tonull
.this.tracers == null
. This will betrue
now and it will return a no-op instance.Case where Dispose runs in the middle of the writer and waits on the lock...
this.tracers
on Line 58. It is valid so it begins its work.this.tracers == null
which isfalse
. It begins to do its work.this.tracers
tonull
.this.tracers
is now actuallynull
because it is working on a local copy.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.
For case 2,
I think this is more of design choice. Yes, it doesn't care that
this.tracers
is now actually null but it could care about it 😄.I was thinking we could offer a stronger guarantee that we would never return a
Tracer
whenTracerProvider
is disposed or being disposed. We could avoid this limbo state where the Dispose method may or may not have marked the newly returnedTracer
no-op when its being used.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 merged the PR because I think what's there will work well enough. I'll circle back to this comment when I have a sec to see if I can simplify it or clean it up in a way that doesn't introduce a bunch of contention.