From e5983dd2afa1576518ba32c7287296eab0b6af21 Mon Sep 17 00:00:00 2001 From: Jeremy Ong <87345238+jeremyong-az@users.noreply.github.com> Date: Tue, 20 Jul 2021 13:38:12 -0600 Subject: [PATCH] Terminate AssetProcessor when spawned by the parent project process (#2272) * Terminate AssetProcessor when spawned by the parent project process Signed-off-by: Jeremy Ong * Maintain default behavior (leaving AP running on quit) To enable the autotermination feature, the ap_tether_lifetime CVAR is provided. Signed-off-by: Jeremy Ong --- .../AssetSystemComponentHelper_Windows.cpp | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/Code/Framework/AzFramework/Platform/Windows/AzFramework/Asset/AssetSystemComponentHelper_Windows.cpp b/Code/Framework/AzFramework/Platform/Windows/AzFramework/Asset/AssetSystemComponentHelper_Windows.cpp index e1d400ecfc..4b685b25a3 100644 --- a/Code/Framework/AzFramework/Platform/Windows/AzFramework/Asset/AssetSystemComponentHelper_Windows.cpp +++ b/Code/Framework/AzFramework/Platform/Windows/AzFramework/Asset/AssetSystemComponentHelper_Windows.cpp @@ -6,6 +6,7 @@ * */ +#include #include #include #include @@ -13,6 +14,9 @@ #include +AZ_CVAR(bool, ap_tether_lifetime, false, nullptr, AZ::ConsoleFunctorFlags::Null, + "If enabled, a parent process that launches the AP will terminate the AP on exit"); + namespace AzFramework::AssetSystem::Platform { void AllowAssetProcessorToForeground() @@ -100,6 +104,21 @@ namespace AzFramework::AssetSystem::Platform fullLaunchCommand += '"'; } + // Create or retrieve the job handle associated with the asset processor + HANDLE apJob = nullptr; + + if (ap_tether_lifetime) + { + apJob = ::CreateJobObjectA(nullptr, "AssetProcessorJob"); + if (apJob && GetLastError() != ERROR_ALREADY_EXISTS) + { + // We're creating the job for the first time. Configure it to close child processes when this process exits. + JOBOBJECT_EXTENDED_LIMIT_INFORMATION info = {}; + info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; + ::SetInformationJobObject(apJob, JobObjectExtendedLimitInformation, &info, sizeof(info)); + } + } + STARTUPINFO si; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); @@ -107,6 +126,14 @@ namespace AzFramework::AssetSystem::Platform si.wShowWindow = SW_MINIMIZE; PROCESS_INFORMATION pi; - return ::CreateProcessA(nullptr, fullLaunchCommand.data(), nullptr, nullptr, FALSE, 0, nullptr, AZ::IO::FixedMaxPathString{ executableDirectory }.c_str(), &si, &pi) != 0; + bool createResult = ::CreateProcessA(nullptr, fullLaunchCommand.data(), nullptr, nullptr, FALSE, 0, nullptr, AZ::IO::FixedMaxPathString{ executableDirectory }.c_str(), &si, &pi) != 0; + + if (ap_tether_lifetime && apJob && createResult) + { + // Save process and thread handle to terminate AP when the parent process exits + ::AssignProcessToJobObject(apJob, pi.hProcess); + } + + return createResult; } }