Avoid pulling in Lazy<T> during startup (dotnet/coreclr#22659)
authorJan Kotas <jkotas@microsoft.com>
Sun, 17 Feb 2019 01:49:06 +0000 (17:49 -0800)
committerGitHub <noreply@github.com>
Sun, 17 Feb 2019 01:49:06 +0000 (17:49 -0800)
Environment constructor runs on every startup path. Remove dependency on Lazy<T> from it.

Commit migrated from https://github.com/dotnet/coreclr/commit/98956dd6b9450bbcafe7c6934e532b557ae38918

src/libraries/System.Private.CoreLib/src/System/Environment.Unix.cs
src/libraries/System.Private.CoreLib/src/System/Environment.Windows.cs
src/libraries/System.Private.CoreLib/src/System/Environment.cs

index 3d54dfa..65a0260 100644 (file)
@@ -298,8 +298,9 @@ namespace System
 
         public static string NewLine => "\n";
 
-        private static readonly Lazy<OperatingSystem> s_osVersion = new Lazy<OperatingSystem>(() => GetOperatingSystem(Interop.Sys.GetUnixRelease()));
+        private static OperatingSystem GetOSVersion() => GetOperatingSystem(Interop.Sys.GetUnixRelease());
 
+        // Tests exercise this method for corner cases via private reflection
         private static OperatingSystem GetOperatingSystem(string release)
         {
             int major = 0, minor = 0, build = 0, revision = 0;
index db56ea1..0887630 100644 (file)
@@ -86,7 +86,7 @@ namespace System
             Interop.Kernel32.GetComputerName() ??
             throw new InvalidOperationException(SR.InvalidOperation_ComputerName);
 
-        private static readonly unsafe Lazy<OperatingSystem> s_osVersion = new Lazy<OperatingSystem>(() =>
+        private static unsafe OperatingSystem GetOSVersion()
         {
             var version = new Interop.Kernel32.OSVERSIONINFOEX { dwOSVersionInfoSize = sizeof(Interop.Kernel32.OSVERSIONINFOEX) };
             if (!Interop.Kernel32.GetVersionExW(ref version))
@@ -98,7 +98,7 @@ namespace System
                 PlatformID.Win32NT,
                 new Version(version.dwMajorVersion, version.dwMinorVersion, version.dwBuildNumber, (version.wServicePackMajor << 16) | version.wServicePackMinor),
                 Marshal.PtrToStringUni((IntPtr)version.szCSDVersion));
-        });
+        }
 
         public static string SystemDirectory
         {
index 870f22d..bb99dc8 100644 (file)
@@ -6,6 +6,7 @@ using System.Collections;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Reflection;
+using System.Threading;
 
 namespace System
 {
@@ -112,7 +113,19 @@ namespace System
 
         public static bool Is64BitOperatingSystem => Is64BitProcess || Is64BitOperatingSystemWhen32BitProcess;
 
-        public static OperatingSystem OSVersion => s_osVersion.Value;
+        private static OperatingSystem s_osVersion;
+
+        public static OperatingSystem OSVersion
+        {
+            get
+            {
+                if (s_osVersion == null)
+                {
+                    Interlocked.CompareExchange(ref s_osVersion, GetOSVersion(), null);
+                }
+                return s_osVersion;
+            }
+        }
 
         public static bool UserInteractive => true;