Skip to content

Fix concurrent parenthesis index crash and duplicate shutdown handler - #189

Merged
magicbug merged 1 commit into
mainfrom
cursor/satellite-catalog-threadsafe-9f66
Oct 27, 2026
Merged

magicbug merged 1 commit into
mainfrom
cursor/satellite-catalog-threadsafe-9f66

Conversation

@magicbug

Copy link
Copy Markdown
Owner

Summary

Fixes the v1.1.4 fatal crash from Carlos’s log (InvalidOperationException in SatelliteCatalogMatching.GetOrBuildParenthesisIndex at 17:37:31 +01:00), plus a duplicate ShutdownRequested shutdown crash seen at 20:26:00.

Root cause (catalog matching)

GetOrBuildParenthesisIndex kept a static Dictionary and rebuilt it in place with no synchronisation. TleService.GetEnabledSatellites allocates a new HashSet on every call, so the reference-equality cache almost never hits and many threads rebuild at once (live tracking worker, UI status refresh, satellite picker, sunlight prediction, etc.). Interleaved writers could mutate the same dictionary instance and trigger the runtime’s “exclusive access” failure.

Fix

  • Build the index into a local dictionary under a lock, then publish it to the static cache (same reference-equality semantics as before).
  • Add SatelliteCatalogMatchingConcurrencyTests (16 threads × 500 iterations, fresh name sets per call).
  • Live tracking worker: log unexpected iteration failures and continue instead of terminating the process via an unhandled background-thread exception.
  • Shutdown: run disconnect / flush handlers only once; catch ObjectDisposedException if the service provider is already torn down (Avalonia fired ShutdownRequested twice in the attached log).

Docs (IC-9700 CI-V address)

Operator docs for https://oscarwatch.org/docs are not in this repository (they live in the OscarWatch website repo per project rules). This tracker repo already documents the correct default (A2) in RigSettings.DefaultCivAddressFor and Settings.Radio.CivHint. No doc change here; the Icom page on the site should be corrected separately.

Test plan

  • dotnet build OscarWatch.slnx -c Release
  • dotnet test OscarWatch.Tests/OscarWatch.Tests.csproj -c Release (3398 passed, including new concurrency test)
Open in Web Open in Cursor 

Serialise GetOrBuildParenthesisIndex so concurrent UI and live-tracking
workers cannot corrupt the static dictionary. Add a concurrent stress test,
log and continue on live-tracking worker failures, and run desktop shutdown
handlers only once when Avalonia fires duplicate ShutdownRequested events.
@magicbug
magicbug merged commit 0cd0816 into main Oct 27, 2026
9 checks passed
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.

2 participants