-
Notifications
You must be signed in to change notification settings - Fork 0
Refactor UdpSourceBase to use proper Dispose pattern #7
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
Changes from all commits
a857b78
a2446cb
6d5b8e1
50797a7
11d98ff
d3c5fe4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -9,6 +9,8 @@ namespace GamesDat.Core.Telemetry.Sources | |||||
| { | ||||||
| public abstract class UdpSourceBase<T> : TelemetrySourceBase<T> | ||||||
| { | ||||||
| private readonly object _disposeLock = new object(); | ||||||
| private bool _disposed; | ||||||
|
|
||||||
| protected UdpClient _listener; | ||||||
| protected IPEndPoint _endpoint; | ||||||
|
|
@@ -45,7 +47,25 @@ public override async IAsyncEnumerable<T> ReadContinuousAsync([EnumeratorCancell | |||||
| finally | ||||||
| { | ||||||
| _isListening = false; | ||||||
| _listener.Dispose(); | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| public override void Dispose() | ||||||
| { | ||||||
| lock (_disposeLock) | ||||||
|
||||||
| { | ||||||
| if (!_disposed) | ||||||
| { | ||||||
| _disposed = true; | ||||||
| try | ||||||
| { | ||||||
| _listener?.Dispose(); | ||||||
|
||||||
| _listener?.Dispose(); | |
| _listener.Dispose(); |
Copilot
AI
Feb 10, 2026
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.
Potential double-disposal issue: With the current implementation, if ReadContinuousAsync completes normally and then Dispose() is called, _listener will be disposed twice - once in the new Dispose() override (line 62) and potentially again if the pattern in the documentation is followed where finally blocks also dispose resources.
Additionally, this conflicts with the planned API refactoring documented in docs/telemetry-source-api-refactoring.md (lines 97-153), which shows that _listener.Dispose() should remain in the finally block even after the refactoring. The current change makes that future refactoring more complex.
UdpClient.Dispose() is idempotent (can be called multiple times safely), but this pattern is still confusing and unnecessary.
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.
The _disposed flag check doesn't prevent ReadContinuousAsync from using a disposed _listener. If Dispose() is called while ReadContinuousAsync is running, the _disposed flag will be set to true, but the running async method will continue to attempt to use _listener on line 38, which has just been disposed on line 62.
There's no check of the _disposed flag before or during ReadContinuousAsync execution. Consider adding a check at the start of ReadContinuousAsync to throw ObjectDisposedException if already disposed, and potentially in the while loop to exit gracefully if disposal occurs during iteration.