Skip to content
This repository has been archived by the owner on Jan 25, 2022. It is now read-only.

Throw if FinalizationGroupCleanupIterator is iterated outside of the FinalizationGroupCleanupJob #84

Merged
merged 1 commit into from
Apr 30, 2019

Conversation

gsathya
Copy link
Member

@gsathya gsathya commented Apr 24, 2019

Leaking the iterator is bad as we could potentially cause the same holding to be iterated twice if the user iterates over a leaked iterator (from a previous turn) and a newly created iterator (in the following turn).

Fixes #29

@gsathya gsathya requested a review from littledan April 24, 2019 23:59
@mhofman
Copy link
Member

mhofman commented Apr 25, 2019

My reading of the spec is that it's not possible to iterate over the same holding twice since the corresponding record is removed before being yielded by the iterator.

Since there is cleanupSome, there is probably no reason for the iterator to be used outside of the callback.

My main concern is if the callback is an async function. This change effectively prevents that.

@littledan
Copy link
Member

I am comfortable preventing async functions from being used here. A turn may happen in the middle of an async function, and we don't want to prevent more GC work from happening then.

@mhofman
Copy link
Member

mhofman commented Apr 25, 2019

What do you mean by "prevent more GC work from happening"?

It might be surprising from the developer's point of view to have code like this fail:

finalizationGroup.cleanupSome(async (items) => {
  for (const holding of items) {
    await freeStuff(holding);
  }
});

Copy link
Member

@littledan littledan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I was picturing punning [[Cells]] or [[FinalizationGroup]] to hold this state, but your approach is cleaner and better.

@@ -210,7 +211,9 @@ <h1>%FinalizationGroupCleanupIteratorPrototype%.next ( )</h1>
1. Let _finalizationGroup_ be _iterator_.[[FinalizationGroup]].
1. If _finalizationGroup_ is *undefined*, then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When will this condition be true? I assumed that this was some vestigial logic for the same case (or is vestigial logic for the shutdown method?)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case the iterator is leaked, then the finalization group doesn't need to leak as well. With this condition the finalization group is weakly held and can be collected independent of the iterator.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what makes it weakly held. Should we update the "abstract jobs" section to indicate that this is weak somehow?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, we should update that too. Both are required.

@gsathya gsathya merged commit 93687df into master Apr 30, 2019
mhofman added a commit to mhofman/tc39-weakrefs-shim that referenced this pull request May 7, 2019
mhofman added a commit to mhofman/tc39-weakrefs-shim that referenced this pull request May 8, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

What happen when next() is called on a cleanup iterator outside the finalization turn?
3 participants