Skip to content

fix: implement IDisposable on WslConfigService to dispose FileSystemWatcher#40249

Merged
benhillis merged 2 commits intomasterfrom
copilot/fix-wslconfig-dispose
Apr 20, 2026
Merged

fix: implement IDisposable on WslConfigService to dispose FileSystemWatcher#40249
benhillis merged 2 commits intomasterfrom
copilot/fix-wslconfig-dispose

Conversation

@benhillis
Copy link
Copy Markdown
Member

Problem

\WslConfigService\ creates a \FileSystemWatcher\ but never disposes it. The existing finalizer only frees unmanaged WslConfig objects — the managed \FileSystemWatcher\ and its OS handles leak until the GC finalizes them (which is non-deterministic and not guaranteed).

Fix

Implement the standard \IDisposable\ pattern:

  • Class now implements \IDisposable\
  • \Dispose(bool)\ handles both managed (\FileSystemWatcher\) and unmanaged (\FreeWslConfig\) cleanup
  • Finalizer calls \Dispose(false)\ (skips managed objects)
  • \Dispose()\ calls \Dispose(true)\ + \GC.SuppressFinalize(this)\

This follows the standard .NET dispose pattern and ensures deterministic cleanup of the file watcher's OS handles.

…atcher

FileSystemWatcher holds unmanaged OS resources and implements
IDisposable. Without disposing it, the watcher leaks handles.
Implement the standard Dispose pattern.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 20, 2026 16:58
@benhillis benhillis requested a review from a team as a code owner April 20, 2026 16:58
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the WinUI WslConfigService (used by the Settings app via DI) to deterministically clean up its FileSystemWatcher by implementing the standard .NET IDisposable pattern, instead of relying on non-deterministic finalization.

Changes:

  • Implement IDisposable on WslConfigService.
  • Add Dispose(bool) to release managed resources (FileSystemWatcher) and unmanaged resources (FreeWslConfig), and update the finalizer to call Dispose(false).
  • Suppress finalization when Dispose() is called.

Comment thread src/windows/wslsettings/Services/WslConfigService.cs Outdated
Comment thread src/windows/wslsettings/Services/WslConfigService.cs Fixed
Copilot AI review requested due to automatic review settings April 20, 2026 18:17
@benhillis benhillis force-pushed the copilot/fix-wslconfig-dispose branch from bf7d272 to 3efbe5b Compare April 20, 2026 18:17
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 3 comments.

Comment thread src/windows/wslsettings/Services/WslConfigService.cs
Comment thread src/windows/wslsettings/Services/WslConfigService.cs
Comment thread src/windows/wslsettings/Services/WslConfigService.cs
@benhillis
Copy link
Copy Markdown
Member Author

Addressed the synchronization feedback — Dispose(bool) now takes _wslCoreConfigInterfaceLockObj before touching the watcher or config objects. Removed the _wslConfig = null\ / _wslConfigDefaults = null\ assignments since _wslConfigDefaults\ has { get; init; }\ (can't assign outside constructor). Also added unsubscribe for \Deleted\ and \Renamed\ handlers. Force-pushed the fix — initial build was failing due to the init-only property assignment.

Comment thread src/windows/wslsettings/Services/WslConfigService.cs Outdated
…atcher

Synchronize Dispose with _wslCoreConfigInterfaceLockObj to prevent racing with
OnWslConfigFileChanged/SetWslConfigSetting. Use _wslConfigFileSystemWatcher null
check instead of a separate _disposed flag so the watcher is always cleaned up
regardless of Dispose(true) vs Dispose(false) ordering.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@benhillis benhillis force-pushed the copilot/fix-wslconfig-dispose branch from 3efbe5b to 06e69b9 Compare April 20, 2026 19:00
@benhillis benhillis merged commit d367d52 into master Apr 20, 2026
9 checks passed
@benhillis benhillis deleted the copilot/fix-wslconfig-dispose branch April 23, 2026 17:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants