Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Fix race conditions in DatataContractSerialization #31065

Merged
merged 3 commits into from
Jul 16, 2018

Conversation

jiayi11
Copy link
Member

@jiayi11 jiayi11 commented Jul 14, 2018

Fixes #30651
@mconnew @huanwu @Lxiamail

@jiayi11 jiayi11 added this to the 3.0 milestone Jul 14, 2018
@jiayi11 jiayi11 self-assigned this Jul 14, 2018
#pragma warning disable 0649
private XmlNodeReader _xmlNodeReader;
#pragma warning restore 0649

private XmlObjectSerializerReadContext _context;

private static Dictionary<string, string> s_nsToPrefixTable;
private static Hashtable s_nsToPrefixTable;
Copy link
Member

Choose a reason for hiding this comment

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

Why the non-generic variant?

Copy link
Member

Choose a reason for hiding this comment

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

I think hash table are safe for concurrent reading and writing https://github.com/dotnet/corefx/issues/29360#issue-318244506.

But it's not using a lock to protect the reads in this function and elsewhere, and unlike Hashtable, Dictionary (and in this case LowLevelDictionary) are not safe for concurrent reading and writing.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks!

So recap:
s_nsToPrefixTable is safe in this way. The write to it is under a lock, the read is double-checked under the lock.
s_prefixToNsTable gets written to under a lock, while the read is unlocked in LookupNamespace. So the "safeness" depends on when LookupNamespace gets called in relation to GetPrefix. To be on the safe side your cite and Hashtable seems to be correct.

So there should be a comment on why Hashtable is used instead of Dictionary<string, string>, but it's not so obvious.

BTW: the two statics could be readonly.

Copy link
Member

Choose a reason for hiding this comment

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

While I understand the desire to make sure things are commented so the code is understood, I feel like understanding the behavior characteristics of the main framework collection types should be a given when working with corefx code. Certainly if someone would want to change this they should understand the differences in behavior of HashTable and whatever they are wanting to replace it with before making a change. Otherwise do we need to add a comment to usages of List explaining it's being used because of constant time retrieval by index as opposed to LinkedList which is linear time but can have constant time removal (whereas List is linear time with size with some usage patterns)?

Copy link
Member

Choose a reason for hiding this comment

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

I think hash table are safe for concurrent reading and writing

They are safe for multiple reader single writer.

Copy link
Member

@gfoidl gfoidl Jul 14, 2018

Choose a reason for hiding this comment

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

O(1) vs O(n) is obvious, no need for any comment. The relation to List and LinkedList is a bit wrong in this place. It's more generic collection type vs nongeneric type with same perf characteristics.

I feel it's not so obvious that here Hashtable is better suited, hence I'd like to see a hint here.

Copy link
Member

Choose a reason for hiding this comment

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

They are safe for multiple reader single writer.

@danmosemsft thank's for info!

@@ -37,20 +37,22 @@ private enum ExtensionDataNodeType
private int _attributeCount;
private int _attributeIndex;

private static object prefixLock = new object();
Copy link
Member

Choose a reason for hiding this comment

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

Nit: prefixLock => s_prefixLock

Copy link
Member

@mconnew mconnew left a comment

Choose a reason for hiding this comment

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

Other than the small naming nit, LGTM.

@jiayi11
Copy link
Member Author

jiayi11 commented Jul 16, 2018

Thanks everyone for reviewing this PR 😃

@jiayi11 jiayi11 merged commit 2b9fa07 into dotnet:master Jul 16, 2018
@jiayi11 jiayi11 deleted the racecondition branch August 14, 2018 23:39
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
* Fix some race conditions in DatataContractSerialization


Commit migrated from dotnet/corefx@2b9fa07
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.

6 participants