[corlib] Use AppContextSwitches implementation from RS. Fixes #54448 (#4682)
[mono.git] / mcs / class / referencesource / mscorlib / system / AppContext / AppContextSwitches.cs
1 // ==++==
2 // 
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6
7 namespace System
8 {
9     using System;
10     using System.Runtime.CompilerServices;
11
12     internal static class AppContextSwitches
13     {
14 #if MOBILE
15                 public static readonly bool ThrowExceptionIfDisposedCancellationTokenSource = false;
16                 public static readonly bool SetActorAsReferenceWhenCopyingClaimsIdentity = false;
17                 public static readonly bool NoAsyncCurrentCulture = false;
18 #else
19         private static int _noAsyncCurrentCulture;
20         public static bool NoAsyncCurrentCulture
21         {
22             [MethodImpl(MethodImplOptions.AggressiveInlining)]
23             get
24             {
25                 return GetCachedSwitchValue(AppContextDefaultValues.SwitchNoAsyncCurrentCulture, ref _noAsyncCurrentCulture);
26             }
27         }
28
29         private static int _throwExceptionIfDisposedCancellationTokenSource;
30         public static bool ThrowExceptionIfDisposedCancellationTokenSource
31         {
32             [MethodImpl(MethodImplOptions.AggressiveInlining)]
33             get
34             {
35                 return GetCachedSwitchValue(AppContextDefaultValues.SwitchThrowExceptionIfDisposedCancellationTokenSource, ref _throwExceptionIfDisposedCancellationTokenSource);
36             }
37         }
38
39         private static int _preserveEventListnerObjectIdentity;
40         public static bool PreserveEventListnerObjectIdentity
41         {
42             [MethodImpl(MethodImplOptions.AggressiveInlining)]
43             get
44             {
45                 return GetCachedSwitchValue(AppContextDefaultValues.SwitchPreserveEventListnerObjectIdentity, ref _preserveEventListnerObjectIdentity);
46             }
47         }
48
49         private static int _useLegacyPathHandling;
50
51         /// <summary>
52         /// Use legacy path normalization logic and blocking of extended syntax.
53         /// </summary>
54         public static bool UseLegacyPathHandling
55         {
56             [MethodImpl(MethodImplOptions.AggressiveInlining)]
57             get
58             {
59                 return GetCachedSwitchValue(AppContextDefaultValues.SwitchUseLegacyPathHandling, ref _useLegacyPathHandling);
60             }
61         }
62
63         private static int _blockLongPaths;
64
65         /// <summary>
66         /// Throw PathTooLongException for paths greater than MAX_PATH or directories greater than 248 (as per CreateDirectory Win32 limitations)
67         /// </summary>
68         public static bool BlockLongPaths
69         {
70             [MethodImpl(MethodImplOptions.AggressiveInlining)]
71             get
72             {
73                 return GetCachedSwitchValue(AppContextDefaultValues.SwitchBlockLongPaths, ref _blockLongPaths);
74             }
75         }
76
77         private static int _cloneActor;
78
79         /// <summary>
80         /// When copying a ClaimsIdentity.Actor this switch controls whether ClaimsIdentity.Actor should be set as a reference or the result of Actor.Clone()
81         /// </summary>
82         public static bool SetActorAsReferenceWhenCopyingClaimsIdentity
83         {
84             [MethodImpl(MethodImplOptions.AggressiveInlining)]
85             get
86             {
87                 return GetCachedSwitchValue(AppContextDefaultValues.SwitchSetActorAsReferenceWhenCopyingClaimsIdentity, ref _cloneActor);
88             }
89         }
90
91         private static int _doNotAddrOfCspParentWindowHandle;
92         public static bool DoNotAddrOfCspParentWindowHandle
93         {
94             [MethodImpl(MethodImplOptions.AggressiveInlining)]
95             get
96             {
97                 return GetCachedSwitchValue(AppContextDefaultValues.SwitchDoNotAddrOfCspParentWindowHandle, ref _doNotAddrOfCspParentWindowHandle);
98             }
99         }
100
101         //
102         // Implementation details
103         //
104
105         private static bool DisableCaching { get; set; }
106
107         static AppContextSwitches()
108         {
109             bool isEnabled;
110             if (AppContext.TryGetSwitch(@"TestSwitch.LocalAppContext.DisableCaching", out isEnabled))
111             {
112                 DisableCaching = isEnabled;
113             }
114         }
115
116         [MethodImpl(MethodImplOptions.AggressiveInlining)]
117         internal static bool GetCachedSwitchValue(string switchName, ref int switchValue)
118         {
119             if (switchValue < 0) return false;
120             if (switchValue > 0) return true;
121
122             return GetCachedSwitchValueInternal(switchName, ref switchValue);
123         }
124
125         private static bool GetCachedSwitchValueInternal(string switchName, ref int switchValue)
126         {
127             bool isSwitchEnabled;
128             AppContext.TryGetSwitch(switchName, out isSwitchEnabled);
129
130             if (DisableCaching)
131             {
132                 return isSwitchEnabled;
133             }
134
135             switchValue = isSwitchEnabled ? 1 /*true*/ : -1 /*false*/;
136             return isSwitchEnabled;
137         }
138 #endif
139     }
140 }