From ad0c07147ec3031f53e6634504e650e2aa200ee6 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Thu, 17 Aug 2023 17:35:25 +0200 Subject: [PATCH] fix thread renaming --- Source/Core/Runtime/CoyoteRuntime.cs | 17 +++++------------ .../Tests.BugFinding/Threads/ThreadRunTests.cs | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/Source/Core/Runtime/CoyoteRuntime.cs b/Source/Core/Runtime/CoyoteRuntime.cs index b07a5fc4c..74aa5e968 100644 --- a/Source/Core/Runtime/CoyoteRuntime.cs +++ b/Source/Core/Runtime/CoyoteRuntime.cs @@ -133,7 +133,7 @@ internal sealed class CoyoteRuntime : ICoyoteRuntime, IDisposable /// /// Map from unique controlled thread names to their corresponding operations. /// - private readonly ConcurrentDictionary ControlledThreads; + private readonly ConcurrentDictionary ControlledThreads; /// /// Map from controlled tasks to their corresponding operations. @@ -321,7 +321,7 @@ private CoyoteRuntime(Configuration configuration, OperationScheduler scheduler, this.ThreadPool = new ConcurrentDictionary(); this.OperationMap = new Dictionary(); this.PendingStartOperationMap = new Dictionary(); - this.ControlledThreads = new ConcurrentDictionary(); + this.ControlledThreads = new ConcurrentDictionary(); this.ControlledTasks = new ConcurrentDictionary(); this.UncontrolledTasks = new ConcurrentDictionary(); this.UncontrolledInvocations = new HashSet(); @@ -584,7 +584,7 @@ internal Thread CreateControlledThread(ControlledOperation op, Delegate logic, A // TODO: optimize by reusing threads instead of creating a new thread each time? this.ThreadPool.AddOrUpdate(op.Id, thread, (id, oldThread) => thread); - this.ControlledThreads.AddOrUpdate(thread.Name, op, (threadName, oldOp) => op); + this.ControlledThreads.AddOrUpdate(thread.ManagedThreadId, op, (threadName, oldOp) => op); return thread; } } @@ -1529,13 +1529,7 @@ internal ControlledOperation GetOperationExecutingOnThread(Thread thread) { using (SynchronizedSection.Enter(this.RuntimeLock)) { - ControlledOperation op = null; - string name = thread?.Name; - if (!string.IsNullOrEmpty(name)) - { - this.ControlledThreads.TryGetValue(name, out op); - } - + this.ControlledThreads.TryGetValue(thread.ManagedThreadId, out var op); return op; } } @@ -1833,8 +1827,7 @@ private void StartMonitoringDeadlocks() => Task.Factory.StartNew(this.CheckIfExe /// private bool IsThreadControlled(Thread thread) { - string name = thread?.Name; - return name != null && this.ControlledThreads.ContainsKey(name); + return this.ControlledThreads.ContainsKey(thread.ManagedThreadId); } /// diff --git a/Tests/Tests.BugFinding/Threads/ThreadRunTests.cs b/Tests/Tests.BugFinding/Threads/ThreadRunTests.cs index f8e1fd2a7..527391a0b 100644 --- a/Tests/Tests.BugFinding/Threads/ThreadRunTests.cs +++ b/Tests/Tests.BugFinding/Threads/ThreadRunTests.cs @@ -98,5 +98,23 @@ public void TestThreadStartAndJoinStress() }, configuration: this.GetConfiguration().WithTestingIterations(10)); } + + [Fact(Timeout = 5000)] + public void TestThreadRenamed() + { + this.Test(() => + { + bool isDone = false; + Thread t = new Thread(() => { isDone = true; }); + t.Name = "CustomName"; + t.Start(); + t.Join(); + + Specification.Assert(isDone, "The expected condition was not satisfied."); + Specification.Assert(t.ThreadState is ThreadState.Stopped, "State of thread '{0}' is {1} instead of Stopped.", + t.ManagedThreadId, t.ThreadState); + }, + configuration: this.GetConfiguration().WithTestingIterations(10)); + } } }