- Fix thread join in DynamicStore CFRunLoop stream: unsubscribe now waits
on a DispatchSemaphore (threadDone) signalled after CFRunLoopRun() exits,
guaranteeing the run-loop thread cannot access the Rust sender box after
Drop frees it (was: CFRunLoopStop + CFRunLoopWakeUp with no join)
- Add panic safety to all three async extern "C" callbacks
(dynamic_store_async_cb, reachability_async_cb, preferences_async_cb)
via doom_fish_utils::panic_safe::catch_user_panic; panics crossing the
Swift/C FFI boundary are undefined behaviour
- Add panic safety to synchronous dynamic_store_callback via
std::panic::catch_unwind(AssertUnwindSafe(...))
- Add SAFETY comments to all ctx/info pointer dereferences in the four
extern "C" callback functions
- Document the ownership invariants on unsafe impl Send/Sync for
SubscriptionHandle
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>