Skip to content

Custom nodes hold their inputs strongly while up-to-date - #123

Open
krauthaufen wants to merge 2 commits into
masterfrom
fix/custom-retain-inputs-122
Open

krauthaufen wants to merge 2 commits into
masterfrom
fix/custom-retain-inputs-122

Conversation

@krauthaufen

Copy link
Copy Markdown
Collaborator

Fixes #122.

Dependency edges are weak (Outputs only), so a node that is created and read inside a custom compute function is unreachable once evaluation returns. After the next GC the chain source -> inner -> outer is gone and outer is never marked again — silently.

Fix, the idiomatic one: a custom node holds the inputs it read strongly for as long as it is up-to-date, exactly like bind holds its inner node. New public interface IInputHoldingObject with AddInput; EvaluateAlways hands each read input to the caller if it implements it (one type test next to the existing Outputs.Add; nothing for other objects, no IAdaptiveObject change). AVal.custom and the ASet/AMap/AList.custom readers implement it: clear on Mark, refill during Compute. No locking needed — AddInput runs under the caller's monitor by construction, Mark under the transaction's EnterWrite.

Test: all seven shapes from the issue plus reads inside the collection customs, forcing a full GC between reads; fails without the EvaluateAlways call site, passes with it. Full suite green.

Edges are weak, so a node created and read inside a custom compute function was collectable, silently dropping the dependency. IInputHoldingObject lets EvaluateAlways hand each read input to the caller; AVal/ASet/AMap/AList.custom keep them until marked.

This branch has not been deployed

No deployments
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.

AVal.custom silently serves a stale value when its compute function creates the node it reads (GC-dependent)

1 participant