Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix space leak in dynamic event switching (#256)
Currently we have a nasty space leak in dynamic event switching. The crux of the problem is that we have a child event that needs to have a new parent. When we change the parent of a node, we need to create a weak pointer to the new parent and store it in the child's list of parents, and we need to store a weak pointer to the child in the new parent node. Currently `connectChild` does this by creating a new weak pointer to the child whenever the parent changes: ```haskell w <- mkWeakNodeValue child child ``` Here we create a weak pointer to the child `SomeNode`, kept alive by the underlying `IORef` that backs `child`. The problem with this approach is that the `child` `IORef` may be reachable throughout the entire duration of the program execution (e.g., `child` is connected to a top-level `reactimate`). This is problematic, because a weak pointer is kept alive by the garbage collector if the key of the weak pointer is alive *regardless* of whether anyone actually has a reference to the weak pointer itself. In the case of `switchE`, this means any time we switch a child to have a new parent, we allocate one more weak pointer that can never be garbage collected. The fix to allow the old weak pointers to be garbage collected is to call `finalize` on them, which we now do in `removeParents`. `removeParents` is responsible for removing a child from all current parents, so when we remove ourself from a parent (removing the weak pointer from the parent), we finalize the weak pointer. Fixes #253, #152.
- Loading branch information