summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStephen Toub <stoub@microsoft.com>2019-04-01 19:32:31 -0400
committerGitHub <noreply@github.com>2019-04-01 19:32:31 -0400
commit39fcfbd2eaed56cabf016d3e1bca32ab8b747777 (patch)
treeffc004b502d29860a0adace501000ca9ac4ba276 /src
parentf406d721bc1edaa6fa842f14e262b74ea3fa4d4e (diff)
downloadcoreclr-39fcfbd2eaed56cabf016d3e1bca32ab8b747777.tar.gz
coreclr-39fcfbd2eaed56cabf016d3e1bca32ab8b747777.tar.bz2
coreclr-39fcfbd2eaed56cabf016d3e1bca32ab8b747777.zip
Nullable: ManualResetEventSlim (#23630)
Diffstat (limited to 'src')
-rw-r--r--src/System.Private.CoreLib/shared/System/Threading/ManualResetEventSlim.cs19
1 files changed, 11 insertions, 8 deletions
diff --git a/src/System.Private.CoreLib/shared/System/Threading/ManualResetEventSlim.cs b/src/System.Private.CoreLib/shared/System/Threading/ManualResetEventSlim.cs
index 18eee25587..9eeba92a1d 100644
--- a/src/System.Private.CoreLib/shared/System/Threading/ManualResetEventSlim.cs
+++ b/src/System.Private.CoreLib/shared/System/Threading/ManualResetEventSlim.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+#nullable enable
using System.Diagnostics;
namespace System.Threading
@@ -35,10 +36,10 @@ namespace System.Threading
// These are the default spin counts we use on single-proc and MP machines.
private const int DEFAULT_SPIN_SP = 1;
- private volatile object m_lock;
+ private volatile object? m_lock;
// A lock used for waiting and pulsing. Lazily initialized via EnsureLockObjectCreated()
- private volatile ManualResetEvent m_eventObj; // A true Win32 event used for waiting.
+ private volatile ManualResetEvent? m_eventObj; // A true Win32 event used for waiting.
// -- State -- //
//For a packed word a uint would seem better, but Interlocked.* doesn't support them as uint isn't CLS-compliant.
@@ -89,6 +90,7 @@ namespace System.Threading
{
// Lazily initialize the event object if needed.
LazyInitializeEvent();
+ Debug.Assert(m_eventObj != null);
}
return m_eventObj;
@@ -318,7 +320,7 @@ namespace System.Threading
}
}
- ManualResetEvent eventObj = m_eventObj;
+ ManualResetEvent? eventObj = m_eventObj;
//Design-decision: do not set the event if we are in cancellation -> better to deadlock than to wake up waiters incorrectly
//It would be preferable to wake up the event and have it throw OCE. This requires MRE to implement cancellation logic
@@ -562,13 +564,14 @@ namespace System.Threading
cancellationToken.ThrowIfCancellationRequested();
}
- // Now enter the lock and wait.
+ // Now enter the lock and wait. Must be created before registering the cancellation callback,
+ // which will try to take this lock.
EnsureLockObjectCreated();
// We must register and unregister the token outside of the lock, to avoid deadlocks.
using (cancellationToken.UnsafeRegister(s_cancellationTokenCallback, this))
{
- lock (m_lock)
+ lock (m_lock!)
{
// Loop to cope with spurious wakeups from other waits being canceled
while (!IsSet)
@@ -656,7 +659,7 @@ namespace System.Threading
{
// We will dispose of the event object. We do this under a lock to protect
// against the race condition outlined in the Set method above.
- ManualResetEvent eventObj = m_eventObj;
+ ManualResetEvent? eventObj = m_eventObj;
if (eventObj != null)
{
lock (eventObj)
@@ -683,8 +686,8 @@ namespace System.Threading
private static Action<object> s_cancellationTokenCallback = new Action<object>(CancellationTokenCallback);
private static void CancellationTokenCallback(object obj)
{
- ManualResetEventSlim mre = obj as ManualResetEventSlim;
- Debug.Assert(mre != null, "Expected a ManualResetEventSlim");
+ Debug.Assert(obj is ManualResetEventSlim, "Expected a ManualResetEventSlim");
+ ManualResetEventSlim mre = (ManualResetEventSlim)obj;
Debug.Assert(mre.m_lock != null); //the lock should have been created before this callback is registered for use.
lock (mre.m_lock)
{