From e9953947db63a4478e9626197c775f4aebd13ad7 Mon Sep 17 00:00:00 2001 From: Anairkoen Schno Date: Sun, 8 Dec 2019 01:04:37 -0600 Subject: [PATCH] Fixed many small issues --- IPA.Loader/Config/Config.cs | 1 + IPA.Loader/Config/ConfigRuntime.cs | 31 +++++++++++---- IPA.Loader/Config/SelfConfig.cs | 1 + IPA.Loader/Config/Stores/GeneratedStore.cs | 44 ++++++++++++++-------- 4 files changed, 53 insertions(+), 24 deletions(-) diff --git a/IPA.Loader/Config/Config.cs b/IPA.Loader/Config/Config.cs index fef8394e..fd4b1610 100644 --- a/IPA.Loader/Config/Config.cs +++ b/IPA.Loader/Config/Config.cs @@ -150,6 +150,7 @@ namespace IPA.Config if (Store != null) throw new InvalidOperationException($"{nameof(SetStore)} can only be called once"); Store = store; + ConfigRuntime.ConfigChanged(); } /// diff --git a/IPA.Loader/Config/ConfigRuntime.cs b/IPA.Loader/Config/ConfigRuntime.cs index a7b8c1d3..ea80b635 100644 --- a/IPA.Loader/Config/ConfigRuntime.cs +++ b/IPA.Loader/Config/ConfigRuntime.cs @@ -67,6 +67,11 @@ namespace IPA.Config AddConfigToWatchers(cfg); } + public static void ConfigChanged() + { + configsChangedWatcher.Set(); + } + private static void AddConfigToWatchers(Config config) { var dir = config.File.Directory; @@ -173,14 +178,24 @@ namespace IPA.Config { while (true) { - var configArr = configs.ToArray(); - var waitHandles = configArr.Select(c => c.Store.SyncObject) - .Prepend(configsChangedWatcher) - .ToArray(); - var index = WaitHandle.WaitAny(waitHandles); - - if (index == 0) - { // we got a signal that the configs collection changed, loop around + var configArr = configs.Where(c => c.Store != null).ToArray(); + int index = -1; + try + { + var waitHandles = configArr.Select(c => c.Store.SyncObject) + .Prepend(configsChangedWatcher) + .ToArray(); + index = WaitHandle.WaitAny(waitHandles); + } + catch (Exception e) + { + Logger.config.Error($"Error waiting for in-memory updates"); + Logger.config.Error(e); + Thread.Sleep(TimeSpan.FromSeconds(1)); + } + + if (index <= 0) + { // we got a signal that the configs collection changed, loop around, or errored continue; } diff --git a/IPA.Loader/Config/SelfConfig.cs b/IPA.Loader/Config/SelfConfig.cs index 5e9a7cf1..57501262 100644 --- a/IPA.Loader/Config/SelfConfig.cs +++ b/IPA.Loader/Config/SelfConfig.cs @@ -20,6 +20,7 @@ namespace IPA.Config { LoaderConfig = Config.GetConfigFor(IPAName, "json"); Instance = LoaderConfig.Generated(); + GeneratedStore.DebugSaveAssembly("GeneratedAssembly.dll"); } public static void ReadCommandLine(string[] args) diff --git a/IPA.Loader/Config/Stores/GeneratedStore.cs b/IPA.Loader/Config/Stores/GeneratedStore.cs index 8487dbb6..7d2549b2 100644 --- a/IPA.Loader/Config/Stores/GeneratedStore.cs +++ b/IPA.Loader/Config/Stores/GeneratedStore.cs @@ -9,11 +9,15 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using System.Linq.Expressions; +using System.Runtime.CompilerServices; +using System.IO; #if NET3 using Net3_Proxy; using Array = Net3_Proxy.Array; #endif +[assembly: InternalsVisibleTo(IPA.Config.Stores.GeneratedStore.GeneratedAssemblyName)] + namespace IPA.Config.Stores { /// @@ -54,7 +58,7 @@ namespace IPA.Config.Stores internal static class GeneratedStore { - private interface IGeneratedStore + internal interface IGeneratedStore { /// /// serializes/deserializes to Value @@ -65,7 +69,7 @@ namespace IPA.Config.Stores Impl Impl { get; } } - private class Impl : IConfigStore + internal class Impl : IConfigStore { private IGeneratedStore generated; @@ -80,27 +84,27 @@ namespace IPA.Config.Stores internal static MethodInfo WriteSyncObjectGetMethod = typeof(Impl).GetProperty(nameof(WriteSyncObject)).GetGetMethod(); internal static MethodInfo ImplSignalChangedMethod = typeof(Impl).GetMethod(nameof(ImplSignalChanged)); - internal static void ImplSignalChanged(IGeneratedStore s) => FindImpl(s).SignalChanged(); - internal void SignalChanged() => resetEvent.Set(); + public static void ImplSignalChanged(IGeneratedStore s) => FindImpl(s).SignalChanged(); + public void SignalChanged() => resetEvent.Set(); internal static MethodInfo ImplTakeReadMethod = typeof(Impl).GetMethod(nameof(ImplTakeRead)); - internal static void ImplTakeRead(IGeneratedStore s) => FindImpl(s).TakeRead(); - internal void TakeRead() => WriteSyncObject.EnterReadLock(); + public static void ImplTakeRead(IGeneratedStore s) => FindImpl(s).TakeRead(); + public void TakeRead() => WriteSyncObject.EnterReadLock(); internal static MethodInfo ImplReleaseReadMethod = typeof(Impl).GetMethod(nameof(ImplReleaseRead)); - internal static void ImplReleaseRead(IGeneratedStore s) => FindImpl(s).ReleaseRead(); - internal void ReleaseRead() => WriteSyncObject.ExitWriteLock(); + public static void ImplReleaseRead(IGeneratedStore s) => FindImpl(s).ReleaseRead(); + public void ReleaseRead() => WriteSyncObject.ExitWriteLock(); internal static MethodInfo ImplTakeWriteMethod = typeof(Impl).GetMethod(nameof(ImplTakeWrite)); - internal static void ImplTakeWrite(IGeneratedStore s) => FindImpl(s).TakeWrite(); - internal void TakeWrite() => WriteSyncObject.EnterWriteLock(); + public static void ImplTakeWrite(IGeneratedStore s) => FindImpl(s).TakeWrite(); + public void TakeWrite() => WriteSyncObject.EnterWriteLock(); internal static MethodInfo ImplReleaseWriteMethod = typeof(Impl).GetMethod(nameof(ImplReleaseWrite)); - internal static void ImplReleaseWrite(IGeneratedStore s) => FindImpl(s).ReleaseWrite(); - internal void ReleaseWrite() => WriteSyncObject.ExitWriteLock(); + public static void ImplReleaseWrite(IGeneratedStore s) => FindImpl(s).ReleaseWrite(); + public void ReleaseWrite() => WriteSyncObject.ExitWriteLock(); internal static MethodInfo FindImplMethod = typeof(Impl).GetMethod(nameof(FindImpl)); - internal static Impl FindImpl(IGeneratedStore store) + public static Impl FindImpl(IGeneratedStore store) { while (store != null) store = store.Parent; // walk to the top of the tree return store?.Impl; @@ -144,6 +148,8 @@ namespace IPA.Config.Stores } } + internal const string GeneratedAssemblyName = "IPA.Config.Generated"; + private static AssemblyBuilder assembly = null; private static AssemblyBuilder Assembly { @@ -151,20 +157,26 @@ namespace IPA.Config.Stores { if (assembly == null) { - var name = new AssemblyName("IPA.Config.Generated"); + var name = new AssemblyName(GeneratedAssemblyName); assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave); } return assembly; } } + + internal static void DebugSaveAssembly(string file) + { + Assembly.Save(file); + } + private static ModuleBuilder module = null; private static ModuleBuilder Module { get { if (module == null) - module = Assembly.DefineDynamicModule(Assembly.GetName().Name); + module = Assembly.DefineDynamicModule(Assembly.GetName().Name + ".dll"); return module; } @@ -412,7 +424,7 @@ namespace IPA.Config.Stores typeBuilder.DefineMethodOverride(readFrom, IConfigStore_ReadFrom); { - var il = writeTo.GetILGenerator(); + var il = readFrom.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, Impl.FindImplMethod);