Browse Source

Merge pull request #101 from Arimodu/Fix-64-config-limit

Fix config 64 max limit
pull/104/head
nike4613 1 year ago
committed by GitHub
parent
commit
055778cc9d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 31 deletions
  1. +46
    -12
      IPA.Loader/Config/ConfigRuntime.cs
  2. +2
    -7
      IPA.Loader/Config/IConfigStore.cs
  3. +2
    -12
      IPA.Loader/Config/Stores/GeneratedStoreImpl/IGeneratedStore.cs

+ 46
- 12
IPA.Loader/Config/ConfigRuntime.cs View File

@ -2,15 +2,10 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Threading; using System.Threading;
using IPA.Utilities;
using IPA.Utilities.Async; using IPA.Utilities.Async;
using System.IO; using System.IO;
using System.Runtime.CompilerServices;
using IPA.Logging;
using UnityEngine;
using Logger = IPA.Logging.Logger; using Logger = IPA.Logging.Logger;
#if NET4 #if NET4
using Task = System.Threading.Tasks.Task; using Task = System.Threading.Tasks.Task;
@ -30,15 +25,17 @@ namespace IPA.Config
=> obj?.GetHashCode() ?? 0; => obj?.GetHashCode() ?? 0;
} }
private static readonly ConcurrentBag<Config> configs = new ConcurrentBag<Config>();
private static readonly AutoResetEvent configsChangedWatcher = new AutoResetEvent(false);
private static readonly ConcurrentBag<Config> configs = new();
private static readonly AutoResetEvent configsChangedWatcher = new(false);
public static readonly BlockingCollection<IConfigStore> RequiresSave = new();
private static readonly ConcurrentDictionary<DirectoryInfo, FileSystemWatcher> watchers private static readonly ConcurrentDictionary<DirectoryInfo, FileSystemWatcher> watchers
= new ConcurrentDictionary<DirectoryInfo, FileSystemWatcher>(new DirInfoEqComparer()); = new ConcurrentDictionary<DirectoryInfo, FileSystemWatcher>(new DirInfoEqComparer());
private static readonly ConcurrentDictionary<FileSystemWatcher, ConcurrentBag<Config>> watcherTrackConfigs private static readonly ConcurrentDictionary<FileSystemWatcher, ConcurrentBag<Config>> watcherTrackConfigs
= new ConcurrentDictionary<FileSystemWatcher, ConcurrentBag<Config>>(); = new ConcurrentDictionary<FileSystemWatcher, ConcurrentBag<Config>>();
private static SingleThreadTaskScheduler loadScheduler = null;
private static TaskFactory loadFactory = null;
private static Thread saveThread = null;
private static SingleThreadTaskScheduler loadScheduler;
private static TaskFactory loadFactory;
private static Thread saveThread;
private static Thread legacySaveThread;
private static void TryStartRuntime() private static void TryStartRuntime()
{ {
@ -55,6 +52,11 @@ namespace IPA.Config
saveThread = new Thread(SaveThread); saveThread = new Thread(SaveThread);
saveThread.Start(); saveThread.Start();
} }
if (legacySaveThread == null || !legacySaveThread.IsAlive)
{
legacySaveThread = new Thread(LegacySaveThread);
legacySaveThread.Start();
}
AppDomain.CurrentDomain.ProcessExit -= ShutdownRuntime; AppDomain.CurrentDomain.ProcessExit -= ShutdownRuntime;
AppDomain.CurrentDomain.ProcessExit += ShutdownRuntime; AppDomain.CurrentDomain.ProcessExit += ShutdownRuntime;
@ -212,15 +214,47 @@ namespace IPA.Config
Logger.Config.Error($"{nameof(IConfigStore)} for {config.File} errored while reading from the {nameof(IConfigProvider)}"); Logger.Config.Error($"{nameof(IConfigStore)} for {config.File} errored while reading from the {nameof(IConfigProvider)}");
Logger.Config.Error(e); Logger.Config.Error(e);
} }
}
}
private static void SaveThread() private static void SaveThread()
{
try
{
foreach (var item in RequiresSave.GetConsumingEnumerable())
{
try
{
Save(configs.First((c) => ReferenceEquals(c.Store.WriteSyncObject, item.WriteSyncObject)));
}
catch (ThreadAbortException)
{
break;
}
catch (Exception e)
{
Logger.Config.Error($"Error waiting for in-memory updates");
Logger.Config.Error(e);
Thread.Sleep(TimeSpan.FromSeconds(1));
}
}
}
catch (ThreadAbortException)
{
// we got aborted :(
}
finally
{
RequiresSave.Dispose();
}
}
private static void LegacySaveThread()
{ {
try try
{ {
while (true) while (true)
{ {
var configArr = configs.Where(c => c.Store != null).ToArray();
var configArr = configs.Where(c => c.Store != null).Where(c => c.Store.SyncObject != null).ToArray();
int index = -1; int index = -1;
try try
{ {


+ 2
- 7
IPA.Loader/Config/IConfigStore.cs View File

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Threading;
namespace IPA.Config namespace IPA.Config
{ {
@ -17,6 +11,7 @@ namespace IPA.Config
/// A synchronization object for the save thread to wait on for changes. /// A synchronization object for the save thread to wait on for changes.
/// It should be signaled whenever the internal state of the object is changed. /// It should be signaled whenever the internal state of the object is changed.
/// The writer will never signal this handle. /// The writer will never signal this handle.
/// This will be null for internally-implemented providers
/// </summary> /// </summary>
WaitHandle SyncObject { get; } WaitHandle SyncObject { get; }


+ 2
- 12
IPA.Loader/Config/Stores/GeneratedStoreImpl/IGeneratedStore.cs View File

@ -47,9 +47,7 @@ namespace IPA.Config.Stores
internal static ConstructorInfo Ctor = typeof(Impl).GetConstructor(new[] { typeof(IGeneratedStore) }); internal static ConstructorInfo Ctor = typeof(Impl).GetConstructor(new[] { typeof(IGeneratedStore) });
public Impl(IGeneratedStore store) => generated = store; public Impl(IGeneratedStore store) => generated = store;
private readonly AutoResetEvent resetEvent = new(false);
public WaitHandle SyncObject => resetEvent;
public WaitHandle? SyncObject => null;
public static WaitHandle? ImplGetSyncObject(IGeneratedStore s) => FindImpl(s)?.SyncObject; public static WaitHandle? ImplGetSyncObject(IGeneratedStore s) => FindImpl(s)?.SyncObject;
internal static MethodInfo ImplGetSyncObjectMethod = typeof(Impl).GetMethod(nameof(ImplGetSyncObject)); internal static MethodInfo ImplGetSyncObjectMethod = typeof(Impl).GetMethod(nameof(ImplGetSyncObject));
@ -61,15 +59,7 @@ namespace IPA.Config.Stores
public static void ImplSignalChanged(IGeneratedStore s) => FindImpl(s)?.SignalChanged(); public static void ImplSignalChanged(IGeneratedStore s) => FindImpl(s)?.SignalChanged();
public void SignalChanged() public void SignalChanged()
{ {
try
{
_ = resetEvent.Set();
}
catch (ObjectDisposedException e)
{
Logger.Config.Error($"ObjectDisposedException while signalling a change for generated store {generated?.GetType()}");
Logger.Config.Error(e);
}
ConfigRuntime.RequiresSave.Add(this);
} }
internal static MethodInfo ImplInvokeChangedMethod = typeof(Impl).GetMethod(nameof(ImplInvokeChanged)); internal static MethodInfo ImplInvokeChangedMethod = typeof(Impl).GetMethod(nameof(ImplInvokeChanged));


Loading…
Cancel
Save