Skip to content

Commit 617faba

Browse files
committed
OrcLib: CommandAgent: synchronize with child process creation
Use CreateChildProcess, ResumeChildProcess and new notifications CommandNotification::Created and CommandNotification::Started to ensure WolfTask will handle correctly process creation even if quickly terminated.
1 parent e21f681 commit 617faba

File tree

5 files changed

+56
-11
lines changed

5 files changed

+56
-11
lines changed

src/OrcCommand/Command/WolfLauncher/WolfTask.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ HRESULT WolfTask::ApplyNotification(
4949
m_executableSha1 = notification->GetExecutableSha1();
5050
m_isSelfOrcExecutable = notification->IsSelfOrcExecutable();
5151
m_orcTool = notification->GetOrcTool();
52+
53+
actions.push_back(CommandMessage::MakeStartMessage(
54+
notification->GetKeyword(), static_cast<DWORD>(static_cast<DWORD64>(notification->GetProcessID()))));
5255
}
5356
break;
5457
case CommandNotification::Started:

src/OrcLib/CommandAgent.cpp

+42-11
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,42 @@ std::shared_ptr<CommandExecute> CommandAgent::PrepareCommandExecute(const std::s
714714
return retval;
715715
}
716716

717+
void CommandAgent::StartCommandExecute(const std::shared_ptr<CommandMessage>& message)
718+
{
719+
Concurrency::critical_section::scoped_lock s(m_cs);
720+
721+
std::shared_ptr<CommandExecute> command = nullptr;
722+
for (const auto& runningCommand : m_RunningCommands)
723+
{
724+
if (runningCommand == nullptr)
725+
{
726+
continue;
727+
}
728+
729+
if (runningCommand->ProcessID() == message->ProcessID())
730+
{
731+
command = runningCommand;
732+
}
733+
}
734+
735+
if (command == nullptr)
736+
{
737+
Log::Critical(L"Command '{}' resume rejected, command not found", message->Keyword());
738+
return;
739+
}
740+
741+
HRESULT hr = command->ResumeChildProcess();
742+
if (FAILED(hr))
743+
{
744+
Log::Critical(L"Command '{}' resume failed [{}]", message->Keyword(), SystemError(hr));
745+
TerminateProcess(command->ProcessHandle(), -1);
746+
return;
747+
}
748+
749+
Concurrency::send<CommandNotification::Notification>(
750+
m_target, CommandNotification::NotifyStarted(command->GetKeyword(), command->ProcessID()));
751+
}
752+
717753
typedef struct _CompletionBlock
718754
{
719755
CommandAgent* pAgent;
@@ -804,6 +840,7 @@ HRESULT CommandAgent::ExecuteNextCommand()
804840
timer->start();
805841
}
806842

843+
// Register a callback that will handle process termination (release semaphore, notify, etc...)
807844
HANDLE hWaitObject = INVALID_HANDLE_VALUE;
808845
CompletionBlock* pBlockPtr = (CompletionBlock*)Concurrency::Alloc(sizeof(CompletionBlock));
809846
CompletionBlock* pBlock = new (pBlockPtr) CompletionBlock;
@@ -834,17 +871,6 @@ HRESULT CommandAgent::ExecuteNextCommand()
834871
notification->SetProcessCommandLine(command->m_commandLine);
835872

836873
SendResult(notification);
837-
838-
hr = command->ResumeChildProcess();
839-
if (FAILED(hr))
840-
{
841-
m_MaximumRunningSemaphore.Release();
842-
command->CompleteExecution();
843-
return S_OK;
844-
}
845-
846-
Concurrency::send<CommandNotification::Notification>(
847-
m_target, CommandNotification::NotifyStarted(command->GetKeyword(), command->ProcessID()));
848874
}
849875

850876
return S_OK;
@@ -1230,6 +1256,11 @@ void CommandAgent::run()
12301256
}
12311257
}
12321258
break;
1259+
case CommandMessage::Start: {
1260+
Log::Debug(L"CommandAgent: Start command '{}'", request->Keyword());
1261+
StartCommandExecute(request);
1262+
}
1263+
break;
12331264
case CommandMessage::RefreshRunningList: {
12341265
Concurrency::critical_section::scoped_lock s(m_cs);
12351266
auto new_end = std::remove_if(

src/OrcLib/CommandAgent.h

+1
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ class CommandAgent : public Concurrency::agent
156156
std::shared_ptr<ProcessRedirect>
157157
PrepareRedirection(const std::shared_ptr<CommandExecute>& cmd, const CommandParameter& output);
158158
std::shared_ptr<CommandExecute> PrepareCommandExecute(const std::shared_ptr<CommandMessage>& message);
159+
void StartCommandExecute(const std::shared_ptr<CommandMessage>& message);
159160

160161
HRESULT ExecuteNextCommand();
161162

src/OrcLib/CommandMessage.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@ CommandMessage::Message CommandMessage::MakeCancelAnyPendingAndStopMessage()
4040
return retval;
4141
}
4242

43+
CommandMessage::Message CommandMessage::MakeStartMessage(const std::wstring& keyword, DWORD dwProcessID)
44+
{
45+
auto retval = std::make_shared<::CommandMessageT>(CommandMessage::Start);
46+
retval->m_dwPid = dwProcessID;
47+
retval->m_Keyword = keyword;
48+
return retval;
49+
}
50+
4351
CommandMessage::Message CommandMessage::MakeTerminateMessage(DWORD dwProcessID)
4452
{
4553
auto retval = std::make_shared<::CommandMessageT>(CommandMessage::Terminate);

src/OrcLib/CommandMessage.h

+2
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ class CommandMessage
7575
typedef enum _Request
7676
{
7777
Execute = 0,
78+
Start,
7879
Abort,
7980
Terminate,
8081
QueryRunningList,
@@ -112,6 +113,7 @@ class CommandMessage
112113

113114
static Message MakeCancelMessage();
114115
static Message MakeAbortMessage(const std::wstring& keyword, DWORD processId, HANDLE hProcess);
116+
static Message MakeStartMessage(const std::wstring& keyword, DWORD dwProcessID);
115117
static Message MakeTerminateMessage(DWORD dwProcessID);
116118
static Message MakeCancelAnyPendingAndStopMessage();
117119
static Message MakeTerminateAllMessage();

0 commit comments

Comments
 (0)