From 0b4db68bcfa83e07e287e350bee6a4f941d4e197 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 20 Mar 2026 00:22:04 +0000 Subject: [PATCH 1/4] Initial plan From 28a2e93995c444712a2be8cfca5cd3235122a565 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 20 Mar 2026 00:31:21 +0000 Subject: [PATCH 2/4] Fix ProcessThreadTests.TestStartTimeProperty race condition with retry loop Co-authored-by: danmoseley <6385855+danmoseley@users.noreply.github.com> --- .../tests/ProcessThreadTests.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs index 6c97c4424f6ba1..03f1b8cf8585ef 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs @@ -148,13 +148,18 @@ public async Task TestStartTimeProperty() // that there's at least one thread greater than the current time we previously grabbed. await Task.Factory.StartNew(() => { - p.Refresh(); - int newThreadId = GetCurrentThreadId(); - ProcessThread[] processThreads = p.Threads.Cast().ToArray(); - ProcessThread newThread = Assert.Single(processThreads, thread => thread.Id == newThreadId); + // Retry to handle the race where the new thread's /proc entry isn't visible yet. + ProcessThread newThread = null; + for (int i = 0; i < 10 && newThread is null; i++) + { + if (i > 0) Thread.Sleep(100); + p.Refresh(); + newThread = p.Threads.Cast().FirstOrDefault(t => t.Id == newThreadId); + } + Assert.NotNull(newThread); Assert.InRange(newThread.StartTime.ToUniversalTime(), curTime - allowedWindow, DateTime.Now.ToUniversalTime() + allowedWindow); }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default); } From b107dbffa5f6b00fce7a69cb128b988b05a6bf5d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 20 Mar 2026 00:33:21 +0000 Subject: [PATCH 3/4] Improve Assert message for thread-not-found failure case Co-authored-by: danmoseley <6385855+danmoseley@users.noreply.github.com> --- .../System.Diagnostics.Process/tests/ProcessThreadTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs index 03f1b8cf8585ef..5939d25d2a8d07 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs @@ -159,7 +159,7 @@ await Task.Factory.StartNew(() => newThread = p.Threads.Cast().FirstOrDefault(t => t.Id == newThreadId); } - Assert.NotNull(newThread); + Assert.True(newThread is not null, $"Thread with id {newThreadId} was not found after retrying."); Assert.InRange(newThread.StartTime.ToUniversalTime(), curTime - allowedWindow, DateTime.Now.ToUniversalTime() + allowedWindow); }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default); } From 8637f70a9da030abfac6d34345adae92b2783440 Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Thu, 19 Mar 2026 22:30:43 -0600 Subject: [PATCH 4/4] Address review feedback: platform-agnostic comment, use DateTime.UtcNow - Reword /proc-specific comment to be platform-agnostic - Use DateTime.UtcNow instead of DateTime.Now.ToUniversalTime() Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../System.Diagnostics.Process/tests/ProcessThreadTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs index 5939d25d2a8d07..0f9965fb8b9b24 100644 --- a/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs +++ b/src/libraries/System.Diagnostics.Process/tests/ProcessThreadTests.cs @@ -150,7 +150,7 @@ await Task.Factory.StartNew(() => { int newThreadId = GetCurrentThreadId(); - // Retry to handle the race where the new thread's /proc entry isn't visible yet. + // Retry to handle the race where the newly started thread is not yet visible via Process.Threads. ProcessThread newThread = null; for (int i = 0; i < 10 && newThread is null; i++) { @@ -160,7 +160,7 @@ await Task.Factory.StartNew(() => } Assert.True(newThread is not null, $"Thread with id {newThreadId} was not found after retrying."); - Assert.InRange(newThread.StartTime.ToUniversalTime(), curTime - allowedWindow, DateTime.Now.ToUniversalTime() + allowedWindow); + Assert.InRange(newThread.StartTime.ToUniversalTime(), curTime - allowedWindow, DateTime.UtcNow + allowedWindow); }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default); } }