From 009ebf619b315be447ac1b782e2f0af670f7f0f6 Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Tue, 6 Sep 2016 16:51:17 -0700 Subject: [PATCH] fix async_wrapper start suspended race (#4718) Main thread in started-suspended process may not be immediately resumable on slow targets- poll for proper state for awhile before attempting resume --- lib/ansible/modules/windows/async_wrapper.ps1 | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/ansible/modules/windows/async_wrapper.ps1 b/lib/ansible/modules/windows/async_wrapper.ps1 index 03ba5d72e9..a4f9009483 100644 --- a/lib/ansible/modules/windows/async_wrapper.ps1 +++ b/lib/ansible/modules/windows/async_wrapper.ps1 @@ -48,6 +48,7 @@ Function Start-Watchdog { using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; + using System.Threading; namespace Ansible.Async { @@ -89,7 +90,17 @@ Function Start-Watchdog { { var proc = Process.GetProcessById(pid); - foreach(var thread in proc.Threads.OfType().Where(t => t.WaitReason == ThreadWaitReason.Suspended)) + // wait for at least one suspended thread in the process (this handles possible slow startup race where primary thread of created-suspended process has not yet become runnable) + var retryCount = 0; + while(!proc.Threads.OfType().Any(t=>t.ThreadState == System.Diagnostics.ThreadState.Wait && t.WaitReason == ThreadWaitReason.Suspended)) + { + proc.Refresh(); + Thread.Sleep(50); + if (retryCount > 100) + throw new InvalidOperationException(String.Format("No threads were suspended in target PID {0} after 5s", pid)); + } + + foreach(var thread in proc.Threads.OfType().Where(t => t.ThreadState == System.Diagnostics.ThreadState.Wait && t.WaitReason == ThreadWaitReason.Suspended)) ResumeThreadById(thread.Id); } }