mirror of
https://github.com/BepInEx/BepInEx.git
synced 2026-10-19 15:51:45 +00:00
Enumerate a config snapshot under the lock (#1357)
ConfigFile documents its public methods as thread-safe, but GetEnumerator returned the live Dictionary enumerator with no lock, so a concurrent Bind/Reload could invalidate it mid-foreach. Snapshot under _ioLock instead.
This commit is contained in:
1 parent
32fb12f2e9
commit
fb5f191b36
1 file changed
+6
-3
@@ -92,9 +92,12 @@ public class ConfigFile : IDictionary<ConfigDefinition, ConfigEntryBase>
|
|||||||
public ConfigEntryBase this[string section, string key] => this[new ConfigDefinition(section, key)];
|
public ConfigEntryBase this[string section, string key] => this[new ConfigDefinition(section, key)];
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IEnumerator<KeyValuePair<ConfigDefinition, ConfigEntryBase>> GetEnumerator() =>
|
public IEnumerator<KeyValuePair<ConfigDefinition, ConfigEntryBase>> GetEnumerator()
|
||||||
// We can't really do a read lock for this
|
{
|
||||||
Entries.GetEnumerator();
|
// Enumerate a snapshot taken under the lock so a concurrent mutation cannot invalidate the iterator.
|
||||||
|
lock (_ioLock)
|
||||||
|
return Entries.ToList().GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user