From edb46ce381b9da3688acd5d0b73b455757d8e963 Mon Sep 17 00:00:00 2001 From: Piotrekol Date: Tue, 13 Feb 2018 16:51:33 +0100 Subject: [PATCH] Make settings thread safe --- osu!StreamCompanion/Code/Core/Settings.cs | 150 +++++++++++++--------- 1 file changed, 87 insertions(+), 63 deletions(-) diff --git a/osu!StreamCompanion/Code/Core/Settings.cs b/osu!StreamCompanion/Code/Core/Settings.cs index 9fa32fbd..2fcf58e0 100644 --- a/osu!StreamCompanion/Code/Core/Settings.cs +++ b/osu!StreamCompanion/Code/Core/Settings.cs @@ -19,6 +19,7 @@ public class Settings private string saveLocation; private readonly string configFileName = "settings.ini"; public string FullConfigFilePath { get { return Path.Combine(saveLocation, configFileName); } } + private static readonly object _lockingObject = new object(); public Settings(ILogger logger) { _logger = logger; @@ -31,112 +32,135 @@ protected virtual void OnSettingUpdated(string settingName) public T Get(ConfigEntry entry) { - return this.Get(entry.Name, entry.Default()); + lock (_lockingObject) + return this.Get(entry.Name, entry.Default()); } public void Add(string key, T value, bool raiseUpdate = false) { - _settingsEntries[key] = value; - if (raiseUpdate) - OnSettingUpdated(key); + lock (_lockingObject) + { + _settingsEntries[key] = value; + if (raiseUpdate) + OnSettingUpdated(key); + } } public void Add(string key, List valueList, bool raiseUpdate = false) { - string vals = string.Join("|,~", valueList); + lock (_lockingObject) + { + string vals = string.Join("|,~", valueList); - Add(key, vals, raiseUpdate); + Add(key, vals, raiseUpdate); + } } public List Get(string key) { - string savedValue = Get(key, ""); - var ret = savedValue.Split(new[] { "|,~" }, StringSplitOptions.None).ToList(); - if (ret[0] == string.Empty) - ret.RemoveAt(0); - return ret; + lock (_lockingObject) + { + string savedValue = Get(key, ""); + var ret = savedValue.Split(new[] { "|,~" }, StringSplitOptions.None).ToList(); + if (ret[0] == string.Empty) + ret.RemoveAt(0); + return ret; + } } public List Geti(string key) { - string savedValue = Get(key, ""); - var ret = new List(); - if (!string.IsNullOrEmpty(savedValue)) - ret = + lock (_lockingObject) + { + string savedValue = Get(key, ""); + var ret = new List(); + if (!string.IsNullOrEmpty(savedValue)) + ret = savedValue.Split(new[] { "|,~" }, StringSplitOptions.None) .ToList().ConvertAll(int.Parse); - return ret; + return ret; + } } private T Get(string key, T defaultValue) { - if (_settingsEntries.ContainsKey(key)) + lock (_lockingObject) { - if (_settingsEntries[key] is T) + if (_settingsEntries.ContainsKey(key)) { - return (T)_settingsEntries[key]; - } - else - { - try + if (_settingsEntries[key] is T) { - return (T)Convert.ChangeType(_settingsEntries[key], typeof(T)); + return (T)_settingsEntries[key]; } - catch (InvalidCastException) + else { - _logger.Log("Warning: Had to use default value on {0} (InvalidCastException){1}::{2}", LogLevel.Basic, key, _settingsEntries[key].GetType().FullName, typeof(T).FullName); - return default(T); + try + { + return (T)Convert.ChangeType(_settingsEntries[key], typeof(T)); + } + catch (InvalidCastException) + { + _logger.Log("Warning: Had to use default value on {0} (InvalidCastException){1}::{2}", + LogLevel.Basic, key, _settingsEntries[key].GetType().FullName, typeof(T).FullName); + return default(T); + } } } - } - int idx = _rawLines.AnyStartsWith(key); - if (idx > -1) - { - string[] splited = _rawLines[idx].Split(new[] { '=' }, 2); - Add(key, Convert.ChangeType(splited[1].Trim(), typeof(T))); - _rawLines.RemoveAt(idx); + int idx = _rawLines.AnyStartsWith(key); + if (idx > -1) + { + string[] splited = _rawLines[idx].Split(new[] { '=' }, 2); + Add(key, Convert.ChangeType(splited[1].Trim(), typeof(T))); + _rawLines.RemoveAt(idx); + } + else + Add(key, defaultValue); + return Get(key, defaultValue); } - else - Add(key, defaultValue); - return Get(key, defaultValue); } public void Save() { - if (_rawLines.Count > 0) + lock (_lockingObject) { - foreach (string line in _rawLines) + if (_rawLines.Count > 0) + { + foreach (string line in _rawLines) + { + string[] splited = line.Split(new[] { '=' }, 2); + if (splited.Length == 2) + Add(splited[0].Trim(), Convert.ChangeType(splited[1].Trim(), typeof(string))); + } + _rawLines.Clear(); + } + StringBuilder stringBuilder = new StringBuilder(); + foreach (var entry in _settingsEntries) { - string[] splited = line.Split(new[] { '=' }, 2); - if (splited.Length == 2) - Add(splited[0].Trim(), Convert.ChangeType(splited[1].Trim(), typeof(string))); + stringBuilder.AppendFormat("{0} = {1}{2}", entry.Key, entry.Value, Environment.NewLine); + } + if (!Directory.Exists(saveLocation)) + { + Directory.CreateDirectory(saveLocation); + } + using (var fileHandle = new StreamWriter(FullConfigFilePath)) + { + fileHandle.Write(stringBuilder); } - _rawLines.Clear(); - } - StringBuilder stringBuilder = new StringBuilder(); - foreach (var entry in _settingsEntries) - { - stringBuilder.AppendFormat("{0} = {1}{2}", entry.Key, entry.Value, Environment.NewLine); - } - if (!Directory.Exists(saveLocation)) - { - Directory.CreateDirectory(saveLocation); - } - using (var fileHandle = new StreamWriter(FullConfigFilePath)) - { - fileHandle.Write(stringBuilder); } } public void Load() { - var filePath = FullConfigFilePath; - if (File.Exists(filePath)) - using (var fileHandle = new StreamReader(filePath, true)) - { - while (!fileHandle.EndOfStream) + lock (_lockingObject) + { + var filePath = FullConfigFilePath; + if (File.Exists(filePath)) + using (var fileHandle = new StreamReader(filePath, true)) { - _rawLines.Add(fileHandle.ReadLine()); + while (!fileHandle.EndOfStream) + { + _rawLines.Add(fileHandle.ReadLine()); + } } - } + } } public void SetSavePath(string path)