From 332900b175457afa71f55baf4a5851c2fcd0271c Mon Sep 17 00:00:00 2001 From: Levi B Date: Tue, 10 Mar 2015 13:57:55 -0700 Subject: [PATCH] Allow XyzEncoder.Default to be settable. --- .../HtmlEncoder.cs | 30 ++++++++++++++----- .../JavaScriptStringEncoder.cs | 30 ++++++++++++++----- .../UrlEncoder.cs | 30 ++++++++++++++----- 3 files changed, 66 insertions(+), 24 deletions(-) diff --git a/src/Microsoft.Framework.WebEncoders/HtmlEncoder.cs b/src/Microsoft.Framework.WebEncoders/HtmlEncoder.cs index 4e30ba2505..6331189706 100644 --- a/src/Microsoft.Framework.WebEncoders/HtmlEncoder.cs +++ b/src/Microsoft.Framework.WebEncoders/HtmlEncoder.cs @@ -4,6 +4,7 @@ using System; using System.Diagnostics; using System.IO; +using System.Runtime.CompilerServices; using System.Threading; namespace Microsoft.Framework.WebEncoders @@ -57,20 +58,33 @@ namespace Microsoft.Framework.WebEncoders } /// - /// The default , which uses as its allow list. + /// A default instance of . /// + /// + /// This normally corresponds to . However, this property is + /// settable so that a developer can change the default implementation application-wide. + /// public static HtmlEncoder Default { get { - HtmlEncoder defaultEncoder = Volatile.Read(ref _defaultEncoder); - if (defaultEncoder == null) - { - defaultEncoder = new HtmlEncoder(); - Volatile.Write(ref _defaultEncoder, defaultEncoder); - } - return defaultEncoder; + return Volatile.Read(ref _defaultEncoder) ?? CreateDefaultEncoderSlow(); } + set + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + Volatile.Write(ref _defaultEncoder, value); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] // the JITter can attempt to inline the caller itself without worrying about us + private static HtmlEncoder CreateDefaultEncoderSlow() + { + var onDemandEncoder = new HtmlEncoder(); + return Interlocked.CompareExchange(ref _defaultEncoder, onDemandEncoder, null) ?? onDemandEncoder; } /// diff --git a/src/Microsoft.Framework.WebEncoders/JavaScriptStringEncoder.cs b/src/Microsoft.Framework.WebEncoders/JavaScriptStringEncoder.cs index 1703a5447a..26bc175b81 100644 --- a/src/Microsoft.Framework.WebEncoders/JavaScriptStringEncoder.cs +++ b/src/Microsoft.Framework.WebEncoders/JavaScriptStringEncoder.cs @@ -4,6 +4,7 @@ using System; using System.Diagnostics; using System.IO; +using System.Runtime.CompilerServices; using System.Threading; namespace Microsoft.Framework.WebEncoders @@ -57,20 +58,33 @@ namespace Microsoft.Framework.WebEncoders } /// - /// The default , which uses as its allow list. + /// A default instance of . /// + /// + /// This normally corresponds to . However, this property is + /// settable so that a developer can change the default implementation application-wide. + /// public static JavaScriptStringEncoder Default { get { - JavaScriptStringEncoder defaultEncoder = Volatile.Read(ref _defaultEncoder); - if (defaultEncoder == null) - { - defaultEncoder = new JavaScriptStringEncoder(); - Volatile.Write(ref _defaultEncoder, defaultEncoder); - } - return defaultEncoder; + return Volatile.Read(ref _defaultEncoder) ?? CreateDefaultEncoderSlow(); } + set + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + Volatile.Write(ref _defaultEncoder, value); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] // the JITter can attempt to inline the caller itself without worrying about us + private static JavaScriptStringEncoder CreateDefaultEncoderSlow() + { + var onDemandEncoder = new JavaScriptStringEncoder(); + return Interlocked.CompareExchange(ref _defaultEncoder, onDemandEncoder, null) ?? onDemandEncoder; } /// diff --git a/src/Microsoft.Framework.WebEncoders/UrlEncoder.cs b/src/Microsoft.Framework.WebEncoders/UrlEncoder.cs index 90f1bf2abc..3f487e2533 100644 --- a/src/Microsoft.Framework.WebEncoders/UrlEncoder.cs +++ b/src/Microsoft.Framework.WebEncoders/UrlEncoder.cs @@ -4,6 +4,7 @@ using System; using System.Diagnostics; using System.IO; +using System.Runtime.CompilerServices; using System.Threading; namespace Microsoft.Framework.WebEncoders @@ -57,20 +58,33 @@ namespace Microsoft.Framework.WebEncoders } /// - /// The default which uses as its allow list. + /// A default instance of . /// + /// + /// This normally corresponds to . However, this property is + /// settable so that a developer can change the default implementation application-wide. + /// public static UrlEncoder Default { get { - UrlEncoder defaultEncoder = Volatile.Read(ref _defaultEncoder); - if (defaultEncoder == null) - { - defaultEncoder = new UrlEncoder(); - Volatile.Write(ref _defaultEncoder, defaultEncoder); - } - return defaultEncoder; + return Volatile.Read(ref _defaultEncoder) ?? CreateDefaultEncoderSlow(); } + set + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + Volatile.Write(ref _defaultEncoder, value); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] // the JITter can attempt to inline the caller itself without worrying about us + private static UrlEncoder CreateDefaultEncoderSlow() + { + var onDemandEncoder = new UrlEncoder(); + return Interlocked.CompareExchange(ref _defaultEncoder, onDemandEncoder, null) ?? onDemandEncoder; } ///