-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Improve COM server quiescing #5652
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…or component attach
This comment was marked as outdated.
This comment was marked as outdated.
src/AppInstallerCLI.sln
Outdated
@@ -968,6 +972,30 @@ Global | |||
{9406322E-6272-487E-902A-9953889719EA}.ReleaseStatic|x64.Build.0 = ReleaseStatic|Any CPU | |||
{9406322E-6272-487E-902A-9953889719EA}.ReleaseStatic|x86.ActiveCfg = ReleaseStatic|Any CPU | |||
{9406322E-6272-487E-902A-9953889719EA}.ReleaseStatic|x86.Build.0 = ReleaseStatic|Any CPU | |||
{7139ED6E-8FBC-0B61-3E3A-AA2A23CC4D6A}.Debug|ARM64.ActiveCfg = Debug|x64 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: through all the new entries, I think only debug/release x64/x86 need Build.0 entries, all other combinations should be set to "not build"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree on the configurations, disagree on removing from the ARM64 build (but updated things to make that work).
|
||
// Waits for running items to complete; waits up to full time out in *each* queue. | ||
// Returns true to indicate all queues are empty before the timeout. | ||
// Intended for test use. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: should we wrap around AICLI_DISABLE_TESTES if it's just for test purpose?
|
||
// Waits until the empty queue event is signaled. | ||
// Returns true to indicate the queue is empty before the timeout. | ||
// Intended for tests. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: should we wrap around AICLI_DISABLE_TESTES if it's just for test purpose?
/// <summary> | ||
/// Gets the process for the server. | ||
/// </summary> | ||
public required Process Process { get; init; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't know required
was a thing. That's cool
bool ContextOrchestrator::WaitForRunningItems(DWORD timeoutMilliseconds) | ||
{ | ||
std::lock_guard<std::mutex> lock{ m_queueLock }; | ||
for (const auto& queue : m_commandQueues) | ||
{ | ||
if (!queue.second->WaitForEmptyQueue(timeoutMilliseconds)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I would expect this function to wait for all items at most timeoutMilliseconds
, but it waits that long for each of them. This may be moot depending on how many command queues we have or how big the timeout is, though.
std::string OrchestratorQueue::GetStatusString() | ||
{ | ||
std::ostringstream stream; | ||
stream << m_commandName << '[' << m_allowedThreads << "]\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: endl
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:
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 theContextOrchestrator
which has been enlightened to handle the shutdown (and to operate as a contained set of instances for test purposes).Configuration
Registers with synchronization on
ConfigurationStaticFunctionsShim
creation (theIConfigurationStatics
for OOP use). All of its functions are routed throughIConfigurationStaticsInternals
to a new shutdown handler. It tracks all of the async token objects used in the "background" sections of theConfigurationProcessor
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.Cancel
function invoked.Validation
New tests are added for the
ContextOrchestrator
, the package management shutdown handling, and the configuration shutdown handling.Microsoft Reviewers: Open in CodeFlow