Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Prevent concurrent use corruption from causing infinite loops#16991

Merged
jkotas merged 2 commits into
dotnet:masterfrom
benaadams:concurrent-dict
Mar 17, 2018
Merged

Prevent concurrent use corruption from causing infinite loops#16991
jkotas merged 2 commits into
dotnet:masterfrom
benaadams:concurrent-dict

Conversation

@benaadams
Copy link
Copy Markdown
Member

Copy link
Copy Markdown
Member

@jkotas jkotas left a comment

Choose a reason for hiding this comment

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

Thanks!

Comment thread src/mscorlib/Resources/Strings.resx Outdated
<value>A prior operation on this collection was interrupted by an exception. Collection's state is no longer trusted.</value>
</data>
<data name="InvalidOperation_ConcurrentOperationsNotSupported" xml:space="preserve">
<value>Concurrent operations are not supported on non-concurrent collections. A concurrent operation was performed on this collection and corrupted its state. Collection's state is no longer correct.</value>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: "Collection's state" => "The collection's state"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Concurrent reads are supported right? Maybe "Operations that change this collection must have exclusive access" or something like that?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Now says:

Operations that change non-concurrent collections must have exclusive access. A concurrent update was performed on this collection and corrupted its state. The collection's state is no longer correct.

How's that?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Sounds fine.

// The chain of entires forms a loop; which means a concurrent update has happened.
// Break out of the loop and throw; rather than looping forever.
ThrowHelper.ThrowInvalidOperationException_ConcurrentOperationsNotSupported();
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What kind of measurable impact, if any, does this have on TryGetValue?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It shouldn't impact items that haven't collided (as they don't loop); hoping it will be minimal; but will have a look.

On the flip side, what's the alternative?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

On the flip side, what's the alternative?

If it's very negatively impactful, not doing it.

i = entries[i].next;
if (loops >= entries.Length)
{
// The chain of entires forms a loop; which means a concurrent update has happened.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: search and replace "entires" => "entries"

if (loops >= entries.Length)
{
// The chain of entires forms a loop; which means a concurrent update has happened.
// Break out of the loop and throw; rather than looping forever.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: ';' => ',' (same in the other copies of this)

// Break out of the loop and throw; rather than looping forever.
ThrowHelper.ThrowInvalidOperationException_ConcurrentOperationsNotSupported();
}
loops++;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What about using the same name collisioncount throughout?

Copy link
Copy Markdown
Member

@safern safern left a comment

Choose a reason for hiding this comment

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

cc: @ianhays

Copy link
Copy Markdown
Member

@danmoseley danmoseley left a comment

Choose a reason for hiding this comment

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

Thanks @benaadams !

@jkotas jkotas merged commit f2f327d into dotnet:master Mar 17, 2018
@benaadams benaadams deleted the concurrent-dict branch March 17, 2018 01:28
@vancem
Copy link
Copy Markdown

vancem commented Mar 19, 2018

Note that the original idea from Feng was on HashSet not Dictionary<K, V>. I think it was reasonable that this issue is more likely on Dictionary since it is used more commonly. Still it may be worth determining whether we apply this change to HashSet.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants