Browse Source

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

pull/46/head
Anairkoen Schno 4 years ago
parent
commit
1bc6c5dc94
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)) if (File.Exists(path))
return AssemblyDefinition.ReadAssembly(path, parameters); return AssemblyDefinition.ReadAssembly(path, parameters);
} }
return base.Resolve(name, parameters); return base.Resolve(name, parameters);
} }
} }
@ -121,8 +121,8 @@ namespace IPA.Loader
SetupAssemblyFilenames(); SetupAssemblyFilenames();
var testFile = $"{asmName.Name}.dll"; 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)) if (FilenameLocations.TryGetValue(testFile, out var path))
{ {
Log(Logger.Level.Debug, $"Found file {testFile} as {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 System.Collections.Generic;
using Mono.Cecil; using Mono.Cecil;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Threading;
#if NET3 #if NET3
using File = Net3_Proxy.File; using File = Net3_Proxy.File;
#endif #endif
namespace IPA.Utilities namespace IPA.Utilities
{ {
/// <summary> /// <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> /// <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; public static bool CanUseDateTimeNowSafely { get; private set; } = true;
private static bool DateTimeSafetyUnknown = true; private static bool DateTimeSafetyUnknown = true;
private static ulong UnsafeAdvanceTicks = 1;
private static long UnsafeAdvanceTicks = 1;
/// <summary> /// <summary>
/// Gets the current <see cref="DateTime"/> if supported, otherwise, if Mono would throw a fit, /// Gets the current <see cref="DateTime"/> if supported, otherwise, if Mono would throw a fit,
@ -170,7 +171,7 @@ namespace IPA.Utilities
else else
{ {
if (CanUseDateTimeNowSafely) return DateTime.Now; 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; return cmpVal;
} }
/// <summary>
/// An object used to manage scope guards.
/// <summary>
/// An object used to manage scope guards.
/// </summary> /// </summary>
/// <example> /// <example>
/// <code> /// <code>
@ -199,12 +200,12 @@ namespace IPA.Utilities
/// </code> /// </code>
/// </example> /// </example>
/// <seealso cref="ScopeGuard(Action)"/> /// <seealso cref="ScopeGuard(Action)"/>
public struct ScopeGuardObject : IDisposable
{
public struct ScopeGuardObject : IDisposable
{
private readonly Action action; 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> /// <param name="action">the action to run on dispose</param>
public ScopeGuardObject(Action action) public ScopeGuardObject(Action action)
=> this.action = action; => this.action = action;
@ -212,10 +213,10 @@ namespace IPA.Utilities
=> action?.Invoke(); => 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> /// <returns>a <see cref="ScopeGuardObject"/> that will run <paramref name="action"/> on disposal</returns>
/// <example> /// <example>
/// <code> /// <code>


Loading…
Cancel
Save