Browse Source

Updated CurrentTime() fallback to use Interlocked for proper thread safety

pull/44/head
Anairkoen Schno 4 years ago
parent
commit
2ab88bf00e
2 changed files with 19 additions and 18 deletions
  1. +4
    -4
      IPA.Loader/Loader/LibLoader.cs
  2. +15
    -14
      IPA.Loader/Utilities/Utils.cs

+ 4
- 4
IPA.Loader/Loader/LibLoader.cs View File

@ -40,8 +40,8 @@ namespace IPA.Loader
if (File.Exists(path))
return AssemblyDefinition.ReadAssembly(path, parameters);
}
return base.Resolve(name, parameters);
}
}
@ -121,8 +121,8 @@ namespace IPA.Loader
SetupAssemblyFilenames();
var testFile = $"{asmName.Name}.dll";
Log(Logger.Level.Debug, $"Looking for file {asmName.Name}.dll");
Log(Logger.Level.Debug, $"Looking for file {asmName.Name}.dll");
if (FilenameLocations.TryGetValue(testFile, out var path))
{
Log(Logger.Level.Debug, $"Found file {testFile} as {path}");


+ 15
- 14
IPA.Loader/Utilities/Utils.cs View File

@ -5,10 +5,11 @@ using System.Linq;
using System.Collections.Generic;
using Mono.Cecil;
using System.Runtime.CompilerServices;
using System.Threading;
#if NET3
using File = Net3_Proxy.File;
#endif
namespace IPA.Utilities
{
/// <summary>
@ -143,7 +144,7 @@ namespace IPA.Utilities
/// <value><see langword="true"/> if you can use <see cref="DateTime.Now"/> safely, <see langword="false"/> otherwise</value>
public static bool CanUseDateTimeNowSafely { get; private set; } = true;
private static bool DateTimeSafetyUnknown = true;
private static ulong UnsafeAdvanceTicks = 1;
private static long UnsafeAdvanceTicks = 1;
/// <summary>
/// Gets the current <see cref="DateTime"/> if supported, otherwise, if Mono would throw a fit,
@ -170,7 +171,7 @@ namespace IPA.Utilities
else
{
if (CanUseDateTimeNowSafely) return DateTime.Now;
else return DateTime.MinValue.AddTicks((long)UnsafeAdvanceTicks++); // return MinValue as a fallback
else return DateTime.MinValue.AddTicks(Interlocked.Increment(ref UnsafeAdvanceTicks)); // return MinValue as a fallback
}
}
@ -190,8 +191,8 @@ namespace IPA.Utilities
return cmpVal;
}
/// <summary>
/// An object used to manage scope guards.
/// <summary>
/// An object used to manage scope guards.
/// </summary>
/// <example>
/// <code>
@ -199,12 +200,12 @@ namespace IPA.Utilities
/// </code>
/// </example>
/// <seealso cref="ScopeGuard(Action)"/>
public struct ScopeGuardObject : IDisposable
{
public struct ScopeGuardObject : IDisposable
{
private readonly Action action;
/// <summary>
/// Creates a new scope guard that will invoke <paramref name="action"/> when disposed.
/// </summary>
/// <summary>
/// Creates a new scope guard that will invoke <paramref name="action"/> when disposed.
/// </summary>
/// <param name="action">the action to run on dispose</param>
public ScopeGuardObject(Action action)
=> this.action = action;
@ -212,10 +213,10 @@ namespace IPA.Utilities
=> action?.Invoke();
}
/// <summary>
/// Creates a scope guard for a given <see cref="Action"/>.
/// </summary>
/// <param name="action">the <see cref="Action"/> to run on dispose</param>
/// <summary>
/// Creates a scope guard for a given <see cref="Action"/>.
/// </summary>
/// <param name="action">the <see cref="Action"/> to run on dispose</param>
/// <returns>a <see cref="ScopeGuardObject"/> that will run <paramref name="action"/> on disposal</returns>
/// <example>
/// <code>


Loading…
Cancel
Save