Browse Source

Added a bunch of checks to streamline upgrades

pull/46/head
Anairkoen Schno 4 years ago
parent
commit
94cb350c88
5 changed files with 91 additions and 47 deletions
  1. +12
    -3
      Doorstop/Proxy/main.c
  2. +1
    -0
      Doorstop/Proxy/proxy.def
  3. +17
    -11
      IPA.Loader/Config/ConfigRuntime.cs
  4. +28
    -12
      IPA.Loader/Config/Stores/GeneratedStoreImpl/IGeneratedStore.cs
  5. +33
    -21
      IPA.Loader/Utilities/CriticalSection.cs

+ 12
- 3
Doorstop/Proxy/main.c View File

@ -38,8 +38,14 @@ EXTERN_C IMAGE_DOS_HEADER __ImageBase; // This is provided by MSVC with the info
HANDLE unhandledMutex; HANDLE unhandledMutex;
void ownMonoJitParseOptions(int argc, char * argv[]); void ownMonoJitParseOptions(int argc, char * argv[]);
BOOL setOptions = FALSE; BOOL setOptions = FALSE;
BOOL shouldBreakOnUnhandledException = TRUE;
void unhandledException(void* exc, void* data)
__declspec(dllexport) void SetIgnoreUnhandledExceptions(BOOL ignore)
{
shouldBreakOnUnhandledException = ignore;
}
void unhandledException(void* exc, void* data)
{ {
WaitForSingleObject(unhandledMutex, INFINITE); WaitForSingleObject(unhandledMutex, INFINITE);
@ -86,11 +92,14 @@ void unhandledException(void* exc, void* data)
MultiByteToWideChar(CP_UTF8, 0, str, -1, wstr, len);*/ MultiByteToWideChar(CP_UTF8, 0, str, -1, wstr, len);*/
wchar_t* wstr = mono_string_to_utf16(mstr); wchar_t* wstr = mono_string_to_utf16(mstr);
if (shouldBreakOnUnhandledException)
{
#ifdef _VERBOSE #ifdef _VERBOSE
ASSERT(FALSE, L"Uncaught exception; see doorstop.log for details");
ASSERT(FALSE, L"Uncaught exception; see doorstop.log for details");
#else #else
ASSERT_F(FALSE, L"Uncaught exception: %wS", wstr);
ASSERT_F(FALSE, L"Uncaught exception: %wS", wstr);
#endif #endif
}
mono_free(wstr); mono_free(wstr);
mono_free(str); mono_free(str);


+ 1
- 0
Doorstop/Proxy/proxy.def View File

@ -52,3 +52,4 @@ EXPORTS
WinHttpWriteData @50 WinHttpWriteData @50
SetGetMessageHook @51 SetGetMessageHook @51
SetPeekMessageHook @52 SetPeekMessageHook @52
SetIgnoreUnhandledExceptions @53

+ 17
- 11
IPA.Loader/Config/ConfigRuntime.cs View File

@ -64,17 +64,23 @@ namespace IPA.Config
=> ShutdownRuntime(); => ShutdownRuntime();
internal static void ShutdownRuntime() internal static void ShutdownRuntime()
{ {
watcherTrackConfigs.Clear();
var watchList = watchers.ToArray();
watchers.Clear();
foreach (var pair in watchList)
pair.Value.EnableRaisingEvents = false;
loadScheduler.Join(); // we can wait for the loads to finish
saveThread.Abort(); // eww, but i don't like any of the other potential solutions
SaveAll();
try
{
watcherTrackConfigs.Clear();
var watchList = watchers.ToArray();
watchers.Clear();
foreach (var pair in watchList)
pair.Value.EnableRaisingEvents = false;
loadScheduler.Join(); // we can wait for the loads to finish
saveThread.Abort(); // eww, but i don't like any of the other potential solutions
SaveAll();
}
catch
{
}
} }
public static void RegisterConfig(Config cfg) public static void RegisterConfig(Config cfg)


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

@ -59,7 +59,18 @@ namespace IPA.Config.Stores
internal static MethodInfo ImplSignalChangedMethod = typeof(Impl).GetMethod(nameof(ImplSignalChanged)); internal static MethodInfo ImplSignalChangedMethod = typeof(Impl).GetMethod(nameof(ImplSignalChanged));
public static void ImplSignalChanged(IGeneratedStore s) => FindImpl(s).SignalChanged(); public static void ImplSignalChanged(IGeneratedStore s) => FindImpl(s).SignalChanged();
public void SignalChanged() => resetEvent.Set();
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);
}
}
internal static MethodInfo ImplInvokeChangedMethod = typeof(Impl).GetMethod(nameof(ImplInvokeChanged)); internal static MethodInfo ImplInvokeChangedMethod = typeof(Impl).GetMethod(nameof(ImplInvokeChanged));
public static void ImplInvokeChanged(IGeneratedStore s) => FindImpl(s).InvokeChanged(); public static void ImplInvokeChanged(IGeneratedStore s) => FindImpl(s).InvokeChanged();
@ -131,18 +142,23 @@ namespace IPA.Config.Stores
public void Dispose() => Dispose(true); public void Dispose() => Dispose(true);
private void Dispose(bool addToStore) private void Dispose(bool addToStore)
{
if (data.owns)
{
data.impl.inChangeTransaction = false;
data.impl.InvokeChanged();
}
{
if (data.owns)
{
data.impl.inChangeTransaction = false;
data.impl.InvokeChanged();
}
data.nested?.Dispose(); data.nested?.Dispose();
if (data.ownsWrite)
data.impl.ReleaseWrite();
if (addToStore)
freeTransactionObjs.Push(this);
try
{
if (data.ownsWrite)
data.impl.ReleaseWrite();
}
catch
{
}
if (addToStore)
freeTransactionObjs.Push(this);
} }
~ChangeTransactionObj() => Dispose(false); ~ChangeTransactionObj() => Dispose(false);


+ 33
- 21
IPA.Loader/Utilities/CriticalSection.cs View File

@ -35,6 +35,14 @@ namespace IPA.Utilities
Win32.SetConsoleCtrlHandler(registeredHandler, false); Win32.SetConsoleCtrlHandler(registeredHandler, false);
Win32.SetConsoleCtrlHandler(registeredHandler, true); Win32.SetConsoleCtrlHandler(registeredHandler, true);
WinHttp.SetPeekMessageHook(PeekMessageHook); WinHttp.SetPeekMessageHook(PeekMessageHook);
AppDomain.CurrentDomain.ProcessExit -= OnProcessExit;
AppDomain.CurrentDomain.ProcessExit += OnProcessExit;
}
private static void OnProcessExit(object sender, EventArgs args)
{
WinHttp.SetIgnoreUnhandledExceptions(true);
} }
private static class WinHttp private static class WinHttp
@ -52,7 +60,11 @@ namespace IPA.Utilities
[DllImport("bsipa-doorstop")] [DllImport("bsipa-doorstop")]
public static extern void SetPeekMessageHook( public static extern void SetPeekMessageHook(
[MarshalAs(UnmanagedType.FunctionPtr)] [MarshalAs(UnmanagedType.FunctionPtr)]
PeekMessageHook hook);
PeekMessageHook hook);
[DllImport("bsipa-doorstop")]
public static extern void SetIgnoreUnhandledExceptions(
[MarshalAs(UnmanagedType.Bool)] bool ignore);
} }
private static Win32.ConsoleCtrlDelegate _handler = null; private static Win32.ConsoleCtrlDelegate _handler = null;
@ -106,29 +118,29 @@ namespace IPA.Utilities
private static volatile bool exitRecieved = false; private static volatile bool exitRecieved = false;
/// <summary>
/// A struct that allows <c>using</c> blocks to manage an execute section.
/// <summary>
/// A struct that allows <c>using</c> blocks to manage an execute section.
/// </summary> /// </summary>
public struct AutoExecuteSection : IDisposable
{
private readonly bool constructed;
internal AutoExecuteSection(bool val)
{
constructed = val && !isInExecuteSection;
if (constructed)
EnterExecuteSection();
}
void IDisposable.Dispose()
{
if (constructed)
ExitExecuteSection();
}
public struct AutoExecuteSection : IDisposable
{
private readonly bool constructed;
internal AutoExecuteSection(bool val)
{
constructed = val && !isInExecuteSection;
if (constructed)
EnterExecuteSection();
}
void IDisposable.Dispose()
{
if (constructed)
ExitExecuteSection();
}
} }
/// <summary>
/// Creates an <see cref="AutoExecuteSection"/> for automated management of an execute section.
/// </summary>
/// <summary>
/// Creates an <see cref="AutoExecuteSection"/> for automated management of an execute section.
/// </summary>
/// <returns>the new <see cref="AutoExecuteSection"/> that manages the section</returns> /// <returns>the new <see cref="AutoExecuteSection"/> that manages the section</returns>
public static AutoExecuteSection ExecuteSection() => new AutoExecuteSection(true); public static AutoExecuteSection ExecuteSection() => new AutoExecuteSection(true);


Loading…
Cancel
Save