Skip to content

Fix deterministic resource lifetimes#5070

Merged
Gabriel Dufresne (GabrielDuf) merged 2 commits into
mainfrom
memory-leak-audit
Jul 10, 2026
Merged

Fix deterministic resource lifetimes#5070
Gabriel Dufresne (GabrielDuf) merged 2 commits into
mainfrom
memory-leak-audit

Conversation

@mamoreau-devolutions

@mamoreau-devolutions Marc-André Moreau (mamoreau-devolutions) commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Remove completed, faulted, and canceled task-recycler entries without retaining captured work.
  • Make package-operation cancellation await cleanup and dispose child processes, redirected streams, and retries deterministically.
  • Dispose HTTP, image, COM, and manager process resources on all request and error paths.
  • Release transient Avalonia view models from static GitHub-auth subscriptions when their controls/pages leave the visual tree.

Operation lifecycle correctness

A follow-up GPT-5.6 Sol audit traced cancellation, retry, disposal, queueing, and terminal-event interleavings in AbstractOperation. It found and fixed races that could:

  • start a retry before the canceled run had finished cleanup, allowing the old run to affect the replacement run;
  • cancel a CancellationTokenSource after concurrent completion disposed it;
  • miss cancellation between run publication and CTS creation;
  • lose a retry requested from a retried run's terminal callback;
  • start a deferred retry after disposal;
  • rewrite a completed or startup-failed operation as canceled when disposal occurred in a terminal callback;
  • let a retry-option exception poison all later retries;
  • retain a canceled operation when cancellation occurred from Enqueued while the queue was full.

Runs now publish their task and cancellation owner atomically, concurrent MainThread() calls share one active run, retries wait for prior cleanup and retain follow-up requests, and disposal prevents pending or future runs without corrupting terminal state.

Coverage

  • Faulted task recycling no longer poisons a cache key.
  • Operation tests cover cancellation cleanup, concurrent MainThread() calls, retry serialization, repeated retry callbacks, deferred-retry disposal, terminal/startup-failure disposal, retry-option failure recovery, and cancellation during queue admission.
  • Telemetry tests verify response disposal on success and failure.

Deferred follow-up

Static caches, logs, IPC output, and operation history remain unchanged. Their bounds and eviction policies will be selected only after representative UI/package workloads provide reliable dotnet-counters and GC-dump evidence.

Validation

  • dotnet test UniGetUI.Windows.slnx --no-restore --verbosity q --nologo /p:Platform=x64 -m:1
  • Package-operation lifecycle tests pass on both net10.0 and net10.0-windows10.0.26100.0.

Dispose HTTP, process, COM, image, task, and UI subscription resources deterministically; add cancellation and lifetime regression coverage.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Prevent cancellation, retry, and disposal races from overlapping operation runs or corrupting terminal state. Add focused regression coverage for cleanup ordering, repeated retries, startup failures, queue cancellation, and disposal boundaries.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@GabrielDuf Gabriel Dufresne (GabrielDuf) merged commit 6ef60b4 into main Jul 10, 2026
5 checks passed
@GabrielDuf Gabriel Dufresne (GabrielDuf) deleted the memory-leak-audit branch July 10, 2026 19:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants