Add lock for IniConfig.SectionMap

This commit is contained in:
Christian Schulz 2025-05-30 21:34:33 +02:00
commit 4e7da54a22

View file

@ -41,6 +41,11 @@ namespace Greenshot.Base.IniFile
/// </summary> /// </summary>
private static readonly object IniLock = new object(); private static readonly object IniLock = new object();
/// <summary>
/// A lock object for the section map
/// </summary>
private static readonly object SectionMapLock = new object();
/// <summary> /// <summary>
/// As the ini implementation is kept someone generic, for reusing, this holds the name of the application /// As the ini implementation is kept someone generic, for reusing, this holds the name of the application
/// </summary> /// </summary>
@ -290,6 +295,8 @@ namespace Greenshot.Base.IniFile
// Load the fixed settings // Load the fixed settings
_fixedProperties = Read(CreateIniLocation(_configName + FixedPostfix + IniExtension, true)); _fixedProperties = Read(CreateIniLocation(_configName + FixedPostfix + IniExtension, true));
lock (SectionMapLock)
{
foreach (IniSection section in SectionMap.Values) foreach (IniSection section in SectionMap.Values)
{ {
try try
@ -310,6 +317,7 @@ namespace Greenshot.Base.IniFile
} }
} }
} }
}
/// <summary> /// <summary>
/// This "fixes" the properties of the section, meaning any properties in the fixed file can't be changed. /// This "fixes" the properties of the section, meaning any properties in the fixed file can't be changed.
@ -389,7 +397,12 @@ namespace Greenshot.Base.IniFile
{ {
get get
{ {
foreach (string sectionName in SectionMap.Keys) List<string> sectionNames;
lock (SectionMapLock)
{
sectionNames = [.. SectionMap.Keys];
}
foreach (string sectionName in sectionNames)
{ {
yield return sectionName; yield return sectionName;
} }
@ -402,10 +415,13 @@ namespace Greenshot.Base.IniFile
/// <param name="sectionName"></param> /// <param name="sectionName"></param>
/// <returns></returns> /// <returns></returns>
public static IniSection GetIniSection(string sectionName) public static IniSection GetIniSection(string sectionName)
{
lock (SectionMapLock)
{ {
SectionMap.TryGetValue(sectionName, out var returnValue); SectionMap.TryGetValue(sectionName, out var returnValue);
return returnValue; return returnValue;
} }
}
/// <summary> /// <summary>
/// A generic method which returns an instance of the supplied type, filled with it's configuration /// A generic method which returns an instance of the supplied type, filled with it's configuration
@ -429,21 +445,25 @@ namespace Greenshot.Base.IniFile
Type iniSectionType = typeof(T); Type iniSectionType = typeof(T);
string sectionName = IniSection.GetIniSectionAttribute(iniSectionType).Name; string sectionName = IniSection.GetIniSectionAttribute(iniSectionType).Name;
lock (SectionMapLock)
{
if (SectionMap.ContainsKey(sectionName)) if (SectionMap.ContainsKey(sectionName))
{ {
//LOG.Debug("Returning pre-mapped section " + sectionName); //LOG.Debug("Returning pre-mapped section " + sectionName);
section = (T) SectionMap[sectionName]; section = (T)SectionMap[sectionName];
} }
else else
{ {
// Create instance of this type // Create instance of this type
section = (T) Activator.CreateInstance(iniSectionType); section = (T)Activator.CreateInstance(iniSectionType);
// Store for later save & retrieval // Store for later save & retrieval
SectionMap.Add(sectionName, section); SectionMap.Add(sectionName, section);
section.Fill(PropertiesForSection(section)); section.Fill(PropertiesForSection(section));
FixProperties(section); FixProperties(section);
} }
}
if (allowSave && section.IsDirty) if (allowSave && section.IsDirty)
{ {