Decompiled source of Adaptive Trigger For PSVR2 v1.0.0
Niko666.Adaptive_Trigger_For_PSVR2.dll
Decompiled a month agousing System; using System.CodeDom.Compiler; using System.Configuration; using System.Diagnostics; using System.Net.Sockets; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Threading; using System.Threading.Tasks; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using FistVR; using HarmonyLib; using Microsoft.CodeAnalysis; using PSVR2Toolkit.CAPI; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCompany("Niko666")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Implemented some Adaptive Trigger effects for chad PSVR2 controller enjoyers. REQUIRES PSVR2 Toolkit TO USE!")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Niko666.Adaptive_Trigger_For_PSVR2")] [assembly: AssemblyTitle("Adaptive_Trigger_For_PSVR2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string id = null, string name = null, string version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string id = null, string name = null, string version = null) { } } } namespace Niko666 { [BepInProcess("h3vr.exe")] [BepInPlugin("Niko666.Adaptive_Trigger_For_PSVR2", "Adaptive_Trigger_For_PSVR2", "1.0.0")] public class AdaptiveTrigger : BaseUnityPlugin { public static ConfigEntry<byte> ClickyEffectStrength; public static ConfigEntry<byte> RecoilFeedbackStrength; public static ConfigEntry<bool> UseVibrationFeedbackForRecoil; public static ConfigEntry<byte> VibrationFrequency; public static int _shotsSoFar; public const string Id = "Niko666.Adaptive_Trigger_For_PSVR2"; internal static ManualLogSource Logger { get; private set; } public static string Name => "Adaptive_Trigger_For_PSVR2"; public static string Version => "1.0.0"; public void Awake() { ClickyEffectStrength = ((BaseUnityPlugin)this).Config.Bind<byte>("General", "ClickyEffectStrength", (byte)4, "Effect strength of clicky trigger effect. (0-8)"); RecoilFeedbackStrength = ((BaseUnityPlugin)this).Config.Bind<byte>("General", "RecoilFeedbackStrength", (byte)8, "Effect strength of firearm recoil effect. (0-8)"); UseVibrationFeedbackForRecoil = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "UseVibrationFeedbackForRecoil", false, "Use vibration-based feedback for recoil effect. By default the mod use force-based feedback to emulate the recoil \"kick\" effect, but it doesn't work well with high rate of fire weapons when doing full-auto shooting. Turning this option on will make the trigger vibrates instead of kicking, which is more suitable for full-auto shooting but worse the feeling when single-shot. "); VibrationFrequency = ((BaseUnityPlugin)this).Config.Bind<byte>("General", "VibrationFrequency", (byte)50, "Vibration frequency for recoil effect when 'UseVibrationFeedbackForRecoil' is enabled. (1-255)"); Logger = ((BaseUnityPlugin)this).Logger; if (!IpcClient.Instance().IsRunning) { if (IpcClient.Instance().Start()) { Logger.LogMessage((object)"PSVR2 Toolkit IPC Connected."); Harmony.CreateAndPatchAll(typeof(AdaptiveTriggerPatch), (string)null); Logger.LogMessage((object)("Fuck this world! Sent from Niko666.Adaptive_Trigger_For_PSVR2 " + Version)); } else { Logger.LogMessage((object)"Failed to connect PSVR2 Toolkit IPC. Did you install PSVR2 Toolkit properly?"); } } } public void OnDestroy() { IpcClient.Instance().TriggerEffectDisable(EVRControllerType.Both); Thread.Sleep(20); IpcClient.Instance().Stop(); Logger.LogMessage((object)"PSVR2 Toolkit IPC disconnected. It is now safe to turn off your computer."); } public static void ShotFired(FVRFireArm fireArm) { if ((Object)(object)((FVRInteractiveObject)fireArm).m_hand != (Object)null) { _shotsSoFar++; } } } internal class AdaptiveTriggerPatch : MonoBehaviour { [CompilerGenerated] private static class <>O { public static ShotFired <0>__ShotFired; } [HarmonyPatch(typeof(FVRViveHand), "Update")] [HarmonyPostfix] public static void ClearEffectOnDrop(FVRViveHand __instance) { bool flag = false; if ((Object)(object)__instance.CurrentInteractable == (Object)null && !flag) { IpcClient.Instance().TriggerEffectDisable(__instance.IsThisTheRightHand ? EVRControllerType.Right : EVRControllerType.Left); flag = true; } else { flag = false; } } [HarmonyPatch(typeof(FVRFireArm), "Awake")] [HarmonyPostfix] public static void ShotDetect(FVRFireArm __instance) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown FVRSceneSettings currentSceneSettings = GM.CurrentSceneSettings; object obj = <>O.<0>__ShotFired; if (obj == null) { ShotFired val = AdaptiveTrigger.ShotFired; <>O.<0>__ShotFired = val; obj = (object)val; } currentSceneSettings.ShotFiredEvent += (ShotFired)obj; } [HarmonyPatch(typeof(FVRFireArm), "FVRUpdate")] [HarmonyPostfix] public static void GlobalRecoilEffect(FVRFireArm __instance) { byte b = 2; byte b2 = 7; bool flag = false; if ((Object)(object)((FVRInteractiveObject)__instance).m_hand != (Object)null) { if (!flag) { ClosedBoltWeapon val = (ClosedBoltWeapon)(object)((__instance is ClosedBoltWeapon) ? __instance : null); if (val == null) { OpenBoltReceiver val2 = (OpenBoltReceiver)(object)((__instance is OpenBoltReceiver) ? __instance : null); if (val2 == null) { Handgun val3 = (Handgun)(object)((__instance is Handgun) ? __instance : null); if (val3 == null) { TubeFedShotgun val4 = (TubeFedShotgun)(object)((__instance is TubeFedShotgun) ? __instance : null); if (val4 == null) { BoltActionRifle val5 = (BoltActionRifle)(object)((__instance is BoltActionRifle) ? __instance : null); if (val5 == null) { if (!(__instance is BreakActionWeapon)) { if (!(__instance is Revolver)) { SingleActionRevolver val6 = (SingleActionRevolver)(object)((__instance is SingleActionRevolver) ? __instance : null); if (val6 == null) { RevolvingShotgun val7 = (RevolvingShotgun)(object)((__instance is RevolvingShotgun) ? __instance : null); if (val7 == null) { LAPD2019 val8 = (LAPD2019)(object)((__instance is LAPD2019) ? __instance : null); if (val8 == null) { BAP val9 = (BAP)(object)((__instance is BAP) ? __instance : null); if (val9 == null) { if (!(__instance is PotatoGun)) { GrappleGun val10 = (GrappleGun)(object)((__instance is GrappleGun) ? __instance : null); if (val10 == null) { Airgun val11 = (Airgun)(object)((__instance is Airgun) ? __instance : null); if (val11 == null) { CarlGustaf val12 = (CarlGustaf)(object)((__instance is CarlGustaf) ? __instance : null); if (val12 == null) { RailTater val13 = (RailTater)(object)((__instance is RailTater) ? __instance : null); if (val13 == null) { FlameThrower val14 = (FlameThrower)(object)((__instance is FlameThrower) ? __instance : null); if (val14 == null) { sblp val15 = (sblp)(object)((__instance is sblp) ? __instance : null); if (val15 != null) { b = (byte)(val15.TriggerResetThreshold * 10f - 1f); b2 = (byte)(val15.TriggerFiringThreshold * 10f - 1f); } else { b = 2; b2 = 7; } } else { b = 3; b2 = (byte)(val14.TriggerFiringThreshold * 10f - 1f); } } else { b = (byte)(val13.TriggerResetThreshold * 10f - 1f); b2 = (byte)(val13.TriggerFiringThreshold * 10f - 1f); } } else { b = (byte)(val12.TriggerResetThreshold * 10f - 1f); b2 = (byte)(val12.TriggerFiringThreshold * 10f - 1f); } } else { b = (byte)(val11.TriggerResetThreshold * 10f - 1f); b2 = (byte)(val11.TriggerFiringThreshold * 10f - 1f); } } else { b = (byte)(val10.TriggerResetThreshold * 10f - 1f); b2 = (byte)(val10.TriggerBreakThreshold * 10f - 1f); } } else { b = 4; b2 = 7; } } else { b = (byte)(val9.TriggerResetThreshold * 10f - 1f); b2 = (byte)(val9.TriggerFiringThreshold * 10f - 1f); } } else { b = (byte)(val8.TriggerResetThreshold * 10f - 1f); b2 = (byte)(val8.TriggerFireThreshold * 10f - 1f); } } else { b = (byte)(val7.TriggerResetThreshold * 10f - 1f); b2 = (byte)(val7.TriggerFiringThreshold * 10f - 1f); } } else { b = (byte)(val6.TriggerThreshold * 10f - 2f); b2 = (byte)(val6.TriggerThreshold * 10f - 1f); } } else { b = 2; b2 = 9; } } else { b = 4; b2 = 7; } } else { b = (byte)(val5.TriggerResetThreshold * 10f - 1f); b2 = (byte)(val5.TriggerFiringThreshold * 10f - 1f); } } else { b = (byte)(val4.TriggerResetThreshold * 10f - 1f); b2 = (byte)(val4.TriggerBreakThreshold * 10f - 1f); } } else { b = (byte)(val3.TriggerResetThreshold * 10f - 1f); b2 = (byte)(val3.TriggerBreakThreshold * 10f - 1f); } } else { b = (byte)(val2.TriggerResetThreshold * 10f - 1f); b2 = (byte)(val2.TriggerFiringThreshold * 10f - 1f); } } else { b = (byte)(val.TriggerResetThreshold * 10f - 1f); b2 = (byte)(val.TriggerFiringThreshold * 10f - 1f); } flag = true; } if (AdaptiveTrigger._shotsSoFar != 0) { if (AdaptiveTrigger.UseVibrationFeedbackForRecoil.Value) { IpcClient.Instance().TriggerEffectVibration(((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? EVRControllerType.Right : EVRControllerType.Left, (byte)(b - 1), AdaptiveTrigger.RecoilFeedbackStrength.Value, AdaptiveTrigger.VibrationFrequency.Value); } else { IpcClient.Instance().TriggerEffectFeedback(((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? EVRControllerType.Right : EVRControllerType.Left, (byte)(b - 1), AdaptiveTrigger.RecoilFeedbackStrength.Value); } if (((FVRInteractiveObject)__instance).m_hand.m_buzztime > 0.02f) { IpcClient.Instance().TriggerEffectSlopeFeedback(((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? EVRControllerType.Right : EVRControllerType.Left, (byte)(b - 1), (byte)(b2 - 1), 1, AdaptiveTrigger.ClickyEffectStrength.Value); AdaptiveTrigger._shotsSoFar = 0; } } else { IpcClient.Instance().TriggerEffectSlopeFeedback(((FVRInteractiveObject)__instance).m_hand.IsThisTheRightHand ? EVRControllerType.Right : EVRControllerType.Left, (byte)(b - 1), (byte)(b2 - 1), 1, AdaptiveTrigger.ClickyEffectStrength.Value); } } else { flag = false; } } } } namespace PSVR2Toolkit.CAPI { public class IpcClient { private const ushort IPC_SERVER_PORT = 3364; private const ushort k_unIpcVersion = 2; private static IpcClient m_pInstance; private bool m_running; private TcpClient? m_client; private NetworkStream? m_stream; private Thread? m_receiveThread; private readonly object m_gazeStateLock = new object(); private TaskCompletionSource<CommandDataServerGazeDataResult>? m_gazeTask; private CancellationTokenSource m_forceShutdownToken; private ushort m_serverIpcVersion = 2; private int m_gazePumpPeriodMs = 8; private CommandDataServerGazeDataResult2? m_lastGazeState; public bool IsRunning => m_running; public static IpcClient Instance() { if (m_pInstance == null) { m_pInstance = new IpcClient(); } return m_pInstance; } public bool Start() { if (m_running) { return false; } try { m_client = new TcpClient(); m_client.Connect("127.0.0.1", 3364); if (m_client.Connected) { m_stream = m_client.GetStream(); m_running = true; m_forceShutdownToken = new CancellationTokenSource(); m_receiveThread = new Thread((ThreadStart)delegate { ReceiveLoop(m_forceShutdownToken.Token); }); m_receiveThread.Start(); return true; } return false; } catch (SocketException ex) { Console.WriteLine($"[IPC_CLIENT] Connection failed. LastError = {ex.SocketErrorCode}"); return false; } } public void Stop() { if (m_running) { m_running = false; m_forceShutdownToken.Cancel(); lock (m_gazeStateLock) { m_gazeTask?.TrySetCanceled(); m_gazeTask = null; } try { m_stream?.Close(); m_client?.Close(); } catch { } if (m_receiveThread != null && m_receiveThread.IsAlive && !m_receiveThread.Join(2000)) { m_receiveThread.Interrupt(); } m_stream?.Dispose(); m_client?.Close(); m_forceShutdownToken.Dispose(); } } private void ReceiveLoop(CancellationToken token) { byte[] array = new byte[1024]; try { Socket client = m_client.Client; m_stream.ReadTimeout = 1; CommandDataClientRequestHandshake commandDataClientRequestHandshake = default(CommandDataClientRequestHandshake); commandDataClientRequestHandshake.ipcVersion = 2; commandDataClientRequestHandshake.processId = (uint)Process.GetCurrentProcess().Id; CommandDataClientRequestHandshake data = commandDataClientRequestHandshake; SendIpcCommand(ECommandType.ClientRequestHandshake, data); Stopwatch stopwatch = Stopwatch.StartNew(); long num = stopwatch.ElapsedMilliseconds; while (m_running && !token.IsCancellationRequested) { long elapsedMilliseconds = stopwatch.ElapsedMilliseconds; if (elapsedMilliseconds >= num) { SendIpcCommand(ECommandType.ClientRequestGazeData); num = elapsedMilliseconds + m_gazePumpPeriodMs; } if (client.Poll(1000, SelectMode.SelectRead) && client.Available > 0) { int available = client.Available; if (available > array.Length) { array = new byte[Math.Max(available, array.Length * 2)]; } int num2 = m_stream.Read(array, 0, Math.Min(array.Length, available)); if (num2 <= 0) { Console.WriteLine("[IPC_CLIENT] Disconnected from server."); break; } if (num2 < Marshal.SizeOf(typeof(CommandHeader))) { Console.WriteLine("[IPC_CLIENT] Received invalid command header size."); } else { HandleIpcCommand(array, num2); } } else { Thread.Sleep(1); } } } catch (Exception ex) { if (m_running) { Console.WriteLine("[IPC_CLIENT] Error in receive loop: " + ex.Message); } } } private GazeEyeResult2 UpgradeGazeEyeResult(GazeEyeResult eye) { GazeEyeResult2 result = default(GazeEyeResult2); result.isGazeOriginValid = eye.isGazeOriginValid; result.gazeOriginMm = eye.gazeOriginMm; result.isGazeDirValid = eye.isGazeDirValid; result.gazeDirNorm = eye.gazeDirNorm; result.isPupilDiaValid = eye.isPupilDiaValid; result.pupilDiaMm = eye.pupilDiaMm; result.isBlinkValid = eye.isBlinkValid; result.blink = eye.blink; result.isOpenEnabled = false; result.open = 0f; return result; } private CommandDataServerGazeDataResult2 UpgradeGazeDataResult(CommandDataServerGazeDataResult result) { CommandDataServerGazeDataResult2 result2 = default(CommandDataServerGazeDataResult2); result2.leftEye = UpgradeGazeEyeResult(result.leftEye); result2.rightEye = UpgradeGazeEyeResult(result.rightEye); return result2; } private void HandleIpcCommand(byte[] pBuffer, int bytesReceived) { CommandHeader commandHeader = ByteArrayToStructure<CommandHeader>(pBuffer, 0); switch (commandHeader.type) { case ECommandType.ServerPong: Console.WriteLine("[IPC_CLIENT] Received Pong from server."); break; case ECommandType.ServerHandshakeResult: if (commandHeader.dataLen == Marshal.SizeOf(typeof(CommandDataServerHandshakeResult))) { CommandDataServerHandshakeResult commandDataServerHandshakeResult = ByteArrayToStructure<CommandDataServerHandshakeResult>(pBuffer, Marshal.SizeOf(typeof(CommandHeader))); m_serverIpcVersion = commandDataServerHandshakeResult.ipcVersion; switch (commandDataServerHandshakeResult.result) { case EHandshakeResult.Success: Console.WriteLine("[IPC_CLIENT] Handshake successful!"); break; case EHandshakeResult.Failed: Console.WriteLine("[IPC_CLIENT] Handshake failed!"); break; case EHandshakeResult.Outdated: Console.WriteLine($"[IPC_CLIENT] Handshake failed with reason: Outdated client. Please upgrade to an IPC version of {commandDataServerHandshakeResult.ipcVersion}"); break; } } break; case ECommandType.ServerGazeDataResult: if (m_serverIpcVersion == 1) { if (commandHeader.dataLen == Marshal.SizeOf(typeof(CommandDataServerGazeDataResult))) { CommandDataServerGazeDataResult result = ByteArrayToStructure<CommandDataServerGazeDataResult>(pBuffer, Marshal.SizeOf(typeof(CommandHeader))); m_lastGazeState = UpgradeGazeDataResult(result); } } else if (commandHeader.dataLen == Marshal.SizeOf(typeof(CommandDataServerGazeDataResult2))) { CommandDataServerGazeDataResult2 value = ByteArrayToStructure<CommandDataServerGazeDataResult2>(pBuffer, Marshal.SizeOf(typeof(CommandHeader))); m_lastGazeState = value; } break; case ECommandType.ClientRequestHandshake: case ECommandType.ClientRequestGazeData: break; } } private void SendIpcCommand<T>(ECommandType type, T data = default(T)) where T : struct { if (m_running) { int num = ((!data.Equals(default(T))) ? Marshal.SizeOf(typeof(T)) : 0); byte[] array = new byte[Marshal.SizeOf(typeof(CommandHeader)) + num]; CommandHeader commandHeader = default(CommandHeader); commandHeader.type = type; commandHeader.dataLen = num; CommandHeader commandHeader2 = commandHeader; IntPtr intPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CommandHeader))); Marshal.StructureToPtr((object)commandHeader2, intPtr, fDeleteOld: false); Marshal.Copy(intPtr, array, 0, Marshal.SizeOf(typeof(CommandHeader))); Marshal.FreeHGlobal(intPtr); if (num > 0) { IntPtr intPtr2 = Marshal.AllocHGlobal(num); Marshal.StructureToPtr((object)data, intPtr2, fDeleteOld: false); Marshal.Copy(intPtr2, array, Marshal.SizeOf(typeof(CommandHeader)), num); Marshal.FreeHGlobal(intPtr2); } m_stream.Write(array, 0, array.Length); } } private void SendIpcCommand(ECommandType type) { if (m_running) { byte[] array = new byte[Marshal.SizeOf(typeof(CommandHeader))]; CommandHeader commandHeader = default(CommandHeader); commandHeader.type = type; commandHeader.dataLen = 0; CommandHeader commandHeader2 = commandHeader; IntPtr intPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CommandHeader))); Marshal.StructureToPtr((object)commandHeader2, intPtr, fDeleteOld: false); Marshal.Copy(intPtr, array, 0, Marshal.SizeOf(typeof(CommandHeader))); Marshal.FreeHGlobal(intPtr); m_stream.Write(array, 0, array.Length); } } private T ByteArrayToStructure<T>(byte[] bytes, int offset) where T : struct { int num = Marshal.SizeOf(typeof(T)); if (num > bytes.Length - offset) { throw new ArgumentException("Byte array is too small to contain the structure."); } IntPtr intPtr = Marshal.AllocHGlobal(num); Marshal.Copy(bytes, offset, intPtr, num); T result = (T)Marshal.PtrToStructure(intPtr, typeof(T)); Marshal.FreeHGlobal(intPtr); return result; } public CommandDataServerGazeDataResult2 RequestEyeTrackingData() { if (!m_running) { return default(CommandDataServerGazeDataResult2); } return m_lastGazeState.GetValueOrDefault(); } public void TriggerEffectDisable(EVRControllerType controllerType) { if (m_running) { CommandDataClientTriggerEffectOff commandDataClientTriggerEffectOff = default(CommandDataClientTriggerEffectOff); commandDataClientTriggerEffectOff.controllerType = controllerType; CommandDataClientTriggerEffectOff data = commandDataClientTriggerEffectOff; SendIpcCommand(ECommandType.ClientTriggerEffectOff, data); } } public void TriggerEffectFeedback(EVRControllerType controllerType, byte position, byte strength) { if (m_running) { CommandDataClientTriggerEffectFeedback commandDataClientTriggerEffectFeedback = default(CommandDataClientTriggerEffectFeedback); commandDataClientTriggerEffectFeedback.controllerType = controllerType; commandDataClientTriggerEffectFeedback.position = position; commandDataClientTriggerEffectFeedback.strength = strength; CommandDataClientTriggerEffectFeedback data = commandDataClientTriggerEffectFeedback; SendIpcCommand(ECommandType.ClientTriggerEffectFeedback, data); } } public void TriggerEffectWeapon(EVRControllerType controllerType, byte startPosition, byte endPosition, byte strength) { if (m_running) { CommandDataClientTriggerEffectWeapon commandDataClientTriggerEffectWeapon = default(CommandDataClientTriggerEffectWeapon); commandDataClientTriggerEffectWeapon.controllerType = controllerType; commandDataClientTriggerEffectWeapon.startPosition = startPosition; commandDataClientTriggerEffectWeapon.endPosition = endPosition; commandDataClientTriggerEffectWeapon.strength = strength; CommandDataClientTriggerEffectWeapon data = commandDataClientTriggerEffectWeapon; SendIpcCommand(ECommandType.ClientTriggerEffectWeapon, data); } } public void TriggerEffectVibration(EVRControllerType controllerType, byte position, byte amplitude, byte frequency) { if (m_running) { CommandDataClientTriggerEffectVibration commandDataClientTriggerEffectVibration = default(CommandDataClientTriggerEffectVibration); commandDataClientTriggerEffectVibration.controllerType = controllerType; commandDataClientTriggerEffectVibration.position = position; commandDataClientTriggerEffectVibration.amplitude = amplitude; commandDataClientTriggerEffectVibration.frequency = frequency; CommandDataClientTriggerEffectVibration data = commandDataClientTriggerEffectVibration; SendIpcCommand(ECommandType.ClientTriggerEffectVibration, data); } } public void TriggerEffectMultiplePositionFeedback(EVRControllerType controllerType, byte[] strength) { if (m_running) { CommandDataClientTriggerEffectMultiplePositionFeedback commandDataClientTriggerEffectMultiplePositionFeedback = default(CommandDataClientTriggerEffectMultiplePositionFeedback); commandDataClientTriggerEffectMultiplePositionFeedback.controllerType = controllerType; commandDataClientTriggerEffectMultiplePositionFeedback.strength = strength; CommandDataClientTriggerEffectMultiplePositionFeedback data = commandDataClientTriggerEffectMultiplePositionFeedback; SendIpcCommand(ECommandType.ClientTriggerEffectMultiplePositionFeedback, data); } } public void TriggerEffectSlopeFeedback(EVRControllerType controllerType, byte startPosition, byte endPosition, byte startStrength, byte endStrength) { if (m_running) { CommandDataClientTriggerEffectSlopeFeedback commandDataClientTriggerEffectSlopeFeedback = default(CommandDataClientTriggerEffectSlopeFeedback); commandDataClientTriggerEffectSlopeFeedback.controllerType = controllerType; commandDataClientTriggerEffectSlopeFeedback.startPosition = startPosition; commandDataClientTriggerEffectSlopeFeedback.endPosition = endPosition; commandDataClientTriggerEffectSlopeFeedback.startStrength = startStrength; commandDataClientTriggerEffectSlopeFeedback.endStrength = endStrength; CommandDataClientTriggerEffectSlopeFeedback data = commandDataClientTriggerEffectSlopeFeedback; SendIpcCommand(ECommandType.ClientTriggerEffectSlopeFeedback, data); } } public void TriggerEffectMultiplePositionVibration(EVRControllerType controllerType, byte frequency, byte[] amplitude) { if (m_running) { CommandDataClientTriggerEffectMultiplePositionVibration commandDataClientTriggerEffectMultiplePositionVibration = default(CommandDataClientTriggerEffectMultiplePositionVibration); commandDataClientTriggerEffectMultiplePositionVibration.controllerType = controllerType; commandDataClientTriggerEffectMultiplePositionVibration.frequency = frequency; commandDataClientTriggerEffectMultiplePositionVibration.amplitude = amplitude; CommandDataClientTriggerEffectMultiplePositionVibration data = commandDataClientTriggerEffectMultiplePositionVibration; SendIpcCommand(ECommandType.ClientTriggerEffectMultiplePositionVibration, data); } } } public enum ECommandType : ushort { ClientPing, ServerPong, ClientRequestHandshake, ServerHandshakeResult, ClientRequestGazeData, ServerGazeDataResult, ClientTriggerEffectOff, ClientTriggerEffectFeedback, ClientTriggerEffectWeapon, ClientTriggerEffectVibration, ClientTriggerEffectMultiplePositionFeedback, ClientTriggerEffectSlopeFeedback, ClientTriggerEffectMultiplePositionVibration } public enum EHandshakeResult : byte { Failed, Success, Outdated } public enum EVRControllerType : byte { Left, Right, Both } public struct CommandDataClientRequestHandshake { public ushort ipcVersion; public uint processId; } public struct CommandDataServerHandshakeResult { public EHandshakeResult result; public ushort ipcVersion; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct GazeVector3 { public float x; public float y; public float z; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct GazeEyeResult { [MarshalAs(UnmanagedType.I1)] public bool isGazeOriginValid; public GazeVector3 gazeOriginMm; [MarshalAs(UnmanagedType.I1)] public bool isGazeDirValid; public GazeVector3 gazeDirNorm; [MarshalAs(UnmanagedType.I1)] public bool isPupilDiaValid; public float pupilDiaMm; [MarshalAs(UnmanagedType.I1)] public bool isBlinkValid; [MarshalAs(UnmanagedType.I1)] public bool blink; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct GazeEyeResult2 { [MarshalAs(UnmanagedType.I1)] public bool isGazeOriginValid; public GazeVector3 gazeOriginMm; [MarshalAs(UnmanagedType.I1)] public bool isGazeDirValid; public GazeVector3 gazeDirNorm; [MarshalAs(UnmanagedType.I1)] public bool isPupilDiaValid; public float pupilDiaMm; [MarshalAs(UnmanagedType.I1)] public bool isBlinkValid; [MarshalAs(UnmanagedType.I1)] public bool blink; [MarshalAs(UnmanagedType.I1)] public bool isOpenEnabled; public float open; } public struct CommandDataServerGazeDataResult { public GazeEyeResult leftEye; public GazeEyeResult rightEye; } public struct CommandDataServerGazeDataResult2 { public GazeEyeResult2 leftEye; public GazeEyeResult2 rightEye; } public struct CommandHeader { public ECommandType type; public int dataLen; } public struct CommandDataClientTriggerEffectOff { public EVRControllerType controllerType; } public struct CommandDataClientTriggerEffectFeedback { public EVRControllerType controllerType; public byte position; public byte strength; } public struct CommandDataClientTriggerEffectWeapon { public EVRControllerType controllerType; public byte startPosition; public byte endPosition; public byte strength; } public struct CommandDataClientTriggerEffectVibration { public EVRControllerType controllerType; public byte position; public byte amplitude; public byte frequency; } public struct CommandDataClientTriggerEffectMultiplePositionFeedback { public EVRControllerType controllerType; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] public byte[] strength; } public struct CommandDataClientTriggerEffectSlopeFeedback { public EVRControllerType controllerType; public byte startPosition; public byte endPosition; public byte startStrength; public byte endStrength; } public struct CommandDataClientTriggerEffectMultiplePositionVibration { public EVRControllerType controllerType; public byte frequency; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] public byte[] amplitude; } } namespace plugin.Properties { [CompilerGenerated] [GeneratedCode("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.14.0.0")] internal sealed class Settings : ApplicationSettingsBase { private static Settings defaultInstance = (Settings)(object)SettingsBase.Synchronized((SettingsBase)(object)new Settings()); public static Settings Default => defaultInstance; } }
System.Threading.Tasks.NET35.dll
Decompiled a month ago
The result has been truncated due to the large size, download it to view full contents!
using System.Collections; using System.Collections.Concurrent; using System.Collections.Concurrent.Partitioners; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Security; using System.Text; using System.Threading; [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyFileVersion("3.0.2.0")] [assembly: AssemblyCompany("Robert McLaws")] [assembly: Guid("693242a3-2f03-494f-b531-ab6265dfeedb")] [assembly: AssemblyTitle("System.Threading.Tasks.NET35")] [assembly: AssemblyDescription("The Mono port of the Task Parallel Library ported to .NET 3.5")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyProduct("System.Threading.Tasks.NET35")] [assembly: AssemblyCopyright("Copyright © 2011 Robert McLaws. Contains code originally Copyright © 2009-2012 Xamarin.")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: AssemblyVersion("3.0.2.0")] namespace System.Threading { [ComVisible(true)] public sealed class Timer : MarshalByRefObject, IDisposable { private sealed class TimerComparer : IComparer { public int Compare(object x, object y) { if (!(x is Timer timer)) { return -1; } if (!(y is Timer timer2)) { return 1; } long num = timer.next_run - timer2.next_run; if (num == 0) { if (x != y) { return -1; } return 0; } if (num <= 0) { return -1; } return 1; } } private sealed class Scheduler { private static Scheduler instance; private SortedList list; private ManualResetEvent changed; private static WaitCallback TimerCaller; public static Scheduler Instance => instance; static Scheduler() { TimerCaller = TimerCB; instance = new Scheduler(); } private Scheduler() { changed = new ManualResetEvent(initialState: false); list = new SortedList(new TimerComparer(), 1024); Thread thread = new Thread(SchedulerThread); thread.IsBackground = true; thread.Start(); } public void Remove(Timer timer) { if (timer.next_run == 0 || timer.next_run == long.MaxValue) { return; } lock (this) { InternalRemove(timer); } } public void Change(Timer timer, long new_next_run) { bool flag = false; lock (this) { InternalRemove(timer); if (new_next_run == long.MaxValue) { timer.next_run = new_next_run; return; } if (!timer.disposed) { timer.next_run = new_next_run; Add(timer); flag = list.GetByIndex(0) == timer; } } if (flag) { changed.Set(); } } private int FindByDueTime(long nr) { int i = 0; int num = list.Count - 1; if (num < 0) { return -1; } if (num < 20) { for (; i <= num; i++) { Timer timer = (Timer)list.GetByIndex(i); if (timer.next_run == nr) { return i; } if (timer.next_run > nr) { return -1; } } return -1; } while (i <= num) { int num2 = i + (num - i >> 1); Timer timer2 = (Timer)list.GetByIndex(num2); if (nr == timer2.next_run) { return num2; } if (nr > timer2.next_run) { i = num2 + 1; } else { num = num2 - 1; } } return -1; } private void Add(Timer timer) { int num = FindByDueTime(timer.next_run); if (num != -1) { bool flag = ((long.MaxValue - timer.next_run > 20000) ? true : false); Timer timer2; do { num++; if (flag) { timer.next_run++; } else { timer.next_run--; } if (num >= list.Count) { break; } timer2 = (Timer)list.GetByIndex(num); } while (timer2.next_run == timer.next_run); } list.Add(timer, timer); } private int InternalRemove(Timer timer) { int num = list.IndexOfKey(timer); if (num >= 0) { list.RemoveAt(num); } return num; } private static void TimerCB(object o) { Timer timer = (Timer)o; try { timer.callback(timer.state); } catch { } } private void SchedulerThread() { Thread.CurrentThread.Name = "Timer-Scheduler"; ArrayList arrayList = new ArrayList(512); while (true) { int num = -1; long ticks = DateTime.Now.Ticks; lock (this) { changed.Reset(); int num2 = list.Count; int num3; for (num3 = 0; num3 < num2; num3++) { Timer timer = (Timer)list.GetByIndex(num3); if (timer.next_run > ticks) { break; } list.RemoveAt(num3); num2--; num3--; ThreadPool.QueueUserWorkItem(TimerCaller, timer); long period_ms = timer.period_ms; long due_time_ms = timer.due_time_ms; if (period_ms == -1 || ((period_ms == 0 || period_ms == -1) && due_time_ms != -1)) { timer.next_run = long.MaxValue; } else { timer.next_run = DateTime.Now.Ticks + 10000 * timer.period_ms; arrayList.Add(timer); } } num2 = arrayList.Count; for (num3 = 0; num3 < num2; num3++) { Timer timer2 = (Timer)arrayList[num3]; Add(timer2); } arrayList.Clear(); ShrinkIfNeeded(arrayList, 512); int capacity = list.Capacity; num2 = list.Count; if (capacity > 1024 && num2 > 0 && capacity / num2 > 3) { list.Capacity = num2 * 2; } long num4 = long.MaxValue; if (list.Count > 0) { num4 = ((Timer)list.GetByIndex(0)).next_run; } num = -1; if (num4 != long.MaxValue) { long num5 = num4 - DateTime.Now.Ticks; num = (int)(num5 / 10000); if (num < 0) { num = 0; } } } changed.WaitOne(num); } } private void ShrinkIfNeeded(ArrayList list, int initial) { int capacity = list.Capacity; int count = list.Count; if (capacity > initial && count > 0 && capacity / count > 3) { list.Capacity = count * 2; } } } private const long MaxValue = 4294967294L; private static Scheduler scheduler = Scheduler.Instance; private TimerCallback callback; private object state; private long due_time_ms; private long period_ms; private long next_run; private bool disposed; public Timer(TimerCallback callback, object state, int dueTime, int period) { Init(callback, state, dueTime, period); } public Timer(TimerCallback callback, object state, long dueTime, long period) { Init(callback, state, dueTime, period); } public Timer(TimerCallback callback, object state, TimeSpan dueTime, TimeSpan period) { Init(callback, state, (long)dueTime.TotalMilliseconds, (long)period.TotalMilliseconds); } [CLSCompliant(false)] public Timer(TimerCallback callback, object state, uint dueTime, uint period) { Init(callback, state, (dueTime == uint.MaxValue) ? (-1L) : ((long)dueTime), (period == uint.MaxValue) ? (-1L) : ((long)period)); } public Timer(TimerCallback callback) { Init(callback, this, -1L, -1L); } private void Init(TimerCallback callback, object state, long dueTime, long period) { if (callback == null) { throw new ArgumentNullException("callback"); } this.callback = callback; this.state = state; Change(dueTime, period, first: true); } public bool Change(int dueTime, int period) { return Change(dueTime, period, first: false); } public bool Change(TimeSpan dueTime, TimeSpan period) { return Change((long)dueTime.TotalMilliseconds, (long)period.TotalMilliseconds, first: false); } [CLSCompliant(false)] public bool Change(uint dueTime, uint period) { long dueTime2 = ((dueTime == uint.MaxValue) ? (-1L) : ((long)dueTime)); long period2 = ((period == uint.MaxValue) ? (-1L) : ((long)period)); return Change(dueTime2, period2, first: false); } public void Dispose() { if (!disposed) { disposed = true; scheduler.Remove(this); } } public bool Change(long dueTime, long period) { return Change(dueTime, period, first: false); } private bool Change(long dueTime, long period, bool first) { if (dueTime > 4294967294u) { throw new ArgumentOutOfRangeException("dueTime", "Due time too large"); } if (period > 4294967294u) { throw new ArgumentOutOfRangeException("period", "Period too large"); } if (dueTime < -1) { throw new ArgumentOutOfRangeException("dueTime"); } if (period < -1) { throw new ArgumentOutOfRangeException("period"); } if (disposed) { return false; } due_time_ms = dueTime; period_ms = period; long new_next_run; if (dueTime == 0) { new_next_run = 0L; } else if (dueTime < 0) { new_next_run = long.MaxValue; if (first) { next_run = new_next_run; return true; } } else { new_next_run = dueTime * 10000 + DateTime.Now.Ticks; } scheduler.Change(this, new_next_run); return true; } public bool Dispose(WaitHandle notifyObject) { if (notifyObject == null) { throw new ArgumentNullException("notifyObject"); } Dispose(); return true; } } } namespace System.Collections.Concurrent { internal class SplitOrderedList<TKey, T> { private class Node { public bool Marked; public ulong Key; public TKey SubKey; public T Data; public Node Next; public Node Init(ulong key, TKey subKey, T data) { Key = key; SubKey = subKey; Data = data; Marked = false; Next = null; return this; } public Node Init(ulong key) { Key = key; Data = default(T); Next = null; Marked = false; SubKey = default(TKey); return this; } public Node Init(Node wrapped) { Marked = true; Next = wrapped; Key = 0uL; Data = default(T); SubKey = default(TKey); return this; } } private class NodeObjectPool : ObjectPool<Node> { protected override Node Creator() { return new Node(); } } private struct SimpleRwLock { private const int RwWait = 1; private const int RwWrite = 2; private const int RwRead = 4; private int rwlock; public void EnterReadLock() { SpinWait spinWait = default(SpinWait); while (true) { if ((rwlock & 3) > 0) { spinWait.SpinOnce(); continue; } if ((Interlocked.Add(ref rwlock, 4) & 1) == 0) { break; } Interlocked.Add(ref rwlock, -4); } } public void ExitReadLock() { Interlocked.Add(ref rwlock, -4); } public void EnterWriteLock() { SpinWait spinWait = default(SpinWait); while (true) { int num = rwlock; if (num < 2) { if (Interlocked.CompareExchange(ref rwlock, 2, num) == num) { break; } num = rwlock; } while ((num & 1) == 0 && Interlocked.CompareExchange(ref rwlock, num | 1, num) != num) { num = rwlock; } while (rwlock > 1) { spinWait.SpinOnce(); } } } public void ExitWriteLock() { Interlocked.Add(ref rwlock, -2); } } private const int MaxLoad = 5; private const uint BucketSize = 512u; private static readonly NodeObjectPool pool = new NodeObjectPool(); private Node head; private Node tail; private Node[] buckets = new Node[512]; private int count; private int size = 2; private SimpleRwLock slim = default(SimpleRwLock); private readonly IEqualityComparer<TKey> comparer; private static readonly byte[] reverseTable = new byte[256] { 0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, 48, 176, 112, 240, 8, 136, 72, 200, 40, 168, 104, 232, 24, 152, 88, 216, 56, 184, 120, 248, 4, 132, 68, 196, 36, 164, 100, 228, 20, 148, 84, 212, 52, 180, 116, 244, 12, 140, 76, 204, 44, 172, 108, 236, 28, 156, 92, 220, 60, 188, 124, 252, 2, 130, 66, 194, 34, 162, 98, 226, 18, 146, 82, 210, 50, 178, 114, 242, 10, 138, 74, 202, 42, 170, 106, 234, 26, 154, 90, 218, 58, 186, 122, 250, 6, 134, 70, 198, 38, 166, 102, 230, 22, 150, 86, 214, 54, 182, 118, 246, 14, 142, 78, 206, 46, 174, 110, 238, 30, 158, 94, 222, 62, 190, 126, 254, 1, 129, 65, 193, 33, 161, 97, 225, 17, 145, 81, 209, 49, 177, 113, 241, 9, 137, 73, 201, 41, 169, 105, 233, 25, 153, 89, 217, 57, 185, 121, 249, 5, 133, 69, 197, 37, 165, 101, 229, 21, 149, 85, 213, 53, 181, 117, 245, 13, 141, 77, 205, 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253, 3, 131, 67, 195, 35, 163, 99, 227, 19, 147, 83, 211, 51, 179, 115, 243, 11, 139, 75, 203, 43, 171, 107, 235, 27, 155, 91, 219, 59, 187, 123, 251, 7, 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247, 15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, 255 }; private static readonly byte[] logTable = new byte[256] { 255, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 }; public int Count => count; public SplitOrderedList(IEqualityComparer<TKey> comparer) { this.comparer = comparer; head = new Node().Init(0uL); tail = new Node().Init(ulong.MaxValue); head.Next = tail; SetBucket(0u, head); } public T InsertOrUpdate(uint key, TKey subKey, Func<T> addGetter, Func<T, T> updateGetter) { if (InsertInternal(key, subKey, default(T), addGetter, out var current)) { return current.Data; } return current.Data = updateGetter(current.Data); } public T InsertOrUpdate(uint key, TKey subKey, T addValue, T updateValue) { if (InsertInternal(key, subKey, addValue, null, out var current)) { return current.Data; } return current.Data = updateValue; } public bool Insert(uint key, TKey subKey, T data) { Node current; return InsertInternal(key, subKey, data, null, out current); } public T InsertOrGet(uint key, TKey subKey, T data, Func<T> dataCreator) { InsertInternal(key, subKey, data, dataCreator, out var current); return current.Data; } private bool InsertInternal(uint key, TKey subKey, T data, Func<T> dataCreator, out Node current) { Node node = pool.Take().Init(ComputeRegularKey(key), subKey, data); uint num = key % (uint)size; Node startPoint; if ((startPoint = GetBucket(num)) == null) { startPoint = InitializeBucket(num); } if (!ListInsert(node, startPoint, out current, dataCreator)) { return false; } int num2 = size; if (Interlocked.Increment(ref count) / num2 > 5 && (num2 & 0x40000000) == 0) { Interlocked.CompareExchange(ref size, 2 * num2, num2); } current = node; return true; } public bool Find(uint key, TKey subKey, out T data) { uint num = key % (uint)size; data = default(T); Node startPoint; if ((startPoint = GetBucket(num)) == null) { startPoint = InitializeBucket(num); } if (!ListFind(ComputeRegularKey(key), subKey, startPoint, out var data2)) { return false; } data = data2.Data; return !data2.Marked; } public bool CompareExchange(uint key, TKey subKey, T data, Func<T, bool> check) { uint num = key % (uint)size; Node startPoint; if ((startPoint = GetBucket(num)) == null) { startPoint = InitializeBucket(num); } if (!ListFind(ComputeRegularKey(key), subKey, startPoint, out var data2)) { return false; } if (!check(data2.Data)) { return false; } data2.Data = data; return true; } public bool Delete(uint key, TKey subKey, out T data) { uint num = key % (uint)size; Node startPoint; if ((startPoint = GetBucket(num)) == null) { startPoint = InitializeBucket(num); } if (!ListDelete(startPoint, ComputeRegularKey(key), subKey, out data)) { return false; } Interlocked.Decrement(ref count); return true; } public IEnumerator<T> GetEnumerator() { for (Node node = head.Next; node != tail; node = node.Next) { while (node.Marked || (node.Key & 1) == 0) { node = node.Next; if (node == tail) { yield break; } } yield return node.Data; } } private Node InitializeBucket(uint b) { uint parent = GetParent(b); Node startPoint; if ((startPoint = GetBucket(parent)) == null) { startPoint = InitializeBucket(parent); } Node node = pool.Take().Init(ComputeDummyKey(b)); if (!ListInsert(node, startPoint, out var current, null)) { return current; } return SetBucket(b, node); } private static uint GetParent(uint v) { uint num; uint num2; int num3 = (((num = v >> 16) == 0) ? (((num2 = v >> 8) != 0) ? (8 + logTable[num2]) : logTable[v]) : (((num2 = num >> 8) != 0) ? (24 + logTable[num2]) : (16 + logTable[num]))); return (uint)(v & ~(1 << num3)); } private static ulong ComputeRegularKey(uint key) { return ComputeDummyKey(key) | 1; } private static ulong ComputeDummyKey(uint key) { return (ulong)(uint)((reverseTable[key & 0xFF] << 24) | (reverseTable[(key >> 8) & 0xFF] << 16) | (reverseTable[(key >> 16) & 0xFF] << 8) | reverseTable[(key >> 24) & 0xFF]) << 1; } private Node GetBucket(uint index) { if (index >= buckets.Length) { return null; } return buckets[index]; } private Node SetBucket(uint index, Node node) { try { slim.EnterReadLock(); CheckSegment(index, readLockTaken: true); Interlocked.CompareExchange(ref buckets[index], node, null); return buckets[index]; } finally { slim.ExitReadLock(); } } private void CheckSegment(uint segment, bool readLockTaken) { if (segment < buckets.Length) { return; } if (readLockTaken) { slim.ExitReadLock(); } try { slim.EnterWriteLock(); while (segment >= buckets.Length) { Array.Resize(ref buckets, buckets.Length * 2); } } finally { slim.ExitWriteLock(); } if (readLockTaken) { slim.EnterReadLock(); } } private Node ListSearch(ulong key, TKey subKey, ref Node left, Node h) { Node node = null; Node node2 = null; while (true) { Node node3 = h; Node next = node3.Next; do { if (!next.Marked) { left = node3; node = next; } node3 = (next.Marked ? next.Next : next); if (node3 == tail) { break; } next = node3.Next; } while (next.Marked || node3.Key < key || (next.Key == key && !comparer.Equals(subKey, node3.SubKey))); node2 = node3; if (node == node2) { if (node2 == tail || !node2.Next.Marked) { return node2; } } else if (Interlocked.CompareExchange(ref left.Next, node2, node) == node) { pool.Release(node); if (node2 == tail || !node2.Next.Marked) { break; } } } return node2; } private bool ListDelete(Node startPoint, ulong key, TKey subKey, out T data) { Node node = null; Node node2 = null; Node left = null; data = default(T); Node node3 = null; while (true) { node = ListSearch(key, subKey, ref left, startPoint); if (node == tail || node.Key != key || !comparer.Equals(subKey, node.SubKey)) { return false; } data = node.Data; node2 = node.Next; if (!node2.Marked) { if (node3 == null) { node3 = pool.Take(); } node3.Init(node2); if (Interlocked.CompareExchange(ref node.Next, node3, node2) == node2) { break; } } } if (Interlocked.CompareExchange(ref left.Next, node2, node) != node) { ListSearch(node.Key, subKey, ref left, startPoint); } else { pool.Release(node); } return true; } private bool ListInsert(Node newNode, Node startPoint, out Node current, Func<T> dataCreator) { ulong key = newNode.Key; Node node = null; Node left = null; do { node = (current = ListSearch(key, newNode.SubKey, ref left, startPoint)); if (node != tail && node.Key == key && comparer.Equals(newNode.SubKey, node.SubKey)) { return false; } newNode.Next = node; if (dataCreator != null) { newNode.Data = dataCreator(); } } while (Interlocked.CompareExchange(ref left.Next, newNode, node) != node); return true; } private bool ListFind(ulong key, TKey subKey, Node startPoint, out Node data) { Node node = null; Node left = null; data = null; node = (data = ListSearch(key, subKey, ref left, startPoint)); if (node != tail && node.Key == key) { return comparer.Equals(subKey, node.SubKey); } return false; } } internal abstract class ObjectPool<T> where T : class { private const int capacity = 20; private const int bit = 134217728; private readonly T[] buffer; private int addIndex; private int removeIndex; public ObjectPool() { buffer = new T[20]; for (int i = 0; i < 20; i++) { buffer[i] = Creator(); } addIndex = 19; } protected abstract T Creator(); public T Take() { if ((addIndex & -134217729) - 1 == removeIndex) { return Creator(); } int num = 3; int num2; T result; do { num2 = removeIndex; if ((addIndex & -134217729) - 1 == num2 || num == 0) { return Creator(); } result = buffer[num2 % 20]; } while (Interlocked.CompareExchange(ref removeIndex, num2 + 1, num2) != num2 && --num > -1); return result; } public void Release(T obj) { if (obj == null || addIndex - removeIndex >= 19) { return; } int num = 3; int num2; while (true) { num2 = addIndex; if ((num2 & 0x8000000) <= 0) { if (num2 - removeIndex >= 19) { return; } if (Interlocked.CompareExchange(ref addIndex, num2 + 1 + 134217728, num2) == num2 || --num <= 0) { break; } } } buffer[num2 % 20] = obj; addIndex -= 134217728; } } public static class Partitioner { public static OrderablePartitioner<TSource> Create<TSource>(IEnumerable<TSource> source) { if (source is IList<TSource> list) { return Create(list, loadBalance: true); } return new EnumerablePartitioner<TSource>(source); } public static OrderablePartitioner<TSource> Create<TSource>(TSource[] array, bool loadBalance) { return Create((IList<TSource>)array, loadBalance); } public static OrderablePartitioner<TSource> Create<TSource>(IList<TSource> list, bool loadBalance) { return new ListPartitioner<TSource>(list); } public static OrderablePartitioner<Tuple<int, int>> Create(int fromInclusive, int toExclusive) { int num = (toExclusive - fromInclusive) / (Environment.ProcessorCount * 3); if (num < 1) { num = 1; } return Create(fromInclusive, toExclusive, num); } public static OrderablePartitioner<Tuple<int, int>> Create(int fromInclusive, int toExclusive, int rangeSize) { if (fromInclusive >= toExclusive) { throw new ArgumentOutOfRangeException("toExclusive"); } if (rangeSize <= 0) { throw new ArgumentOutOfRangeException("rangeSize"); } return new UserRangePartitioner(fromInclusive, toExclusive, rangeSize); } public static OrderablePartitioner<Tuple<long, long>> Create(long fromInclusive, long toExclusive) { long num = (toExclusive - fromInclusive) / (Environment.ProcessorCount * 3); if (num < 1) { num = 1L; } return Create(fromInclusive, toExclusive, num); } public static OrderablePartitioner<Tuple<long, long>> Create(long fromInclusive, long toExclusive, long rangeSize) { if (rangeSize <= 0) { throw new ArgumentOutOfRangeException("rangeSize"); } if (fromInclusive >= toExclusive) { throw new ArgumentOutOfRangeException("toExclusive"); } return new UserLongRangePartitioner(fromInclusive, toExclusive, rangeSize); } } public abstract class Partitioner<TSource> { public virtual bool SupportsDynamicPartitions => false; public virtual IEnumerable<TSource> GetDynamicPartitions() { if (!SupportsDynamicPartitions) { throw new NotSupportedException(); } return null; } public abstract IList<IEnumerator<TSource>> GetPartitions(int partitionCount); } } namespace System.Threading.Tasks { internal class TaskConstants<T> { internal static readonly Task<T> Canceled; static TaskConstants() { TaskCompletionSource<T> taskCompletionSource = new TaskCompletionSource<T>(); taskCompletionSource.SetCanceled(); Canceled = taskCompletionSource.Task; } } } namespace System { [Serializable] [ComVisible(true)] public class OperationCanceledException : SystemException { private const int Result = -2146233029; private CancellationToken? token; public CancellationToken CancellationToken { get { if (!token.HasValue) { return CancellationToken.None; } return token.Value; } } public OperationCanceledException() : base("The operation was canceled.") { base.HResult = -2146233029; } public OperationCanceledException(string message) : base(message) { base.HResult = -2146233029; } public OperationCanceledException(string message, Exception innerException) : base(message, innerException) { base.HResult = -2146233029; } protected OperationCanceledException(SerializationInfo info, StreamingContext context) : base(info, context) { } public OperationCanceledException(CancellationToken token) : this() { this.token = token; } public OperationCanceledException(string message, CancellationToken token) : this(message) { this.token = token; } public OperationCanceledException(string message, Exception innerException, CancellationToken token) : base(message, innerException) { this.token = token; } } } namespace System.Collections { [Serializable] [ComVisible(true)] public sealed class Comparer : IComparer { public static readonly Comparer Default = new Comparer(); public static readonly Comparer DefaultInvariant = new Comparer(CultureInfo.InvariantCulture); private CompareInfo m_compareInfo; private Comparer() { } public Comparer(CultureInfo culture) { if (culture == null) { throw new ArgumentNullException("culture"); } m_compareInfo = culture.CompareInfo; } public int Compare(object a, object b) { if (a == b) { return 0; } if (a == null) { return -1; } if (b == null) { return 1; } if (m_compareInfo != null) { string text = a as string; string text2 = b as string; if (text != null && text2 != null) { return m_compareInfo.Compare(text, text2); } } if (a is IComparable) { return (a as IComparable).CompareTo(b); } if (b is IComparable) { return -(b as IComparable).CompareTo(a); } throw new ArgumentException("Neither 'a' nor 'b' implements IComparable."); } } } namespace System.Threading { public struct CancellationTokenRegistration : IDisposable, IEquatable<CancellationTokenRegistration> { private int id; private CancellationTokenSource source; internal CancellationTokenRegistration(int id, CancellationTokenSource source) { this.id = id; this.source = source; } public void Dispose() { source.RemoveCallback(this); } public bool Equals(CancellationTokenRegistration other) { if (id == other.id) { return source == other.source; } return false; } public static bool operator ==(CancellationTokenRegistration left, CancellationTokenRegistration right) { return left.Equals(right); } public static bool operator !=(CancellationTokenRegistration left, CancellationTokenRegistration right) { return !left.Equals(right); } public override int GetHashCode() { return id.GetHashCode() ^ source.GetHashCode(); } public override bool Equals(object obj) { if (!(obj is CancellationTokenRegistration)) { return false; } return Equals((CancellationTokenRegistration)obj); } } } namespace System.Collections.Concurrent { public abstract class OrderablePartitioner<TSource> : Partitioner<TSource> { private class ProxyEnumerator : IEnumerator<TSource>, IEnumerator, IDisposable { private IEnumerator<KeyValuePair<long, TSource>> internalEnumerator; object IEnumerator.Current => Current; public TSource Current { get; private set; } internal ProxyEnumerator(IEnumerator<KeyValuePair<long, TSource>> enumerator) { internalEnumerator = enumerator; } public void Dispose() { internalEnumerator.Dispose(); } public bool MoveNext() { if (!internalEnumerator.MoveNext()) { return false; } Current = internalEnumerator.Current.Value; return true; } public void Reset() { internalEnumerator.Reset(); } } private bool keysOrderedInEachPartition; private bool keysOrderedAcrossPartitions; private bool keysNormalized; public bool KeysOrderedInEachPartition => keysOrderedInEachPartition; public bool KeysOrderedAcrossPartitions => keysOrderedAcrossPartitions; public bool KeysNormalized => keysNormalized; protected OrderablePartitioner(bool keysOrderedInEachPartition, bool keysOrderedAcrossPartitions, bool keysNormalized) { this.keysOrderedInEachPartition = keysOrderedInEachPartition; this.keysOrderedAcrossPartitions = keysOrderedAcrossPartitions; this.keysNormalized = keysNormalized; } public override IEnumerable<TSource> GetDynamicPartitions() { foreach (KeyValuePair<long, TSource> item in GetOrderableDynamicPartitions()) { KeyValuePair<long, TSource> keyValuePair = item; yield return keyValuePair.Value; } } public override IList<IEnumerator<TSource>> GetPartitions(int partitionCount) { IEnumerator<TSource>[] array = new IEnumerator<TSource>[partitionCount]; IList<IEnumerator<KeyValuePair<long, TSource>>> orderablePartitions = GetOrderablePartitions(partitionCount); for (int i = 0; i < orderablePartitions.Count; i++) { array[i] = new ProxyEnumerator(orderablePartitions[i]); } return array; } private IEnumerator<TSource> GetProxyEnumerator(IEnumerator<KeyValuePair<long, TSource>> enumerator) { while (enumerator.MoveNext()) { yield return enumerator.Current.Value; } } public abstract IList<IEnumerator<KeyValuePair<long, TSource>>> GetOrderablePartitions(int partitionCount); public virtual IEnumerable<KeyValuePair<long, TSource>> GetOrderableDynamicPartitions() { if (!SupportsDynamicPartitions) { throw new NotSupportedException(); } return null; } } } namespace System.Collections.Concurrent.Partitioners { internal class UserRangePartitioner : OrderablePartitioner<Tuple<int, int>> { private readonly int start; private readonly int end; private readonly int rangeSize; public UserRangePartitioner(int start, int end, int rangeSize) : base(keysOrderedInEachPartition: true, keysOrderedAcrossPartitions: true, keysNormalized: true) { this.start = start; this.end = end; this.rangeSize = rangeSize; } public override IList<IEnumerator<KeyValuePair<long, Tuple<int, int>>>> GetOrderablePartitions(int partitionCount) { if (partitionCount <= 0) { throw new ArgumentOutOfRangeException("partitionCount"); } int currentIndex = 0; Func<int> getNextIndex = () => Interlocked.Increment(ref currentIndex) - 1; IEnumerator<KeyValuePair<long, Tuple<int, int>>>[] array = new IEnumerator<KeyValuePair<long, Tuple<int, int>>>[partitionCount]; for (int i = 0; i < partitionCount; i++) { array[i] = GetEnumerator(getNextIndex); } return array; } private IEnumerator<KeyValuePair<long, Tuple<int, int>>> GetEnumerator(Func<int> getNextIndex) { while (true) { int index = getNextIndex(); int sliceStart = index * rangeSize + start; if (sliceStart < end) { yield return new KeyValuePair<long, Tuple<int, int>>(index, Tuple.Create(sliceStart, Math.Min(end, sliceStart + rangeSize))); _ = sliceStart + rangeSize; continue; } break; } } } internal class UserLongRangePartitioner : OrderablePartitioner<Tuple<long, long>> { private readonly long start; private readonly long end; private readonly long rangeSize; public UserLongRangePartitioner(long start, long end, long rangeSize) : base(keysOrderedInEachPartition: true, keysOrderedAcrossPartitions: true, keysNormalized: true) { this.start = start; this.end = end; this.rangeSize = rangeSize; } public override IList<IEnumerator<KeyValuePair<long, Tuple<long, long>>>> GetOrderablePartitions(int partitionCount) { if (partitionCount <= 0) { throw new ArgumentOutOfRangeException("partitionCount"); } long currentIndex = 0L; Func<long> getNextIndex = () => Interlocked.Increment(ref currentIndex) - 1; IEnumerator<KeyValuePair<long, Tuple<long, long>>>[] array = new IEnumerator<KeyValuePair<long, Tuple<long, long>>>[partitionCount]; for (int i = 0; i < partitionCount; i++) { array[i] = GetEnumerator(getNextIndex); } return array; } private IEnumerator<KeyValuePair<long, Tuple<long, long>>> GetEnumerator(Func<long> getNextIndex) { while (true) { long index = getNextIndex(); long sliceStart = index * rangeSize + start; if (sliceStart < end) { yield return new KeyValuePair<long, Tuple<long, long>>(index, Tuple.Create(sliceStart, Math.Min(end, sliceStart + rangeSize))); _ = sliceStart + rangeSize; continue; } break; } } } } namespace System { public static class Tuple { public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8>> Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8) { return new Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8>>(item1, item2, item3, item4, item5, item6, item7, new Tuple<T8>(item8)); } public static Tuple<T1, T2, T3, T4, T5, T6, T7> Create<T1, T2, T3, T4, T5, T6, T7>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) { return new Tuple<T1, T2, T3, T4, T5, T6, T7>(item1, item2, item3, item4, item5, item6, item7); } public static Tuple<T1, T2, T3, T4, T5, T6> Create<T1, T2, T3, T4, T5, T6>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) { return new Tuple<T1, T2, T3, T4, T5, T6>(item1, item2, item3, item4, item5, item6); } public static Tuple<T1, T2, T3, T4, T5> Create<T1, T2, T3, T4, T5>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) { return new Tuple<T1, T2, T3, T4, T5>(item1, item2, item3, item4, item5); } public static Tuple<T1, T2, T3, T4> Create<T1, T2, T3, T4>(T1 item1, T2 item2, T3 item3, T4 item4) { return new Tuple<T1, T2, T3, T4>(item1, item2, item3, item4); } public static Tuple<T1, T2, T3> Create<T1, T2, T3>(T1 item1, T2 item2, T3 item3) { return new Tuple<T1, T2, T3>(item1, item2, item3); } public static Tuple<T1, T2> Create<T1, T2>(T1 item1, T2 item2) { return new Tuple<T1, T2>(item1, item2); } public static Tuple<T1> Create<T1>(T1 item1) { return new Tuple<T1>(item1); } } } namespace System.Threading.Tasks { [DebuggerDisplay("Id = {Id}, Status = {Status}")] [DebuggerTypeProxy(typeof(TaskDebuggerView))] public class Task : IDisposable, IAsyncResult { internal const TaskCreationOptions WorkerTaskNotSupportedOptions = TaskCreationOptions.PreferFairness | TaskCreationOptions.LongRunning; private const TaskCreationOptions MaxTaskCreationOptions = TaskCreationOptions.PreferFairness | TaskCreationOptions.LongRunning | TaskCreationOptions.AttachedToParent | TaskCreationOptions.DenyChildAttach | TaskCreationOptions.HideScheduler; [ThreadStatic] private static Task current; [ThreadStatic] private static Action<Task> childWorkAdder; internal readonly Task parent; private readonly Task contAncestor; private static int id = -1; private static readonly TaskFactory defaultFactory = new TaskFactory(); private CountdownEvent childTasks; private int taskId; private TaskCreationOptions taskCreationOptions; internal TaskScheduler scheduler; private TaskExceptionSlot exSlot; private TaskStatus status; private TaskActionInvoker invoker; private object state; internal AtomicBooleanValue executing; private TaskCompletionQueue<IContinuation> continuations; private CancellationToken token; private CancellationTokenRegistration? cancellationRegistration; public static TaskFactory Factory => defaultFactory; public static int? CurrentId => current?.Id; public AggregateException Exception { get { if (exSlot == null) { return null; } exSlot.Observed = true; return exSlot.Exception; } } public bool IsCanceled => status == TaskStatus.Canceled; public bool IsCompleted => status >= TaskStatus.RanToCompletion; public bool IsFaulted => status == TaskStatus.Faulted; public TaskCreationOptions CreationOptions => taskCreationOptions & (TaskCreationOptions.PreferFairness | TaskCreationOptions.LongRunning | TaskCreationOptions.AttachedToParent | TaskCreationOptions.DenyChildAttach | TaskCreationOptions.HideScheduler); public TaskStatus Status { get { return status; } internal set { status = value; Thread.MemoryBarrier(); } } private TaskExceptionSlot ExceptionSlot { get { if (exSlot != null) { return exSlot; } Interlocked.CompareExchange(ref exSlot, new TaskExceptionSlot(this), null); return exSlot; } } public object AsyncState => state; bool IAsyncResult.CompletedSynchronously => true; WaitHandle IAsyncResult.AsyncWaitHandle => null; public int Id => taskId; private bool IsContinuation => contAncestor != null; internal Task ContinuationAncestor => contAncestor; internal string DisplayActionMethod { get { Delegate action = invoker.Action; if ((object)action != null) { return action.Method.ToString(); } return "<none>"; } } internal Task Parent => parent; public Task(Action action) : this(action, TaskCreationOptions.None) { } public Task(Action action, TaskCreationOptions creationOptions) : this(action, CancellationToken.None, creationOptions) { } public Task(Action action, CancellationToken cancellationToken) : this(action, cancellationToken, TaskCreationOptions.None) { } public Task(Action action, CancellationToken cancellationToken, TaskCreationOptions creationOptions) : this(TaskActionInvoker.Create(action), null, cancellationToken, creationOptions, current) { if (action == null) { throw new ArgumentNullException("action"); } if (creationOptions > (TaskCreationOptions.PreferFairness | TaskCreationOptions.LongRunning | TaskCreationOptions.AttachedToParent | TaskCreationOptions.DenyChildAttach | TaskCreationOptions.HideScheduler) || creationOptions < TaskCreationOptions.None) { throw new ArgumentOutOfRangeException("creationOptions"); } } public Task(Action<object> action, object state) : this(action, state, TaskCreationOptions.None) { } public Task(Action<object> action, object state, TaskCreationOptions creationOptions) : this(action, state, CancellationToken.None, creationOptions) { } public Task(Action<object> action, object state, CancellationToken cancellationToken) : this(action, state, cancellationToken, TaskCreationOptions.None) { } public Task(Action<object> action, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions) : this(TaskActionInvoker.Create(action), state, cancellationToken, creationOptions, current) { if (action == null) { throw new ArgumentNullException("action"); } if (creationOptions > (TaskCreationOptions.PreferFairness | TaskCreationOptions.LongRunning | TaskCreationOptions.AttachedToParent | TaskCreationOptions.DenyChildAttach | TaskCreationOptions.HideScheduler) || creationOptions < TaskCreationOptions.None) { throw new ArgumentOutOfRangeException("creationOptions"); } } internal Task(TaskActionInvoker invoker, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions, Task parent, Task contAncestor = null) { this.invoker = invoker; taskCreationOptions = creationOptions; this.state = state; taskId = Interlocked.Increment(ref id); status = (cancellationToken.IsCancellationRequested ? TaskStatus.Canceled : TaskStatus.Created); token = cancellationToken; this.parent = parent; this.contAncestor = contAncestor; if (CheckTaskOptions(taskCreationOptions, TaskCreationOptions.AttachedToParent)) { parent?.AddChild(); } if (token.CanBeCanceled) { cancellationRegistration = token.Register(delegate(object l) { ((Task)l).CancelReal(); }, this); } } private static bool CheckTaskOptions(TaskCreationOptions opt, TaskCreationOptions member) { return (opt & member) == member; } public void Start() { Start(TaskScheduler.Current); } public void Start(TaskScheduler scheduler) { if (scheduler == null) { throw new ArgumentNullException("scheduler"); } if (status >= TaskStatus.WaitingToRun) { throw new InvalidOperationException("The Task is not in a valid state to be started."); } if (IsContinuation) { throw new InvalidOperationException("Start may not be called on a continuation task"); } SetupScheduler(scheduler); Schedule(); } internal void SetupScheduler(TaskScheduler scheduler) { this.scheduler = scheduler; Status = TaskStatus.WaitingForActivation; } public void RunSynchronously() { RunSynchronously(TaskScheduler.Current); } public void RunSynchronously(TaskScheduler scheduler) { if (scheduler == null) { throw new ArgumentNullException("scheduler"); } if (Status > TaskStatus.WaitingForActivation) { throw new InvalidOperationException("The task is not in a valid state to be started"); } SetupScheduler(scheduler); TaskStatus taskStatus = status; Status = TaskStatus.WaitingToRun; try { if (scheduler.RunInline(this)) { return; } } catch (Exception innerException) { throw new TaskSchedulerException(innerException); } Status = taskStatus; Start(scheduler); Wait(); } public Task ContinueWith(Action<Task> continuationAction) { return ContinueWith(continuationAction, TaskContinuationOptions.None); } public Task ContinueWith(Action<Task> continuationAction, TaskContinuationOptions continuationOptions) { return ContinueWith(continuationAction, CancellationToken.None, continuationOptions, TaskScheduler.Current); } public Task ContinueWith(Action<Task> continuationAction, CancellationToken cancellationToken) { return ContinueWith(continuationAction, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current); } public Task ContinueWith(Action<Task> continuationAction, TaskScheduler scheduler) { return ContinueWith(continuationAction, CancellationToken.None, TaskContinuationOptions.None, scheduler); } public Task ContinueWith(Action<Task> continuationAction, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler) { if (continuationAction == null) { throw new ArgumentNullException("continuationAction"); } if (scheduler == null) { throw new ArgumentNullException("scheduler"); } return ContinueWith(TaskActionInvoker.Create(continuationAction), cancellationToken, continuationOptions, scheduler); } internal Task ContinueWith(TaskActionInvoker invoker, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler) { Task task = new Task(invoker, null, cancellationToken, GetCreationOptions(continuationOptions), parent, this); ContinueWithCore(task, continuationOptions, scheduler); return task; } public Task<TResult> ContinueWith<TResult>(Func<Task, TResult> continuationFunction) { return ContinueWith(continuationFunction, TaskContinuationOptions.None); } public Task<TResult> ContinueWith<TResult>(Func<Task, TResult> continuationFunction, TaskContinuationOptions continuationOptions) { return ContinueWith(continuationFunction, CancellationToken.None, continuationOptions, TaskScheduler.Current); } public Task<TResult> ContinueWith<TResult>(Func<Task, TResult> continuationFunction, CancellationToken cancellationToken) { return ContinueWith(continuationFunction, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current); } public Task<TResult> ContinueWith<TResult>(Func<Task, TResult> continuationFunction, TaskScheduler scheduler) { return ContinueWith(continuationFunction, CancellationToken.None, TaskContinuationOptions.None, scheduler); } public Task<TResult> ContinueWith<TResult>(Func<Task, TResult> continuationFunction, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler) { if (continuationFunction == null) { throw new ArgumentNullException("continuationFunction"); } if (scheduler == null) { throw new ArgumentNullException("scheduler"); } return ContinueWith<TResult>(TaskActionInvoker.Create(continuationFunction), cancellationToken, continuationOptions, scheduler); } internal Task<TResult> ContinueWith<TResult>(TaskActionInvoker invoker, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler) { Task<TResult> task = new Task<TResult>(invoker, null, cancellationToken, GetCreationOptions(continuationOptions), parent, this); ContinueWithCore(task, continuationOptions, scheduler); return task; } internal void ContinueWithCore(Task continuation, TaskContinuationOptions options, TaskScheduler scheduler) { if ((options & (TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.NotOnRanToCompletion)) == (TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.NotOnRanToCompletion) || (options & (TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.NotOnRanToCompletion)) == (TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.NotOnRanToCompletion) || (options & (TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.NotOnRanToCompletion)) == (TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.NotOnRanToCompletion)) { throw new ArgumentException("continuationOptions", "Some options are mutually exclusive"); } continuation.scheduler = scheduler; continuation.Status = TaskStatus.WaitingForActivation; ContinueWith(new System.Threading.Tasks.TaskContinuation(continuation, options)); } internal void ContinueWith(IContinuation continuation) { if (IsCompleted) { continuation.Execute(); return; } continuations.Add(continuation); if (IsCompleted && continuations.Remove(continuation)) { continuation.Execute(); } } private void RemoveContinuation(IContinuation continuation) { continuations.Remove(continuation); } internal static TaskCreationOptions GetCreationOptions(TaskContinuationOptions kind) { TaskCreationOptions taskCreationOptions = TaskCreationOptions.None; if ((kind & TaskContinuationOptions.AttachedToParent) > TaskContinuationOptions.None) { taskCreationOptions |= TaskCreationOptions.AttachedToParent; } if ((kind & TaskContinuationOptions.PreferFairness) > TaskContinuationOptions.None) { taskCreationOptions |= TaskCreationOptions.PreferFairness; } if ((kind & TaskContinuationOptions.LongRunning) > TaskContinuationOptions.None) { taskCreationOptions |= TaskCreationOptions.LongRunning; } return taskCreationOptions; } internal void Schedule() { Status = TaskStatus.WaitingToRun; if (scheduler != TaskScheduler.Current || childWorkAdder == null || CheckTaskOptions(taskCreationOptions, TaskCreationOptions.PreferFairness)) { scheduler.QueueTask(this); } else { childWorkAdder(this); } } private void ThreadStart() { if (!executing.TryRelaxedSet()) { return; } if (cancellationRegistration.HasValue) { cancellationRegistration.Value.Dispose(); cancellationRegistration = null; } current = this; TaskScheduler.Current = scheduler; if (!token.IsCancellationRequested) { status = TaskStatus.Running; try { InnerInvoke(); } catch (OperationCanceledException ex) { if (token != CancellationToken.None && ex.CancellationToken == token) { CancelReal(); } else { HandleGenericException(ex); } } catch (Exception e) { HandleGenericException(e); } } else { CancelReal(); } Finish(); } internal bool TrySetCanceled() { if (IsCompleted) { return false; } if (!executing.TryRelaxedSet()) { SpinWait spinWait = default(SpinWait); while (!IsCompleted) { spinWait.SpinOnce(); } return false; } CancelReal(); return true; } internal bool TrySetException(AggregateException aggregate) { if (IsCompleted) { return false; } if (!executing.TryRelaxedSet()) { SpinWait spinWait = default(SpinWait); while (!IsCompleted) { spinWait.SpinOnce(); } return false; } HandleGenericException(aggregate); return true; } internal void Execute(Action<Task> childAdder) { childWorkAdder = childAdder; Execute(); } internal void Execute() { ThreadStart(); } internal void AddChild() { if (childTasks == null) { Interlocked.CompareExchange(ref childTasks, new CountdownEvent(1), null); } childTasks.AddCount(); } internal void ChildCompleted(AggregateException childEx) { if (childEx != null) { if (ExceptionSlot.ChildExceptions == null) { Interlocked.CompareExchange(ref ExceptionSlot.ChildExceptions, new ConcurrentQueue<AggregateException>(), null); } ExceptionSlot.ChildExceptions.Enqueue(childEx); } if (childTasks.Signal() && status == TaskStatus.WaitingForChildrenToComplete) { Status = TaskStatus.RanToCompletion; ProcessChildExceptions(); ProcessCompleteDelegates(); if (CheckTaskOptions(taskCreationOptions, TaskCreationOptions.AttachedToParent) && parent != null) { parent.ChildCompleted(Exception); } } } private void InnerInvoke() { if (IsContinuation) { invoker.Invoke(contAncestor, state, this); } else { invoker.Invoke(this, state, this); } } internal void Finish() { if (childTasks != null) { childTasks.Signal(); } if (status == TaskStatus.Running) { if (childTasks == null || childTasks.IsSet) { Status = TaskStatus.RanToCompletion; } else { Status = TaskStatus.WaitingForChildrenToComplete; } } if (status == TaskStatus.RanToCompletion) { ProcessCompleteDelegates(); } current = null; TaskScheduler.Current = null; if (cancellationRegistration.HasValue) { cancellationRegistration.Value.Dispose(); } if (CheckTaskOptions(taskCreationOptions, TaskCreationOptions.AttachedToParent) && parent != null && status != TaskStatus.WaitingForChildrenToComplete) { parent.ChildCompleted(Exception); } } private void ProcessCompleteDelegates() { if (continuations.HasElements) { IContinuation continuation; while (continuations.TryGetNextCompletion(out continuation)) { continuation.Execute(); } } } private void ProcessChildExceptions() { if (exSlot != null && exSlot.ChildExceptions != null) { if (ExceptionSlot.Exception == null) { exSlot.Exception = new AggregateException(); } AggregateException result; while (exSlot.ChildExceptions.TryDequeue(out result)) { exSlot.Exception.AddChildException(result); } } } internal void CancelReal() { Status = TaskStatus.Canceled; ProcessCompleteDelegates(); } private void HandleGenericException(Exception e) { HandleGenericException(new AggregateException(e)); } private void HandleGenericException(AggregateException e) { ExceptionSlot.Exception = e; Thread.MemoryBarrier(); Status = TaskStatus.Faulted; ProcessCompleteDelegates(); } internal void WaitOnChildren() { if (Status == TaskStatus.WaitingForChildrenToComplete && childTasks != null) { childTasks.Wait(); } } public void Wait() { Wait(-1, CancellationToken.None); } public void Wait(CancellationToken cancellationToken) { Wait(-1, cancellationToken); } public bool Wait(TimeSpan timeout) { return Wait(CheckTimeout(timeout), CancellationToken.None); } public bool Wait(int millisecondsTimeout) { return Wait(millisecondsTimeout, CancellationToken.None); } public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken) { if (millisecondsTimeout < -1) { throw new ArgumentOutOfRangeException("millisecondsTimeout"); } bool flag = true; if (!IsCompleted) { if (Status == TaskStatus.WaitingToRun && millisecondsTimeout == -1 && scheduler != null) { Execute(); } if (!IsCompleted) { ManualResetEventSlim manualResetEventSlim = new ManualResetEventSlim(); ManualEventSlot continuation = new ManualEventSlot(manualResetEventSlim); try { ContinueWith(continuation); flag = manualResetEventSlim.Wait(millisecondsTimeout, cancellationToken); } finally { if (!flag) { RemoveContinuation(continuation); } manualResetEventSlim.Dispose(); } } } if (IsCanceled) { throw new AggregateException(new TaskCanceledException(this)); } AggregateException exception = Exception; if (exception != null) { throw exception; } if (childTasks != null) { childTasks.Wait(); } return flag; } public static void WaitAll(params Task[] tasks) { WaitAll(tasks, -1, CancellationToken.None); } public static void WaitAll(Task[] tasks, CancellationToken cancellationToken) { WaitAll(tasks, -1, cancellationToken); } public static bool WaitAll(Task[] tasks, TimeSpan timeout) { return WaitAll(tasks, CheckTimeout(timeout), CancellationToken.None); } public static bool WaitAll(Task[] tasks, int millisecondsTimeout) { return WaitAll(tasks, millisecondsTimeout, CancellationToken.None); } public static bool WaitAll(Task[] tasks, int millisecondsTimeout, CancellationToken cancellationToken) { if (tasks == null) { throw new ArgumentNullException("tasks"); } bool flag = true; foreach (Task task in tasks) { if (task == null) { throw new ArgumentNullException("tasks", "the tasks argument contains a null element"); } flag &= task.Status == TaskStatus.RanToCompletion; } if (!flag) { CountdownEvent countdownEvent = new CountdownEvent(tasks.Length); CountdownEventSlot continuation = new CountdownEventSlot(countdownEvent); try { foreach (Task task2 in tasks) { task2.ContinueWith(continuation); } flag = countdownEvent.Wait(millisecondsTimeout, cancellationToken); } finally { List<Exception> list = null; foreach (Task task3 in tasks) { if (flag) { if (task3.Status != TaskStatus.RanToCompletion) { if (list == null) { list = new List<Exception>(); } if (task3.Exception != null) { list.AddRange(task3.Exception.InnerExceptions); } else { list.Add(new TaskCanceledException(task3)); } } } else { task3.RemoveContinuation(continuation); } } countdownEvent.Dispose(); if (list != null) { throw new AggregateException(list); } } } return flag; } public static int WaitAny(params Task[] tasks) { return WaitAny(tasks, -1, CancellationToken.None); } public static int WaitAny(Task[] tasks, TimeSpan timeout) { return WaitAny(tasks, CheckTimeout(timeout)); } public static int WaitAny(Task[] tasks, int millisecondsTimeout) { return WaitAny(tasks, millisecondsTimeout, CancellationToken.None); } public static int WaitAny(Task[] tasks, CancellationToken cancellationToken) { return WaitAny(tasks, -1, cancellationToken); } public static int WaitAny(Task[] tasks, int millisecondsTimeout, CancellationToken cancellationToken) { if (tasks == null) { throw new ArgumentNullException("tasks"); } if (millisecondsTimeout < -1) { throw new ArgumentOutOfRangeException("millisecondsTimeout"); } CheckForNullTasks(tasks); if (tasks.Length > 0) { ManualResetEventSlim manualResetEventSlim = new ManualResetEventSlim(); ManualEventSlot continuation = new ManualEventSlot(manualResetEventSlim); bool flag = false; try { for (int i = 0; i < tasks.Length; i++) { Task task = tasks[i]; if (task.IsCompleted) { return i; } task.ContinueWith(continuation); } if (!(flag = manualResetEventSlim.Wait(millisecondsTimeout, cancellationToken))) { return -1; } } finally { if (!flag) { foreach (Task task2 in tasks) { task2.RemoveContinuation(continuation); } } manualResetEventSlim.Dispose(); } } int result = -1; for (int k = 0; k < tasks.Length; k++) { Task task3 = tasks[k]; if (task3.IsCompleted) { result = k; break; } } return result; } private static int CheckTimeout(TimeSpan timeout) { try { return checked((int)timeout.TotalMilliseconds); } catch (OverflowException) { throw new ArgumentOutOfRangeException("timeout"); } } private static void CheckForNullTasks(Task[] tasks) { foreach (Task task in tasks) { if (task == null) { throw new ArgumentNullException("tasks", "the tasks argument contains a null element"); } } } public void Dispose() { Dispose(disposing: true); } protected virtual void Dispose(bool disposing) { if (!IsCompleted) { throw new InvalidOperationException("A task may only be disposed if it is in a completion state"); } if (disposing) { invoker = null; state = null; if (cancellationRegistration.HasValue) { cancellationRegistration.Value.Dispose(); } } } public Task ContinueWith(Action<Task, object> continuationAction, object state) { return ContinueWith(continuationAction, state, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Current); } public Task ContinueWith(Action<Task, object> continuationAction, object state, CancellationToken cancellationToken) { return ContinueWith(continuationAction, state, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current); } public Task ContinueWith(Action<Task, object> continuationAction, object state, TaskContinuationOptions continuationOptions) { return ContinueWith(continuationAction, state, CancellationToken.None, continuationOptions, TaskScheduler.Current); } public Task ContinueWith(Action<Task, object> continuationAction, object state, TaskScheduler scheduler) { return ContinueWith(continuationAction, state, CancellationToken.None, TaskContinuationOptions.None, scheduler); } public Task ContinueWith(Action<Task, object> continuationAction, object state, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler) { if (continuationAction == null) { throw new ArgumentNullException("continuationAction"); } if (scheduler == null) { throw new ArgumentNullException("scheduler"); } Task task = new Task(TaskActionInvoker.Create(continuationAction), state, cancellationToken, GetCreationOptions(continuationOptions), parent, this); ContinueWithCore(task, continuationOptions, scheduler); return task; } public Task<TResult> ContinueWith<TResult>(Func<Task, object, TResult> continuationFunction, object state) { return ContinueWith(continuationFunction, state, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Current); } public Task<TResult> ContinueWith<TResult>(Func<Task, object, TResult> continuationFunction, object state, TaskContinuationOptions continuationOptions) { return ContinueWith(continuationFunction, state, CancellationToken.None, continuationOptions, TaskScheduler.Current); } public Task<TResult> ContinueWith<TResult>(Func<Task, object, TResult> continuationFunction, object state, CancellationToken cancellationToken) { return ContinueWith(continuationFunction, state, cancellationToken, TaskContinuationOptions.None, TaskScheduler.Current); } public Task<TResult> ContinueWith<TResult>(Func<Task, object, TResult> continuationFunction, object state, TaskScheduler scheduler) { return ContinueWith(continuationFunction, state, CancellationToken.None, TaskContinuationOptions.None, scheduler); } public Task<TResult> ContinueWith<TResult>(Func<Task, object, TResult> continuationFunction, object state, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler) { if (continuationFunction == null) { throw new ArgumentNullException("continuationFunction"); } if (scheduler == null) { throw new ArgumentNullException("scheduler"); } Task<TResult> task = new Task<TResult>(TaskActionInvoker.Create(continuationFunction), state, cancellationToken, GetCreationOptions(continuationOptions), parent, this); ContinueWithCore(task, continuationOptions, scheduler); return task; } public static Task<TResult> FromResult<TResult>(TResult result) { TaskCompletionSource<TResult> taskCompletionSource = new TaskCompletionSource<TResult>(); taskCompletionSource.SetResult(result); return taskCompletionSource.Task; } public static Task Run(Action action) { return Run(action, CancellationToken.None); } public static Task Run(Action action, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return TaskConstants.Canceled; } Task task = new Task(action, cancellationToken, TaskCreationOptions.DenyChildAttach); task.Start(); return task; } public static Task Run(Func<Task> function) { return Run(function, CancellationToken.None); } public static Task Run(Func<Task> function, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return TaskConstants.Canceled; } Task<Task> task = new Task<Task>(function, cancellationToken); task.Start(); return task; } public static Task<TResult> Run<TResult>(Func<TResult> function) { return Run(function, CancellationToken.None); } public static Task<TResult> Run<TResult>(Func<TResult> function, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return TaskConstants<TResult>.Canceled; } Task<TResult> task = new Task<TResult>(function, cancellationToken, TaskCreationOptions.DenyChildAttach); task.Start(); return task; } } } namespace System.Collections.Concurrent { public interface IProducerConsumerCollection<T> : IEnumerable<T>, ICollection, IEnumerable { bool TryAdd(T item); bool TryTake(out T item); T[] ToArray(); void CopyTo(T[] array, int index); } [DebuggerTypeProxy(typeof(CollectionDebuggerView<>))] [DebuggerDisplay("Count={Count}")] public class ConcurrentQueue<T> : IProducerConsumerCollection<T>, IEnumerable<T>, ICollection, IEnumerable { private class Node { public T Value; public Node Next; } private class NodeObjectPool : ObjectPool<Node> { protected override Node Creator() { return new Node(); } } private Node head = new Node(); private Node tail; private int count; private static readonly NodeObjectPool pool = new NodeObjectPool(); private object syncRoot = new object(); bool ICollection.IsSynchronized => true; object ICollection.SyncRoot => syncRoot; public int Count => count; public bool IsEmpty => count == 0; private static Node ZeroOut(Node node) { node.Value = default(T); node.Next = null; return node; } public ConcurrentQueue() { tail = head; } public ConcurrentQueue(IEnumerable<T> collection) : this() { foreach (T item in collection) { Enqueue(item); } } public void Enqueue(T item) { Node node = pool.Take(); node.Value = item; Node node2 = null; Node node3 = null; bool flag = false; while (!flag) { node2 = tail; node3 = node2.Next; if (tail == node2) { if (node3 == null) { flag = Interlocked.CompareExchange(ref tail.Next, node, null) == null; } else { Interlocked.CompareExchange(ref tail, node3, node2); } } } Interlocked.CompareExchange(ref tail, node, node2); Interlocked.Increment(ref count); } bool IProducerConsumerCollection<T>.TryAdd(T item) { Enqueue(item); return true; } public bool TryDequeue(out T result) { result = default(T); bool flag = false; while (!flag) { Node node = head; Node node2 = tail; Node next = node.Next; if (node != head) { continue; } if (node == node2) { if (next != null) { Interlocked.CompareExchange(ref tail, next, node2); } result = default(T); return false; } result = next.Value; flag = Interlocked.CompareExchange(ref head, next, node) == node; if (flag) { pool.Release(ZeroOut(node)); } } Interlocked.Decrement(ref count); return true; } public bool TryPeek(out T result) { if (IsEmpty) { result = default(T); return false; } Node next = head.Next; result = next.Value; return true; } internal void Clear() { count = 0; tail = (head = new Node()); } IEnumerator IEnumerable.GetEnumerator() { return InternalGetEnumerator(); } public IEnumerator<T> GetEnumerator() { return InternalGetEnumerator(); } private IEnumerator<T> InternalGetEnumerator() { Node my_head = head; while (true) { Node next; my_head = (next = my_head.Next); if (next != null) { yield return my_head.Value; continue; } break; } } void ICollection.CopyTo(Array array, int index) { if (array is T[] array2) { CopyTo(array2, index); } } public void CopyTo(T[] array, int index) { IEnumerator<T> enumerator = InternalGetEnumerator(); int num = index; while (enumerator.MoveNext()) { array[num++] = enumerator.Current; } } public T[] ToArray() { T[] array = new T[count]; CopyTo(array, 0); return array; } bool IProducerConsumerCollection<T>.TryTake(out T item) { return TryDequeue(out item); } } } namespace System { [Serializable] [DebuggerDisplay("Count = {InnerExceptions.Count}")] public class AggregateException : Exception { private const string defaultMessage = "One or more errors occured"; private List<Exception> innerExceptions = new List<Exception>(); public ReadOnlyCollection<Exception> InnerExceptions => innerExceptions.AsReadOnly(); public AggregateException() : base("One or more errors occured") { } public AggregateException(string message) : base(message) { } public AggregateException(string message, Exception innerException) : base(message, innerException) { if (innerException == null) { throw new ArgumentNullException("innerException"); } innerExceptions.Add(innerException); } protected AggregateException(SerializationInfo info, StreamingContext context) : base(info, context) { } public AggregateException(params Exception[] innerExceptions) : this(string.Empty, innerExceptions) { } public AggregateException(string message, params Exception[] innerExceptions) : base(message, (innerExceptions == null || innerExceptions.Length == 0) ? null : innerExceptions[0]) { if (innerExceptions == null) { throw new ArgumentNullException("innerExceptions"); } foreach (Exception ex in innerExceptions) { if (ex == null) { throw new ArgumentException("One of the inner exception is null", "innerExceptions"); } } this.innerExceptions.AddRange(innerExceptions); } public AggregateException(IEnumerable<Exception> innerExceptions) : this("One or more errors occured", innerExceptions) { } public AggregateException(string message, IEnumerable<Exception> innerExceptions) : this(message, new List<Exception>(innerExceptions).ToArray()) { } public AggregateException Flatten() { List<Exception> list = new List<Exception>(); foreach (Exception innerException in innerExceptions) { if (innerException is AggregateException ex) { list.AddRange(ex.Flatten().InnerExceptions); } else { list.Add(innerException); } } return new AggregateException(list); } public void Handle(Func<Exception, bool> predicate) { List<Exception> list = new List<Exception>(); foreach (Exception innerException in innerExceptions) { try { if (!predicate(innerException)) { list.Add(innerException); } } catch { throw new AggregateException(list); } } if (list.Count > 0) { throw new AggregateException(list); } } internal void AddChildException(AggregateException childEx) { if (innerExceptions == null) { innerExceptions = new List<Exception>(); } if (childEx != null) { innerExceptions.Add(childEx); } } public override string ToString() { StringBuilder stringBuilder = new StringBuilder(base.ToString()); int num = -1; foreach (Exception innerException in innerExceptions) { stringBuilder.Append(Environment.NewLine); stringBuilder.Append(" --> (Inner exception "); stringBuilder.Append(++num); stringBuilder.Append(") "); stringBuilder.Append(innerException.ToString()); stringBuilder.Append(Environment.NewLine); } return stringBuilder.ToString(); } public override void GetObjectData(SerializationInfo info, StreamingContext context) { throw new NotImplementedException(); } public override Exception GetBaseException() { if (innerExceptions == null || innerExceptions.Count == 0) { return this; } return innerExceptions[0].GetBaseException(); } } } namespace System.Threading.Tasks { internal class TaskExceptionSlot { public volatile AggregateException Exception; public volatile bool Observed; public ConcurrentQueue<AggregateException> ChildExceptions; private Task parent; public TaskExceptionSlot(Task parent) { this.parent = parent; } ~TaskExceptionSlot() { if (Exception != null && (!Observed && !TaskScheduler.FireUnobservedEvent(parent, Exception).Observed)) { parent = null; throw Exception; } } } internal abstract class TaskActionInvoker { private sealed class EmptyTaskActionInvoker : TaskActionInvoker { public override Delegate Action => null; public override void Invoke(Task owner, object state, Task context) { } } private sealed class ActionInvoke : TaskActionInvoker { private readonly Action action; public override Delegate Action => action; public ActionInvoke(Action action) { this.action = action; } public override void Invoke(Task owner, object state, Task context) { action(); } } private sealed class ActionObjectInvoke : TaskActionInvoker { private readonly Action<object> action; public override Delegate Action => action; public ActionObjectInvoke(Action<object> action) { this.action = action; } public override void Invoke(Task owner, object state, Task context) { action(state); } } private sealed class ActionTaskInvoke : TaskActionInvoker { private readonly Action<Task> action; public override Delegate Action => action; public ActionTaskInvoke(Action<Task> action) { this.action = action; } public override void Invoke(Task owner, object state, Task context) { action(owner); } } private sealed class ActionTasksInvoke : TaskActionInvoker { private readonly Action<Task[]> action; private readonly Task[] tasks; public override Delegate Action => action; public ActionTasksInvoke(Action<Task[]> action, Task[] tasks) { this.action = action; this.tasks = tasks; } public override void Invoke(Task owner, object state, Task context) { action(tasks); } } private sealed class ActionTaskObjectInvoke : TaskActionInvoker { private readonly Action<Task, object> action; public override Delegate Action => action; public ActionTaskObjectInvoke(Action<Task, object> action) { this.action = action; } public override void Invoke(Task owner, object state, Task context) { action(owner, state); } } private sealed class ActionTaskObjectInvoke<TResult> : TaskActionInvoker { private readonly Action<Task<TResult>, object> action; public override Delegate Action => action; public ActionTaskObjectInvoke(Action<Task<TResult>, object> action) { this.action = action; } public override void Invoke(Task owner, object state, Task context) { action((Task<TResult>)owner, state); } } private sealed class ActionTaskInvoke<TResult> : TaskActionInvoker { private readonly Action<Task<TResult>> action; public override Delegate Action => action; public ActionTaskInvoke(Action<Task<TResult>> action) { this.action = action; } public override void Invoke(Task owner, object state, Task context) { action((Task<TResult>)owner); } } private sealed class ActionTaskSelected : TaskActionInvoker { private readonly Action<Task> action; private readonly Task[] tasks; public override Delegate Action => action; public ActionTaskSelected(Action<Task> action, Task[] tasks) { this.action = action; this.tasks = tasks; } public override void Invoke(Task owner, object state, Task context) { int result = ((Task<int>)owner).Result; action(tasks[result]); } } private sealed class FuncInvoke<TResult> : TaskActionInvoker { private readonly Func<TResult> action; public override Delegate Action => action; public FuncInvoke(Func<TResult> action) { this.action = action; } public override void Invoke(Task owner, object state, Task context) { ((Task<TResult>)context).Result = action(); } } private sealed class FuncTaskInvoke<TResult> : TaskActionInvoker { private readonly Func<Task, TResult> action; public override Delegate Action => action; public FuncTaskInvoke(Func<Task, TResult> action) { this.action = action; } public override void Invoke(Task owner, object state, Task context) { ((Task<TResult>)context).Result = action(owner); } } private sealed class FuncTasksInvoke<TResult> : TaskActionInvoker { private readonly Func<Task[], TResult> action; private readonly Task[] tasks; public override Delegate Action => action; public FuncTasksInvoke(Func<Task[], TResult> action, Task[] tasks) { this.action = action; this.tasks = tasks; } public override void Invoke(Task owner, object state, Task context) { ((Task<TResult>)context).Result = action(tasks); } } private sealed class FuncTaskSelected<TResult> : TaskActionInvoker { private readonly Func<Task, TResult> action; private readonly Task[] tasks; public override Delegate Action => action; public FuncTaskSelected(Func<Task, TResult> action, Task[] tasks) { this.action = action; this.tasks = tasks; } public override void Invoke(Task owner, object state, Task context) { int result = ((Task<int>)owner).Result; ((Task<TResult>)context).Result = action(tasks[result]); } } private sealed class FuncTaskInvoke<TResult, TNewResult> : TaskActionInvoker { private readonly Func<Task<TResult>, TNewResult> action; public override Delegate Action => action; public FuncTaskInvoke(Func<Task<TResult>, TNewResult> action) { this.action = action; } public override void Invoke(Task owner, object state, Task context) { ((Task<TNewResult>)context).Result = action((Task<TResult>)owner); } } private sealed class FuncObjectInvoke<TResult> : TaskActionInvoker { private readonly Func<object, TResult> action; public override Delegate Action => action; public FuncObjectInvoke(Func<object, TResult> action) { this.action = action; } public override void Invoke(Task owner, object state, Task context) { ((Task<TResult>)context).Result = action(state); } } private sealed class FuncTaskObjectInvoke<TResult> : TaskActionInvoker { private readonly Func<Task, object, TResult> action; public override Delegate Action => action; public FuncTaskObjectInvoke(Func<Task, object, TResult> action) { this.action = action; } public override void Invoke(Task owner, object state, Task context) { ((Task<TResult>)context).Result = action(owner, state); } } private sealed class FuncTaskObjectInvoke<TResult, TNewResult> : TaskActionInvoker { private readonly Func<Task<TResult>, object, TNewResult> action; public override Delegate Action => action; public FuncTaskObjectInvoke(Func<Task<TResult>, object, TNewResult> action) { this.action = action; } public override void Invoke(Task owner, object state, Task context) { ((Task<TNewResult>)context).Result = action((Task<TResult>)owner, state); } } public static readonly TaskActionInvoker Empty = new EmptyTaskActionInvoker(); public abstract Delegate Action { get; } public static TaskActionInvoker Create(Action action) { return new ActionInvoke(action); } public static TaskActionInvoker Create(Action<object> action) { return new ActionObjectInvoke(action); } public static TaskActionInvoker Create(Action<Task> action) { return new ActionTaskInvoke(action); } public static TaskActionInvoker Create(Action<Task, object> action) { return new ActionTaskObjectInvoke(action); } public static TaskActionInvoker Create<TResult>(Action<Task<TResult>> action) { return new ActionTaskInvoke<TResult>(action); } public static TaskActionInvoker Create<TResult>(Action<Task<TResult>, object> action) { return new ActionTaskObjectInvoke<TResult>(action); } public static TaskActionInvoker Create<TResult>(Func<TResult> action) { return new FuncInvoke<TResult>(action); } public static TaskActionInvoker Create<TResult>(Func<object, TResult> action) { return new FuncObjectInvoke<TResult>(action); } public static TaskActionInvoker Create<TResult>(Func<Task, TResult> action) { return new FuncTaskInvoke<TResult>(action); } public static TaskActionInvoker Create<TResult>(Func<Task, object, TResult> action) { return new FuncTaskObjectInvoke<TResult>(action); } public static TaskActionInvoker Create<TResult, TNewResult>(Func<Task<TResult>, TNewResult> action) { return new FuncTaskInvoke<TResult, TNewResult>(action); } public static TaskActionInvoker Create<TResult, TNewResult>(Func<Task<TResult>, object, TNewResult> action) { return new FuncTaskObjectInvoke<TResult, TNewResult>(action); } public static TaskActionInvoker Create(Action<Task[]> action, Task[] tasks) { return new ActionTasksInvoke(action, tasks); } public static TaskActionInvoker Create<TResult>(Func<Task[], TResult> action, Task[] tasks) { return new FuncTasksInvoke<TResult>(action, tasks); } public static TaskActionInvoker Create(Action<Task> action, Task[] tasks) { return new ActionTaskSelected(action, tasks); } public static TaskActionInvoker Create<TResult>(Func<Task, TResult> action, Task[] tasks) { return new FuncTaskSelected<TResult>(action, tasks); } public abstract void Invoke(Task owner, object state, Task context); } } namespace System.Collections { [Serializable] internal class ArrayList : IList, ICollection, IEnumerable { private sealed class ArrayListEnumerator : IEnumerator { private object m_Current; private ArrayList m_List; private int m_Pos; private int m_Index; private int m_Count; private int m_ExpectedStateChanges; public object Current { get { if (m_Pos == m_Index - 1) { throw new InvalidOperationException("Enumerator unusable (Reset pending, or past end of array."); } return m_Current; } } public ArrayListEnumerator(ArrayList list) : this(list, 0, list.Count) { } public object Clone() { return MemberwiseClone(); } public ArrayListEnumerator(ArrayList list, int index, int count) { m_List = list; m_Index = index; m_Count = count; m_Pos = m_Index - 1; m_Current = null; m_ExpectedStateChanges = list._version; } public bool MoveNext() { if (m_List._version != m_ExpectedStateChanges) { throw new InvalidOperationException("List has changed."); } m_Pos++; if (m_Pos - m_Index < m_Count) { m_Current = m_List[m_Pos]; return true; } return false; } public void Reset() { m_Current = null; m_Pos = m_Index - 1; } } private sealed class SimpleEnumerator : IEnumerator { private ArrayList list; private object currentElement; private int index; private int version; private static object endFlag = new object(); public object Current { get { if (currentElement == endFlag) { if (index == -1) { throw new InvalidOperationException("Enumerator not started"); } throw new InvalidOperationException("Enumerator ended"); } return currentElement; } } public SimpleEnumerator(ArrayList list) { this.list = list; index = -1; version = list._version; currentElement = endFlag; } public object Clone() { return MemberwiseClone(); } public bool MoveNext() { if (version != list._version) { throw new InvalidOperationException("List has changed."); } if (++index < list.Count) { currentElement = list[index]; return true; } currentElement = endFlag; return false; } public void Reset() { if (version != list._version) { throw new InvalidOperationException("List has changed."); } currentElement = endFlag; index = -1; } } [Serializable] private sealed class ArrayListAdapter : ArrayList { private sealed class EnumeratorWithRange : IEnumerator { private int m_StartIndex; private int m_Count; private int m_MaxCount; private IEnumerator m_Enumerator; public object Current => m_Enumerator.Current; public EnumeratorWithRange(IEnumerator enumerator, int index, int count) { m_Count = 0; m_StartIndex = index; m_MaxCount = count; m_Enumerator = enumerator; Reset(); } public object Clone() { return MemberwiseClone(); } public bool MoveNext() { if (m_Count >= m_MaxCount) { return false; } m_Count++; return m_Enumerator.MoveNext(); } public void Reset() { m_Count = 0; m_Enumerator.Reset(); for (int i = 0; i < m_StartIndex; i++) { m_Enumerator.MoveNext(); } } } private IList m_Adaptee; public override object this[int index] { get { return m_Adaptee[index]; } set { m_Adaptee[index] = value; } } public override int Count => m_Adaptee.Count; public override int Capacity { get { return m_Adaptee.Count; } set { if (value < m_Adaptee.Count) { throw new ArgumentException("capacity"); } } } public override bool IsFixedSize => m_Adaptee.IsFixedSize; public override bool IsReadOnly => m_Adaptee.IsReadOnly; public override object SyncRoot => m_Adaptee.SyncRoot; public override bool IsSynchronized => m_Adaptee.IsSynchronized; public ArrayListAdapter(IList adaptee) : base(0, forceZeroSize: true) { m_Adaptee = adaptee; } public override int Add(object value) { return m_Adaptee.Add(value); } public override void Clear() { m_Adaptee.Clear(); } public override bool Contains(object value) { return m_Adaptee.Contains(value); } public override int IndexOf(object value) { return m_Adaptee.IndexOf(value); } public override int IndexOf(object value, int startIndex) { return IndexOf(value, startIndex, m_Adaptee.Count - startIndex); } public override int IndexOf(object value, int startIndex, int count) { if (startIndex < 0 || startIndex > m_Adaptee.Count) { ThrowNewArgumentOutOfRangeException("startIndex", startIndex, "Does not specify valid index."); } if (count < 0) { ThrowNewArgumentOutOfRangeException("count", count, "Can't be less than 0."); } if (startIndex > m_Adaptee.Count - count) { throw new ArgumentOutOfRangeException("count", "Start index and count do not specify a valid range."); } if (value == null) { for (int i = startIndex; i < startIndex + count; i++) { if (m_Adaptee[i] == null) { return i; } } } else { for (int j = startIndex; j < startIndex + count; j++) { if (value.Equals(m_Adaptee[j])) { return j; } } } return -1; } public override int LastIndexOf(object value) { return LastIndexOf(value, m_Adaptee.Count - 1); } public override int LastIndexOf(object value, int startIndex) { return LastIndexOf(value, startIndex, startIndex + 1); } public override int LastIndexOf(object value, int startIndex, int count) { if (startIndex < 0) { ThrowNewArgumentOutOfRangeException("startIndex", startIndex, "< 0"); } if (count < 0) { ThrowNewArgumentOutOfRangeException("count", count, "count is negative."); } if (startIndex - count + 1 < 0) { ThrowNewArgumentOutOfRangeException("count", count, "count is too large."); } if (value == null) { for (int num = startIndex; num > startIndex - count; num--) { if (m_Adaptee[num] == null) { return num; } } } else { for (int num2 = startIndex; num2 > startIndex - count; num2--) { if (value.Equals(m_Adaptee[num2])) { return num2; } } } return -1; } public override void Insert(int index, object value) { m_Adaptee.Insert(index, value); } public override void InsertRange(int index, ICollection c) { if (c == null) { throw new ArgumentNullException("c"); } if (index > m_Adaptee.Count) { ThrowNewArgumentOutOfRangeException("index", index, "Index must be >= 0 and <= Count."); } foreach (object item in c) { m_Adaptee.Insert(index++, item); } } public override void Remove(object value) { m_Adaptee.Remove(value); } public override void RemoveAt(int index) { m_Adaptee.RemoveAt(index); } public override void RemoveRange(int index, int count) { CheckRange(index, count, m_Adaptee.Count); for (int i = 0; i < count; i++) { m_Adaptee.RemoveAt(index); } } public override void Reverse() { Reverse(0, m_Adaptee.Count); } public override void Reverse(int index, int count) { CheckRange(index, count, m_Adaptee.Count); for (int i = 0; i < count / 2; i++) { object value = m_Adaptee[i + index]; m_Adaptee[i + index] = m_Adaptee[index + count - i + index - 1]; m_Adaptee[index + count - i + index - 1] = value; } } public override void SetRange(int index, ICollection c) { if (c == null) { throw new ArgumentNullException("c"); } if (index < 0 || index + c.Count > m_Adaptee.Count) { throw new ArgumentOutOfRangeException("index"); } int num = index; foreach (object item in c) { m_Adaptee[num++] = item; } } public override void CopyTo(Array array) { m_Adaptee.CopyTo(array, 0); } public override void CopyTo(Array array, int index) { m_Adaptee.CopyTo(array, index); } public override void CopyTo(int index, Array array, int arrayIndex, int count) { if (index < 0) { ThrowNewArgumentOutOfRangeException("index", index, "Can't be less than zero."); } if (arrayIndex < 0) { ThrowNewArgumentOutOfRangeException("arrayIndex", arrayIndex, "Can't be less than zero."); } if (count < 0) { ThrowNewArgumentOutOfRangeException("index", index, "Can't be less than zero."); } if (index >= m_Adaptee.Count) { throw new ArgumentException("Can't be more or equal to list count.", "index"); } if (array.Rank > 1) { throw new ArgumentException("Can't copy into multi-dimensional array."); } if (arrayIndex >= array.Length) { throw new ArgumentException("arrayIndex can't be greater than array.Length - 1."); } if (array.Length - arrayIndex + 1 < count) { throw new ArgumentException("Destination array is too small."); } if (index > m_Adaptee.Count - count) { throw new ArgumentException("Index and count do not denote a valid range of elements.", "index"); } for (int i = 0; i < count; i++) { array.SetValue(m_Adaptee[index + i], arrayIndex + i); } } public override IEnumerator GetEnumerator() { return m_Adaptee.GetEnumerator(); } public override IEnumerator GetEnumerator(int index, int count) { CheckRange(index, count, m_Adaptee.Count); return new EnumeratorWithRange(m_Adaptee.GetEnumerator(), index, count); } public override void AddRange(ICollection c) { foreach (object item in c) { m_Adaptee.Add(item); } } public override int BinarySearch(object value) { return BinarySearch(value, null); } public override int BinarySearch(object value, IComparer comparer) { return BinarySearch(0, m_Adaptee.Count, value, comparer); } public override int BinarySearch(int index, int count, object value, IComparer comparer) { CheckRange(index, count, m_Adaptee.Count); if (comparer == null) { comparer = Comparer.Default; } int num = index; int num2 = index + count - 1; while (num <= num2) { int num3 = num + (num2 - num) / 2; int num4 = comparer.Compare(value, m_Adaptee[num3]); if (num4 < 0) { num2 = num3 - 1; continue; } if (num4 > 0) { num = num3 + 1; continue; } return num3; } return ~num; } public override object Clone() { return new ArrayListAdapter(m_Adaptee); } public override ArrayList GetRange(int index, int count) { CheckRange(index, count, m_Adaptee.Count); return new RangedArrayList(this, index, count); } public override void TrimToSize() { } public override void Sort() { Sort(Comparer.Default); } public override void Sort(IComparer comparer) { Sort(0, m_Adaptee.Count, comparer); } public override void Sort(int index, int count, IComparer comparer) { CheckRange(index, count, m_Adaptee.Count); if (comparer == null) { comparer = Comparer.Default; } QuickSort(m_Adaptee, index, index + count - 1, comparer); } private static void Swap(IList list, int x, int y) { object value = list[x]; list[x] = list[y]; list[y] = value; } internal static void QuickSort(IList list, int left, int right, IComparer comparer) { if (left >= right) { return; } int num = left + (right - left) / 2; if (comparer.Compare(list[num], list[left]) < 0) { Swap(list, num, left); } if (comparer.Compare(list[right], list[left]) < 0) { Swap(list, right, left); } if (comparer.Compare(list[right], list[num]) < 0) { Swap(list, right, num); } if (right - left + 1 <= 3) { return; } Swap(list, right - 1, num); object y = list[right - 1]; int num2 = left; int num3 = right - 1; while (true) { if (comparer.Compare(list[++num2], y) >= 0) { while (comparer.Compare(list[--num3], y) > 0) { } if (num2 >= num3) { break; } Swap(list, num2, num3); } } Swap(list, right - 1, num2); QuickSort(list, left, num2 - 1, comparer); QuickSort(list, num2 + 1, right, comparer); } public override object[] ToArray() { object[] array = new object[m_Adaptee.Count]; m_Adaptee.CopyTo(array, 0); return array; } public override Array ToArray(Type elementType) { Array array = Array.CreateInstance(elementType, m_Adaptee.Count); m_Adaptee.CopyTo(array, 0); return array; } } [Serializable] private class ArrayListWrapper : ArrayList { protected ArrayList m_InnerArrayList; public override object this[int index] { get { return m_InnerArrayList[index]; } set { m_InnerArrayList[index] = value; } } public override int Count => m_InnerArrayList.Count; public override int Capacity { get { return m_InnerArrayList.Capacity; } set { m_InnerArrayList.Capacity = value; } } public override bool IsFixedSize => m_InnerArrayList.IsFixedSize; public override bool IsReadOnly => m_InnerArrayList.IsReadOnly; public override bool IsSynchronized => m_InnerArrayList.IsSynchronized; public override object SyncRoot => m_InnerArrayList.SyncRoot; public ArrayListWrapper(ArrayList innerArrayList) { m_InnerArrayList = innerArrayList; } public override int Add(object value) { return m_InnerArrayList.Add(value); } public override void Clear() { m_InnerArrayList.Clear(); } public override bool Contains(object value) { return m_InnerArrayList.Contains(value); } public override int IndexOf(object value) { return m_InnerArrayList.IndexOf(value); } public override int IndexOf(object value, int startIndex) { return m_InnerArrayList.IndexOf(value, startIndex); } public override int IndexOf(object value, int startIndex, int count) { return m_InnerArrayList.IndexOf(value, startIndex, count); } public override int LastIndexOf(object value) { return m_InnerArrayList.LastIndexOf(value); } public override int LastIndexOf(object value, int startIndex) { return m_InnerArrayList.LastIndexOf(value, startIndex); } public override int LastIndexOf(object value, int startIndex, int count) { return m_InnerArrayList.LastIndexOf(value, startIndex, count); } public override void Insert(int index, object value) { m_InnerArrayList.Insert(index, value); } public override void InsertRange(int index, ICollection c) { m_InnerArrayList.InsertRange(index, c); } public override void Remove(object value) { m_InnerArrayList.Remove(value); } public override void RemoveAt(int index) { m_InnerArrayList.RemoveAt(index); } public override void RemoveRange(int index, int count) { m_InnerArrayList.RemoveRange(index, count); } public override void Reverse() { m_InnerArrayList.Reverse(); } public override void Reverse(int index, int count) { m_InnerArrayList.Reverse(index, count); } public override void SetRange(int index, ICollection c) { m_InnerArrayList.SetRange(index, c); } public override void CopyTo(Array array) { m_InnerArrayList.CopyTo(array); } public override void CopyTo(Array array, int index) { m_InnerArrayList.CopyTo(array, index); } public override void CopyTo(int index, Array array, int arrayIndex, int count) { m_InnerArrayList.CopyTo(index, array, arrayIndex, count); } public override IEnumerator GetEnumerator() { return m_InnerArrayList.GetEnumerator(); } public override IEnumerator GetEnumerator(int index, int count) { return m_InnerArrayList.GetEnumerator(index, count); } public override void AddRange(ICollection c) { m_InnerArrayList.AddRange(c); } public override int BinarySearch(object value) { return m_InnerArrayList.BinarySearch(value); } public override int BinarySearch(object value, IComparer comparer) { return m_InnerArrayList.BinarySearch(value, comparer); } public override int BinarySearch(int index, int count, object value, IComparer comparer) { return m_InnerArrayList.BinarySearch(index, count, value, comparer); } public override object Clone() { return m_InnerArrayList.Clone(); } public override ArrayList GetRange(int index, int count) { return m_InnerArrayList.GetRange(index, count); } public override void TrimToSize() { m_InnerArrayList.TrimToSize(); } public override void Sort() { m_InnerArrayList.Sort(); } public override void Sort(IComparer comparer) { m_InnerArrayList.Sort(comparer); } public override void Sort(int index, int count, IComparer comparer) { m_InnerArrayList.Sort(index, count, comparer); } public override object[] ToArray() { return m_InnerArrayList.ToArray(); } public override Array ToArray(Type elementType) { return m_InnerArrayList.ToArray(elementType); } } [Serializable] private sealed class SynchronizedArrayListWrapper : ArrayListWrapper { private object m_SyncRoot; public override object this[int index] { get { lock (m_SyncRoot) { return m_InnerArrayList[index]; } } set { lock (m_SyncRoot) { m_InnerArrayList[index] = value; } } } public override int Count { get { lock (m_SyncRoot) { return m_InnerArrayList.Count; } } } public override int Capacity { get { lock (m_SyncRoot) { return m_InnerArrayList.Capacity; } } set { lock (m_SyncRoot) { m_InnerArrayList.Capacity = value; } } } public override bool IsFixedSize { get { lock (m_SyncRoot) { return m_InnerArrayList.IsFixedSize; } } } public override bool IsReadOnly { get { lock (m_SyncRoot) { return m_InnerArrayList.IsReadOnly; } } } public override bool IsSynchronized => true; public override object SyncRoot => m_SyncRoot; internal SynchronizedArrayListWrapper(ArrayList innerArrayList) : base(innerArrayList) { m_SyncRoot = innerArrayList.SyncRoot; } public override int Add(object value) { lock (m_SyncRoot) { return m_InnerArrayList.Add(value); } } public override void Clear() { lock (m_SyncRoot) { m_InnerArrayList.Clear(); } } public override bool Contains(object value) { lock (m_SyncRoot) { return m_InnerArrayList.Contains(value); } } public override int IndexOf(object value) { lock (m_SyncRoot) { return m_InnerArrayList.IndexOf(value); } } public override int IndexOf(object value, int startIndex) { lock (m_SyncRoot) { return m_InnerArrayList.IndexOf(value, startIndex); } } public override int IndexOf(object value, int startIndex, int count) { lock (m_S