From 063f0e706f17d6ccda910bf8ce922b668ab211e5 Mon Sep 17 00:00:00 2001 From: "Gaurav Khanna (CLR)" Date: Wed, 27 Jan 2016 08:54:21 -0800 Subject: [PATCH] Fix for CoreCLR issue 2881 - Fix race in Default ALC initialization. https://github.com/dotnet/coreclr/issues/2881 Incorporate PR feedback --- .../Runtime/Loader/AssemblyLoadContext.cs | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs b/src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs index c44365e1ff..48a4882c3c 100644 --- a/src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs +++ b/src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs @@ -285,21 +285,23 @@ namespace System.Runtime.Loader { get { - while (m_DefaultAssemblyLoadContext == null) + if (s_DefaultAssemblyLoadContext == null) { // Try to initialize the default assembly load context with apppath one if we are allowed to if (AssemblyLoadContext.CanUseAppPathAssemblyLoadContextInCurrentDomain()) { -#pragma warning disable 0420 - Interlocked.CompareExchange(ref m_DefaultAssemblyLoadContext, new AppPathAssemblyLoadContext(), null); - break; -#pragma warning restore 0420 + // Synchronize access to initializing Default ALC + lock(s_initLock) + { + if (s_DefaultAssemblyLoadContext == null) + { + s_DefaultAssemblyLoadContext = new AppPathAssemblyLoadContext(); + } + } } - // Otherwise, need to yield to other thread to finish the initialization - Thread.Yield(); } - return m_DefaultAssemblyLoadContext; + return s_DefaultAssemblyLoadContext; } } @@ -322,7 +324,7 @@ namespace System.Runtime.Loader } // Update the managed side as well. - m_DefaultAssemblyLoadContext = context; + s_DefaultAssemblyLoadContext = context; } // This call opens and closes the file, but does not add the @@ -395,7 +397,10 @@ namespace System.Runtime.Loader // Each AppDomain contains the reference to its AssemblyLoadContext instance, if one is // specified by the host. By having the field as a static, we are // making it an AppDomain-wide field. - private static volatile AssemblyLoadContext m_DefaultAssemblyLoadContext; + private static volatile AssemblyLoadContext s_DefaultAssemblyLoadContext; + + // Synchronization primitive for controlling initialization of Default load context + private static readonly object s_initLock = new Object(); } [System.Security.SecuritySafeCritical] -- 2.34.1