summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStephen Toub <stoub@microsoft.com>2019-04-01 20:20:02 -0400
committerDan Moseley <danmose@microsoft.com>2019-04-01 17:20:02 -0700
commite06e85d79882027ecb4315ffcab76a6eecee030c (patch)
tree7e5141b975643e074b5f6c575c100f1437f7f4a0 /src
parentb86e0c59fc4b2691131de3cd789a4309e3cb7252 (diff)
downloadcoreclr-e06e85d79882027ecb4315ffcab76a6eecee030c.tar.gz
coreclr-e06e85d79882027ecb4315ffcab76a6eecee030c.tar.bz2
coreclr-e06e85d79882027ecb4315ffcab76a6eecee030c.zip
Nullable: Lazy (#23639)
Diffstat (limited to 'src')
-rw-r--r--src/System.Private.CoreLib/shared/System/Lazy.cs43
-rw-r--r--src/System.Private.CoreLib/shared/System/Threading/LazyInitializer.cs19
-rw-r--r--src/System.Private.CoreLib/shared/System/Threading/LazyThreadSafetyMode.cs1
3 files changed, 33 insertions, 30 deletions
diff --git a/src/System.Private.CoreLib/shared/System/Lazy.cs b/src/System.Private.CoreLib/shared/System/Lazy.cs
index ca445fc9d5..1fce87d0ca 100644
--- a/src/System.Private.CoreLib/shared/System/Lazy.cs
+++ b/src/System.Private.CoreLib/shared/System/Lazy.cs
@@ -10,9 +10,9 @@
//
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+#nullable enable
using System.Diagnostics;
using System.Runtime.ExceptionServices;
-using System.Runtime.InteropServices;
using System.Threading;
namespace System
@@ -51,7 +51,7 @@ namespace System
internal LazyState State { get; }
- private readonly ExceptionDispatchInfo _exceptionDispatch;
+ private readonly ExceptionDispatchInfo? _exceptionDispatch;
/// <summary>
/// Constructor that defines the state
@@ -121,14 +121,14 @@ namespace System
}
}
- internal static LazyThreadSafetyMode? GetMode(LazyHelper state)
+ internal static LazyThreadSafetyMode? GetMode(LazyHelper? state)
{
if (state == null)
return null; // we don't know the mode anymore
return state.GetMode();
}
- internal static bool GetIsValueFaulted(LazyHelper state) => state?._exceptionDispatch != null;
+ internal static bool GetIsValueFaulted(LazyHelper? state) => state?._exceptionDispatch != null;
internal static LazyHelper Create(LazyThreadSafetyMode mode, bool useDefaultConstructor)
{
@@ -189,14 +189,14 @@ namespace System
}
// _state, a volatile reference, is set to null after _value has been set
- private volatile LazyHelper _state;
+ private volatile LazyHelper? _state;
// we ensure that _factory when finished is set to null to allow garbage collector to clean up
// any referenced items
- private Func<T> _factory;
+ private Func<T>? _factory;
// _value eventually stores the lazily created value. It is valid when _state = null.
- private T _value;
+ private T _value = default!; // TODO-NULLABLE: Generic annotation
/// <summary>
/// Initializes a new instance of the <see cref="T:System.Threading.Lazy{T}"/> class that
@@ -206,7 +206,7 @@ namespace System
/// An instance created with this constructor may be used concurrently from multiple threads.
/// </remarks>
public Lazy()
- : this(null, LazyThreadSafetyMode.ExecutionAndPublication, useDefaultConstructor:true)
+ : this(null, LazyThreadSafetyMode.ExecutionAndPublication, useDefaultConstructor: true)
{
}
@@ -237,7 +237,7 @@ namespace System
/// An instance created with this constructor may be used concurrently from multiple threads.
/// </remarks>
public Lazy(Func<T> valueFactory)
- : this(valueFactory, LazyThreadSafetyMode.ExecutionAndPublication, useDefaultConstructor:false)
+ : this(valueFactory, LazyThreadSafetyMode.ExecutionAndPublication, useDefaultConstructor: false)
{
}
@@ -248,7 +248,7 @@ namespace System
/// <param name="isThreadSafe">true if this instance should be usable by multiple threads concurrently; false if the instance will only be used by one thread at a time.
/// </param>
public Lazy(bool isThreadSafe) :
- this(null, LazyHelper.GetModeFromIsThreadSafe(isThreadSafe), useDefaultConstructor:true)
+ this(null, LazyHelper.GetModeFromIsThreadSafe(isThreadSafe), useDefaultConstructor: true)
{
}
@@ -275,7 +275,7 @@ namespace System
/// <exception cref="System.ArgumentNullException"><paramref name="valueFactory"/> is
/// a null reference (Nothing in Visual Basic).</exception>
public Lazy(Func<T> valueFactory, bool isThreadSafe) :
- this(valueFactory, LazyHelper.GetModeFromIsThreadSafe(isThreadSafe), useDefaultConstructor:false)
+ this(valueFactory, LazyHelper.GetModeFromIsThreadSafe(isThreadSafe), useDefaultConstructor: false)
{
}
@@ -295,7 +295,7 @@ namespace System
{
}
- private Lazy(Func<T> valueFactory, LazyThreadSafetyMode mode, bool useDefaultConstructor)
+ private Lazy(Func<T>? valueFactory, LazyThreadSafetyMode mode, bool useDefaultConstructor)
{
if (valueFactory == null && !useDefaultConstructor)
throw new ArgumentNullException(nameof(valueFactory));
@@ -314,7 +314,7 @@ namespace System
{
try
{
- Func<T> factory = _factory;
+ Func<T>? factory = _factory;
if (factory == null)
throw new InvalidOperationException(SR.Lazy_Value_RecursiveCallsToValue);
_factory = null;
@@ -351,7 +351,7 @@ namespace System
private void PublicationOnly(LazyHelper publicationOnly, T possibleValue)
{
- LazyHelper previous = Interlocked.CompareExchange(ref _state, LazyHelper.PublicationOnlyWaitForOtherThreadToPublish, publicationOnly);
+ LazyHelper? previous = Interlocked.CompareExchange(ref _state, LazyHelper.PublicationOnlyWaitForOtherThreadToPublish, publicationOnly);
if (previous == publicationOnly)
{
_factory = null;
@@ -367,7 +367,7 @@ namespace System
private void PublicationOnlyViaFactory(LazyHelper initializer)
{
- Func<T> factory = _factory;
+ Func<T>? factory = _factory;
if (factory == null)
{
PublicationOnlyWaitForOtherThreadToPublish();
@@ -393,7 +393,7 @@ namespace System
{
// we have to create a copy of state here, and use the copy exclusively from here on in
// so as to ensure thread safety.
- var state = _state;
+ LazyHelper? state = _state;
if (state != null)
{
switch (state.State)
@@ -440,9 +440,11 @@ namespace System
/// <exception cref="T:System.NullReferenceException">
/// The <see cref="Value"/> is null.
/// </exception>
- public override string ToString()
+ public override string? ToString()
{
- return IsValueCreated ? Value.ToString() : SR.Lazy_ToString_ValueNotCreated;
+ return IsValueCreated ?
+ Value!.ToString() : // TODO-NULLABLE: Documented to throw NullReferenceException
+ SR.Lazy_ToString_ValueNotCreated;
}
/// <summary>Gets the value of the Lazy&lt;T&gt; for debugging display purposes.</summary>
@@ -452,7 +454,7 @@ namespace System
{
if (!IsValueCreated)
{
- return default;
+ return default!; // TODO-NULLABLE: generic nullability
}
return _value;
}
@@ -527,8 +529,7 @@ namespace System
/// <summary>Returns the value of the Lazy object.</summary>
public T Value
{
- get
- { return _lazy.ValueForDebugDisplay; }
+ get { return _lazy.ValueForDebugDisplay; }
}
/// <summary>Returns the execution mode of the Lazy object</summary>
diff --git a/src/System.Private.CoreLib/shared/System/Threading/LazyInitializer.cs b/src/System.Private.CoreLib/shared/System/Threading/LazyInitializer.cs
index e7928b6f93..ef03b7e97c 100644
--- a/src/System.Private.CoreLib/shared/System/Threading/LazyInitializer.cs
+++ b/src/System.Private.CoreLib/shared/System/Threading/LazyInitializer.cs
@@ -8,6 +8,7 @@
//
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+#nullable enable
using System.Diagnostics;
namespace System.Threading
@@ -60,7 +61,7 @@ namespace System.Threading
{
try
{
- Interlocked.CompareExchange(ref target, Activator.CreateInstance<T>(), null);
+ Interlocked.CompareExchange(ref target, Activator.CreateInstance<T>(), null!); // TODO-NULLABLE: Need to be able to express ref T nullability
}
catch (MissingMethodException)
{
@@ -117,7 +118,7 @@ namespace System.Threading
throw new InvalidOperationException(SR.Lazy_StaticInit_InvalidOperation);
}
- Interlocked.CompareExchange(ref target, value, null);
+ Interlocked.CompareExchange(ref target, value, null!); // TODO-NULLABLE: Need to be able to express ref T nullability
Debug.Assert(target != null);
return target;
}
@@ -134,7 +135,7 @@ namespace System.Threading
/// <param name="syncLock">A reference to an object used as the mutually exclusive lock for initializing
/// <paramref name="target"/>. If <paramref name="syncLock"/> is null, a new object will be instantiated.</param>
/// <returns>The initialized value of type <typeparamref name="T"/>.</returns>
- public static T EnsureInitialized<T>(ref T target, ref bool initialized, ref object syncLock)
+ public static T EnsureInitialized<T>(ref T target, ref bool initialized, ref object? syncLock)
{
// Fast path.
if (Volatile.Read(ref initialized))
@@ -156,7 +157,7 @@ namespace System.Threading
/// a new object will be instantiated.
/// </param>
/// <returns>The initialized object.</returns>
- private static T EnsureInitializedCore<T>(ref T target, ref bool initialized, ref object syncLock)
+ private static T EnsureInitializedCore<T>(ref T target, ref bool initialized, ref object? syncLock)
{
// Lazily initialize the lock if necessary and then double check if initialization is still required.
lock (EnsureLockInitialized(ref syncLock))
@@ -193,7 +194,7 @@ namespace System.Threading
/// <param name="valueFactory">The <see cref="T:System.Func{T}"/> invoked to initialize the
/// reference or value.</param>
/// <returns>The initialized value of type <typeparamref name="T"/>.</returns>
- public static T EnsureInitialized<T>(ref T target, ref bool initialized, ref object syncLock, Func<T> valueFactory)
+ public static T EnsureInitialized<T>(ref T target, ref bool initialized, ref object? syncLock, Func<T> valueFactory)
{
// Fast path.
if (Volatile.Read(ref initialized))
@@ -217,7 +218,7 @@ namespace System.Threading
/// The <see cref="T:System.Func{T}"/> to invoke in order to produce the lazily-initialized value.
/// </param>
/// <returns>The initialized object.</returns>
- private static T EnsureInitializedCore<T>(ref T target, ref bool initialized, ref object syncLock, Func<T> valueFactory)
+ private static T EnsureInitializedCore<T>(ref T target, ref bool initialized, ref object? syncLock, Func<T> valueFactory)
{
// Lazily initialize the lock if necessary and then double check if initialization is still required.
lock (EnsureLockInitialized(ref syncLock))
@@ -241,7 +242,7 @@ namespace System.Threading
/// <paramref name="target"/>. If <paramref name="syncLock"/> is null, a new object will be instantiated.</param>
/// <param name="valueFactory">The <see cref="T:System.Func{T}"/> invoked to initialize the reference.</param>
/// <returns>The initialized value of type <typeparamref name="T"/>.</returns>
- public static T EnsureInitialized<T>(ref T target, ref object syncLock, Func<T> valueFactory) where T : class =>
+ public static T EnsureInitialized<T>(ref T target, ref object? syncLock, Func<T> valueFactory) where T : class =>
Volatile.Read(ref target) ?? EnsureInitializedCore(ref target, ref syncLock, valueFactory);
/// <summary>
@@ -256,7 +257,7 @@ namespace System.Threading
/// The <see cref="T:System.Func{T}"/> to invoke in order to produce the lazily-initialized value.
/// </param>
/// <returns>The initialized object.</returns>
- private static T EnsureInitializedCore<T>(ref T target, ref object syncLock, Func<T> valueFactory) where T : class
+ private static T EnsureInitializedCore<T>(ref T target, ref object? syncLock, Func<T> valueFactory) where T : class
{
// Lazily initialize the lock if necessary and then double check if initialization is still required.
lock (EnsureLockInitialized(ref syncLock))
@@ -280,7 +281,7 @@ namespace System.Threading
/// <param name="syncLock">A reference to a location containing a mutual exclusive lock. If <paramref name="syncLock"/> is null,
/// a new object will be instantiated.</param>
/// <returns>Initialized lock object.</returns>
- private static object EnsureLockInitialized(ref object syncLock) =>
+ private static object EnsureLockInitialized(ref object? syncLock) =>
syncLock ??
Interlocked.CompareExchange(ref syncLock, new object(), null) ??
syncLock;
diff --git a/src/System.Private.CoreLib/shared/System/Threading/LazyThreadSafetyMode.cs b/src/System.Private.CoreLib/shared/System/Threading/LazyThreadSafetyMode.cs
index 2d13f23762..ae650824d7 100644
--- a/src/System.Private.CoreLib/shared/System/Threading/LazyThreadSafetyMode.cs
+++ b/src/System.Private.CoreLib/shared/System/Threading/LazyThreadSafetyMode.cs
@@ -8,6 +8,7 @@
//
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+#nullable enable
namespace System.Threading
{
/// <summary>