Skip to content

Commit d0096b3

Browse files
authored
Improve COM server quiescing (#5652)
## Issue When the package needs to be updated, the COM server does not currently shut down in response to the signals that it receives. This is because it only shuts down when all COM object references have been released. We need to be more proactive in termination as the process will be terminated shortly after we are notified either way. ## Change This change refactors the existing shutdown signaling code out from `ExecutionContext.cpp` into its own, public location. It then adds another system for coordinating complex shutdown that is triggered by the signaler. Individual subsystems can register with the shutdown synchronizer with functions for: - Disable new work - Cancel current work - Wait for quiesce and on shutdown initialization, all subsystems are called for each stage in order. When the final subsystem returns from waiting, the existing "all COM objects have been released" event is signaled and the process will exit. Additionally, the shutdown signal handler waits for shutdown synchronization to complete in the window message function as after we return from that we are expected to be gone shortly after. While this will lead to some increased number of non-quiescing processes, we want to do the best that we can to cooperatively exit. > [!NOTE] > Any actions being taken by callers outside of those described below will **NOT** block the process from exiting. ### Package Management Registers with synchronization on `PackageManager` creation. All of its functions lead back to the `ContextOrchestrator` which has been enlightened to handle the shutdown (and to operate as a contained set of instances for test purposes). - **Disable new work** causes the orchestrator to refuse to queue items with an exception for new items and a cancellation for existing ones. - **Cancel current work** causes all queued items to be cancelled, with different handling based on current status. - **Wait for quiesce** waits on an event for each queue that is signaled when the queue is empty. ### Configuration Registers with synchronization on `ConfigurationStaticFunctionsShim` creation (the `IConfigurationStatics` for OOP use). All of its functions are routed through `IConfigurationStaticsInternals` to a new shutdown handler. It tracks all of the async token objects used in the "background" sections of the `ConfigurationProcessor` functions. This tracking is performed automatically by new types that manage that tracking with the lifetime. It also enables non-async invocations to be cancelled by providing a dummy promise into the existing system. - **Disable new work** causes an error whenever a new async token object is created. - **Cancel current work** causes all tracked async tokens to have their `Cancel` function invoked. - **Wait for quiesce** waits until all async tokens are destroyed.
1 parent a8f88bd commit d0096b3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+2107
-345
lines changed

src/AppInstallerCLI.sln

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "targets", "targets", "{A0B4
209209
EndProject
210210
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PureLib", "PureLib\PureLib.vcxitems", "{A33223D2-550B-4D99-A53D-488B1F68683E}"
211211
EndProject
212+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinGetTestCommon", "WinGetTestCommon\WinGetTestCommon.csproj", "{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}"
213+
EndProject
214+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
215+
EndProject
212216
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinGetMCPServer", "WinGetMCPServer\WinGetMCPServer.csproj", "{33745E4A-39E2-676F-7E23-50FB43848D25}"
213217
EndProject
214218
Global
@@ -968,6 +972,24 @@ Global
968972
{9406322E-6272-487E-902A-9953889719EA}.ReleaseStatic|x64.Build.0 = ReleaseStatic|Any CPU
969973
{9406322E-6272-487E-902A-9953889719EA}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Any CPU
970974
{9406322E-6272-487E-902A-9953889719EA}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Any CPU
975+
{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Debug|ARM64.ActiveCfg = Debug|arm64
976+
{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Debug|ARM64.Build.0 = Debug|arm64
977+
{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Debug|x64.ActiveCfg = Debug|x64
978+
{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Debug|x64.Build.0 = Debug|x64
979+
{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Debug|x86.ActiveCfg = Debug|x86
980+
{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Debug|x86.Build.0 = Debug|x86
981+
{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Fuzzing|ARM64.ActiveCfg = Release|arm64
982+
{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Fuzzing|x64.ActiveCfg = Release|x64
983+
{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Fuzzing|x86.ActiveCfg = Release|x86
984+
{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Release|ARM64.ActiveCfg = Release|arm64
985+
{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Release|ARM64.Build.0 = Release|arm64
986+
{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Release|x64.ActiveCfg = Release|x64
987+
{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Release|x64.Build.0 = Release|x64
988+
{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Release|x86.ActiveCfg = Release|x86
989+
{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Release|x86.Build.0 = Release|x86
990+
{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.ReleaseStatic|ARM64.ActiveCfg = Release|arm64
991+
{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.ReleaseStatic|x64.ActiveCfg = Release|x64
992+
{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.ReleaseStatic|x86.ActiveCfg = Release|x86
971993
{33745E4A-39E2-676F-7E23-50FB43848D25}.Debug|ARM64.ActiveCfg = Debug|arm64
972994
{33745E4A-39E2-676F-7E23-50FB43848D25}.Debug|ARM64.Build.0 = Debug|arm64
973995
{33745E4A-39E2-676F-7E23-50FB43848D25}.Debug|x64.ActiveCfg = Debug|x64
@@ -994,19 +1016,26 @@ Global
9941016
HideSolutionNode = FALSE
9951017
EndGlobalSection
9961018
GlobalSection(NestedProjects) = preSolution
1019+
{89B1AAB4-2BBC-4B65-9ED7-A01D5CF88230} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
1020+
{6CB84692-5994-407D-B9BD-9216AF77FE83} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
9971021
{6E36DDD7-1602-474E-B1D7-D0A7E1D5AD86} = {8D53D749-D51C-46F8-A162-9371AAA6C2E7}
1022+
{3C0269FA-E582-4CA7-9E33-3881A005CA0C} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
1023+
{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
1024+
{C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
9981025
{3B8466CF-4FDD-4329-9C80-91321C4AAC99} = {EA8CD934-0702-4911-A2C5-A40600E616DE}
9991026
{1622DA16-914F-4F57-A259-D5169003CC8C} = {6D7776A8-42FE-46DD-B0F8-712F35EA0C79}
10001027
{3BAF989F-7F65-465B-ACE8-BAFE42D1017E} = {EA8CD934-0702-4911-A2C5-A40600E616DE}
10011028
{7D05F64D-CE5A-42AA-A2C1-E91458F061CF} = {8D53D749-D51C-46F8-A162-9371AAA6C2E7}
10021029
{952B513F-8A00-4D74-9271-925AFB3C6252} = {8D53D749-D51C-46F8-A162-9371AAA6C2E7}
10031030
{2ACDE176-F13F-42FA-8159-C34FA3D37837} = {8D53D749-D51C-46F8-A162-9371AAA6C2E7}
10041031
{1A47951F-5C7A-4D6D-BB5F-D77484437940} = {8D53D749-D51C-46F8-A162-9371AAA6C2E7}
1032+
{68808357-902B-406C-8C19-E8E26A69DE8A} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
10051033
{409CD681-22A4-469D-88AE-CB5E4836E07A} = {8D53D749-D51C-46F8-A162-9371AAA6C2E7}
10061034
{B0BBBD92-943B-408F-B2B2-DBBAB4A22D23} = {8D53D749-D51C-46F8-A162-9371AAA6C2E7}
10071035
{463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C} = {7C218A3E-9BC8-48FF-B91B-BCACD828C0C9}
10081036
{31ED69A8-5310-45A9-953F-56C351D2C3E1} = {60618CAC-2995-4DF9-9914-45C6FC02C995}
10091037
{8E43F982-40D5-4DF1-9044-C08047B5F43B} = {8D53D749-D51C-46F8-A162-9371AAA6C2E7}
1038+
{EE43C990-7789-4A60-B077-BF0ED3D093A1} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
10101039
{1F56BECB-D65D-4BBA-8788-6671B251392A} = {7C218A3E-9BC8-48FF-B91B-BCACD828C0C9}
10111040
{167F634B-A3AD-494E-8E67-B888103E35FF} = {7C218A3E-9BC8-48FF-B91B-BCACD828C0C9}
10121041
{C54F80ED-B736-49B0-9BD3-662F57024D01} = {7C218A3E-9BC8-48FF-B91B-BCACD828C0C9}
@@ -1016,6 +1045,7 @@ Global
10161045
{76B26B2C-602A-4AD0-9736-4162D3FCA92A} = {1A5D7A7D-5CB2-47D5-B40D-4E61CAEDC798}
10171046
{A0B4F808-B190-41C4-97CB-C8EA1932F84F} = {8D53D749-D51C-46F8-A162-9371AAA6C2E7}
10181047
{A33223D2-550B-4D99-A53D-488B1F68683E} = {60618CAC-2995-4DF9-9914-45C6FC02C995}
1048+
{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
10191049
EndGlobalSection
10201050
GlobalSection(ExtensibilityGlobals) = postSolution
10211051
SolutionGuid = {B6FDB70C-A751-422C-ACD1-E35419495857}

src/AppInstallerCLICore/AppInstallerCLICore.vcxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@
347347
<ClInclude Include="ContextOrchestrator.h" />
348348
<ClInclude Include="COMContext.h" />
349349
<ClInclude Include="Public\ConfigurationSetProcessorFactoryRemoting.h" />
350+
<ClInclude Include="Public\ShutdownMonitoring.h" />
350351
<ClInclude Include="Sixel.h" />
351352
<ClInclude Include="Workflows\ConfigurationFlow.h" />
352353
<ClInclude Include="Workflows\DependenciesFlow.h" />
@@ -421,6 +422,7 @@
421422
<ClCompile Include="ConfigurationWingetDscModuleUnitValidation.cpp" />
422423
<ClCompile Include="ConfigureExportCommand.cpp" />
423424
<ClCompile Include="ContextOrchestrator.cpp" />
425+
<ClCompile Include="ShutdownMonitoring.cpp" />
424426
<ClCompile Include="Sixel.cpp" />
425427
<ClCompile Include="Workflows\ConfigurationFlow.cpp" />
426428
<ClCompile Include="Workflows\DependenciesFlow.cpp" />

src/AppInstallerCLICore/AppInstallerCLICore.vcxproj.filters

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,9 @@
293293
<ClInclude Include="Commands\DscAdminSettingsResource.h">
294294
<Filter>Commands\Configuration</Filter>
295295
</ClInclude>
296+
<ClInclude Include="Public\ShutdownMonitoring.h">
297+
<Filter>Public</Filter>
298+
</ClInclude>
296299
<ClInclude Include="Commands\McpCommand.h">
297300
<Filter>Commands</Filter>
298301
</ClInclude>
@@ -556,6 +559,9 @@
556559
<ClCompile Include="Commands\DscAdminSettingsResource.cpp">
557560
<Filter>Commands\Configuration</Filter>
558561
</ClCompile>
562+
<ClCompile Include="ShutdownMonitoring.cpp">
563+
<Filter>Source Files</Filter>
564+
</ClCompile>
559565
<ClCompile Include="Commands\McpCommand.cpp">
560566
<Filter>Commands</Filter>
561567
</ClCompile>

src/AppInstallerCLICore/Commands/TestCommand.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "AppInstallerRuntime.h"
99
#include "TableOutput.h"
1010
#include "Public/ConfigurationSetProcessorFactoryRemoting.h"
11+
#include "Public/ShutdownMonitoring.h"
1112
#include "Workflows/ConfigurationFlow.h"
1213
#include "Workflows/MSStoreInstallerHandler.h"
1314
#include <winrt/Microsoft.Management.Configuration.h>
@@ -19,16 +20,16 @@ namespace AppInstaller::CLI
1920
{
2021
namespace
2122
{
22-
void LogAndReport(Execution::Context& context, const std::string& message)
23+
void LogAndReport(Execution::Context& context, std::string_view message)
2324
{
24-
AICLI_LOG(CLI, Info, << message);
2525
context.Reporter.Info() << message << std::endl;
26+
AICLI_LOG(CLI, Info, << message);
2627
}
2728

2829
HRESULT WaitForShutdown(Execution::Context& context)
2930
{
3031
LogAndReport(context, "Waiting for app shutdown event");
31-
if (!Execution::WaitForAppShutdownEvent())
32+
if (!ShutdownMonitoring::TerminationSignalHandler::Instance().WaitForAppShutdownEvent())
3233
{
3334
LogAndReport(context, "Failed getting app shutdown event");
3435
return APPINSTALLER_CLI_ERROR_INTERNAL_ERROR;
@@ -40,7 +41,7 @@ namespace AppInstaller::CLI
4041

4142
HRESULT AppShutdownWindowMessage(Execution::Context& context)
4243
{
43-
auto windowHandle = Execution::GetWindowHandle();
44+
auto windowHandle = ShutdownMonitoring::TerminationSignalHandler::Instance().GetWindowHandle();
4445

4546
if (windowHandle == NULL)
4647
{

0 commit comments

Comments
 (0)