From 0a17193aa86a933af77babe620261046e39610db Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Fri, 6 Dec 2019 12:02:53 -0500 Subject: [PATCH] Add test for CancellationTokenRegistration.Unregister race condition (#313) --- .../tests/CancellationTokenTests.cs | 44 ++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/libraries/System.Threading.Tasks/tests/CancellationTokenTests.cs b/src/libraries/System.Threading.Tasks/tests/CancellationTokenTests.cs index 2a95368..0f954d4 100644 --- a/src/libraries/System.Threading.Tasks/tests/CancellationTokenTests.cs +++ b/src/libraries/System.Threading.Tasks/tests/CancellationTokenTests.cs @@ -1418,6 +1418,50 @@ namespace System.Threading.Tasks.Tests } } + [OuterLoop("Runs for several seconds")] + [Fact] + public static void Unregister_ConcurrentUse_ThreadSafe() + { + CancellationTokenRegistration reg = default; + var cts = new CancellationTokenSource(); + + DateTime end = DateTime.UtcNow.AddSeconds(4); + bool run = true; + Task.WaitAll( + Task.Run(() => + { + try + { + while (Volatile.Read(ref run) && DateTime.UtcNow < end) + { + reg = cts.Token.Register(() => { }); + reg.Unregister(); + reg = default; + } + } + finally + { + Volatile.Write(ref run, false); + } + }), + Task.Run(() => + { + try + { + while (Volatile.Read(ref run) && DateTime.UtcNow < end) + { + reg.Unregister(); + } + } + finally + { + Volatile.Write(ref run, false); + } + })); + + // Validating that no exception is thrown. + } + [Fact] public static void Register_ExecutionContextFlowsIfExpected() { -- 2.7.4