Skip to content

fix: Invalidate outstanding ICU handles in Wrapper.Cleanup() - #239

Draft
imnasnainaec wants to merge 1 commit into
masterfrom
fix-237-cleanup-invalidates-handles
Draft

imnasnainaec wants to merge 1 commit into
masterfrom
fix-237-cleanup-invalidates-handles

Conversation

@imnasnainaec

@imnasnainaec imnasnainaec commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Cleanup() unloaded the ICU libraries but left every outstanding handle
pointing into the unloaded module, so using an object created before the
call dereferenced freed memory and took down the process with an
AccessViolationException that managed code cannot catch.

Objects that own a native handle now register with IcuHandleRegistry, and
Cleanup() invalidates them before unloading. Using one afterwards throws
ObjectDisposedException, and disposing one no longer calls into the
unloaded libraries. Handles that were never opened can't go stale, so
ResourceBundle.Null and not-yet-initialized break iterators keep working.

The types that already used SafeHandle (collator, transliterator,
enumerator) share a new SafeIcuHandle base, where SetHandleAsInvalid()
makes the interop marshaler do the throwing. The classes that hold a plain
IntPtr (BiDi, RuleBasedBreakIterator, RegexMatcher, MessageFormatter,
ResourceBundle, Normalizer2) hold it in a NativeHandle instead.

Fixes #237

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@imnasnainaec imnasnainaec self-assigned this Sep 21, 2026
@github-actions

Copy link
Copy Markdown

Test Results

       8 files  ±  0     656 suites  +8   10s ⏱️ -1s
   450 tests +11     446 ✔️ +11      4 💤 ±0  0 ±0 
3 688 runs  +88  3 478 ✔️ +88  210 💤 ±0  0 ±0 

Results for commit 55218e6. ± Comparison against base commit e596389.

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.

1 participant