Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use lock for set iteration. #1524

Closed
wants to merge 1 commit into from
Closed

Conversation

joshwd36
Copy link
Contributor

This Pull Request fixes the issue of concurrent modification of a set during iteration, similar to that in map in #1092.

It changes the following:

  • Changes the key of OrderedSet to a SetKey, which contains either a JsValue or an empty value.
  • Allows locking a set to allow safe iteration.
  • When an entry is deleted while the set is locked, it replaces the entry with an empty value to maintain the indexes.
  • When the set is unlocked any empty entries are deleted.
  • Locks are implemented as a guard object so that they are released even if an error occurs.

This implementation is very similar to that of #1366, and so should not present any additional issues.

@Razican
Copy link
Member

Razican commented Aug 28, 2021

Test262 conformance changes:

Test result master count PR count difference
Total 80,685 80,685 0
Passed 31,821 31,823 +2
Ignored 15,818 15,818 0
Failed 33,046 33,044 -2
Panics 2 2 0
Conformance 39.44% 39.44% +0.00%
Fixed tests (2):
test/built-ins/Set/prototype/forEach/iterates-values-revisits-after-delete-re-add.js [strict mode] (previously Failed)
test/built-ins/Set/prototype/forEach/iterates-values-revisits-after-delete-re-add.js (previously Failed)

@jedel1043
Copy link
Member

Couldn't this be implemented as rustc does, with type HashSet<K> = HashMap<K, ()>? Maybe I'm overlooking something, but this should avoid implementing the exact same logic by hand.

@jedel1043 jedel1043 added this to the v0.13.0 milestone Aug 28, 2021
@joshwd36
Copy link
Contributor Author

Couldn't this be implemented as rustc does, with type HashSet<K> = HashMap<K, ()>? Maybe I'm overlooking something, but this should avoid implementing the exact same logic by hand.

I did think of that, but there would have to be some differences as the behaviour when deleting is slightly different. I can investigate whether it would be worth it

@jedel1043
Copy link
Member

Couldn't this be implemented as rustc does, with type HashSet<K> = HashMap<K, ()>? Maybe I'm overlooking something, but this should avoid implementing the exact same logic by hand.

I did think of that, but there would have to be some differences as the behaviour when deleting is slightly different. I can investigate whether it would be worth it

I investigated a little bit more and rustc in actuality uses a newtype wrapping a HashMap, making the definition of HashSet something more like struct HashSet<K>(HashMap<K, ()>). With this you can also customize the behaviour of delete, so I think it's worth considering.

@jedel1043 jedel1043 added the bug Something isn't working label Aug 29, 2021
Copy link
Contributor

@RageKnify RageKnify left a comment

Choose a reason for hiding this comment

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

Looks ok to me, but as @jedel1043 said, might be a good idea to make use of the NewTypes we have implemented for Map rather than having really similar ones here.

@raskad raskad modified the milestones: v0.13.0, v0.14.0 Sep 25, 2021
@RageKnify
Copy link
Contributor

Hey @joshwd36, do you have time to get back to this? Could you explain the downsides to not using the struct implemented for the Map.

@Razican
Copy link
Member

Razican commented Feb 5, 2022

I'm closing this for now, since it's not being updated. Feel free to open a new PR with a rebased proposal.

@Razican Razican closed this Feb 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants