aboutsummaryrefslogtreecommitdiff
path: root/CHANGELOG.md
diff options
context:
space:
mode:
Diffstat (limited to 'CHANGELOG.md')
-rw-r--r--CHANGELOG.md14
1 files changed, 14 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7cbe748..c7f0250 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -115,6 +115,20 @@ None
These changes fix incorrect word-index computation and avoid sending empty option values to the underlying completion engine from PowerShell completions.
+10. **[`core:resources`]** Refactored the global resource storage from a single type-erased `Arc<Mutex<HashMap<...>>>` container into a standalone `GlobalResContainer` struct with per-resource mutexes.
+
+ Previously, `GlobalResources` was a type alias for `Arc<Mutex<HashMap<TypeId, Box<dyn Any + Sync + Send>>>>`, and the resource methods (`with_resource`, `modify_res`, `__modify_res_and_return_route`, `__extract_res_mut`, `__store_res`, `res`, `res_or_route`, `res_or_default`) were implemented directly on `Program`. Now:
+
+ - **`GlobalResContainer`** — A new public struct owning the resource map (`map: Mutex<HashMap<TypeId, Box<dyn Any + Send + Sync>>>`), with `new()` and `Default` impls. Each resource entry is stored as `Arc<Mutex<Arc<Res>>>` — the outer `Mutex` guards the entry itself (so a resource can be locked without holding the container lock), and the inner `Arc<Res>` is the shared immutable snapshot returned by `res()`.
+ - **Per-resource mutex** — The container lock is only held for the brief lookup/clone of the entry. This means two nested `modify_res` calls (e.g., two `&mut` resource parameters generated by `#[chain]`) lock _different_ mutexes and cannot deadlock against each other.
+ - **`Program` delegation** — All resource methods on `Program` now delegate to its internal `resources: GlobalResContainer` member, keeping the public `Program` resource API unchanged.
+ - **Generic helper methods** — `__modify_res_and_return_route<Res, C>` and `res_or_route<Res, C>` now take an explicit `C: ProgramCollect<Enum = C>` generic parameter (added separately on the container), with `Program`'s versions keeping the single-`Res` signature.
+ - **`__store_res` semantics** — If an entry already exists for the type and is a matching `Arc<Mutex<Arc<Res>>>`, the value is updated in place under the entry lock; otherwise (missing entry, type mismatch, or poisoned lock) the entry is replaced wholesale.
+
+ The container is standalone and not coupled to any `Program` instance or the global `this::<C>()` context, so any number of independent `GlobalResContainer`s can be created and used simultaneously.
+
+ _No behavioral changes for downstream code — `Program`'s public resource API (`with_resource`, `modify_res`, `res`, `res_or_route`, `res_or_default`) is unchanged, and the `&mut` resource injection syntax for `#[chain]` (sync and async) continues to work as before. A side benefit: nested resource modifications no longer risk deadlock._
+
#### Optimizations:
1. **[`pathf`]** Added `is_module` field to `AnalyzeItem` and a new constructor `AnalyzeItem::local_module(module, item_name)` which sets `is_module: true`. The `type_mapping_builder` now tracks whether an item is a module: when generating `type_using.rs`, module items produce `use path::to::module::*;` (glob import) instead of the standard `use path::to::TypeName;` direct import. Non-module items continue to use direct imports as before. The internal data structure changed from `Vec<(String, String)>` to `Vec<(String, String, bool)>` to carry the `is_module` flag through the pipeline.