-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Fix thread-safety issues with enumerating ResourceManager. #75054
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
Changes from all commits
862e7fe
0c274c1
5d99bf6
a8a8b61
a6278d0
eea9c08
7307995
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,7 @@ | |
| using System.Collections.Generic; | ||
| using System.Diagnostics; | ||
| using System.IO; | ||
| using System.Threading; | ||
|
|
||
| namespace System.Resources | ||
| #if RESOURCES_EXTENSIONS | ||
|
|
@@ -287,6 +288,9 @@ private IDictionaryEnumerator GetEnumeratorHelper() | |
| object? value; | ||
| ResourceLocator resEntry; | ||
|
|
||
| // Lock the cache first, then the reader (reader locks implicitly through its methods). | ||
| // Lock order MUST match ResourceReader.ResourceEnumerator.Entry to avoid deadlock. | ||
| Debug.Assert(!Monitor.IsEntered(reader)); | ||
| lock (cache) | ||
| { | ||
| // Find the offset within the data section | ||
|
|
@@ -299,7 +303,7 @@ private IDictionaryEnumerator GetEnumeratorHelper() | |
|
|
||
| // When data type cannot be cached | ||
| dataPos = resEntry.DataPosition; | ||
| return isString ? reader.LoadString(dataPos) : reader.LoadObject(dataPos, out _); | ||
| return isString ? reader.LoadString(dataPos) : reader.LoadObject(dataPos); | ||
| } | ||
|
|
||
| dataPos = reader.FindPosForResource(key); | ||
|
|
@@ -357,14 +361,11 @@ private IDictionaryEnumerator GetEnumeratorHelper() | |
| return value; | ||
| } | ||
|
|
||
| private static object? ReadValue (ResourceReader reader, int dataPos, bool isString, out ResourceLocator locator) | ||
| private static object? ReadValue(ResourceReader reader, int dataPos, bool isString, out ResourceLocator locator) | ||
| { | ||
| object? value; | ||
| ResourceTypeCode typeCode; | ||
|
|
||
| // Normally calling LoadString or LoadObject requires | ||
| // taking a lock. Note that in this case, we took a | ||
| // lock before calling this method. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment was not (no longer?) correct. We do typically call these within a lock, but it is a lock on either Now, |
||
| if (isString) | ||
| { | ||
| value = reader.LoadString(dataPos); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.