fix: exit lifecycle probe from verified idle
This commit is contained in:
@@ -180,7 +180,10 @@ internal sealed class FirstLimitedApplyAutomationCoordinator
|
|||||||
{
|
{
|
||||||
transitions.Add("LifecycleProbeCompleted");
|
transitions.Add("LifecycleProbeCompleted");
|
||||||
WriteEvidence(true, null);
|
WriteEvidence(true, null);
|
||||||
RequestControlledExit();
|
// LifecycleProbe is already running from the first verified Idle callback.
|
||||||
|
// Do not wait for a second Idle: a startup-script host is permitted not to
|
||||||
|
// raise one, which otherwise leaves acad.exe responsive but stranded.
|
||||||
|
RequestControlledExit(idleSafe: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnIdle(object? sender, EventArgs e) => RunCallback("Idle", BeginContextVerification);
|
private void OnIdle(object? sender, EventArgs e) => RunCallback("Idle", BeginContextVerification);
|
||||||
@@ -285,18 +288,28 @@ internal sealed class FirstLimitedApplyAutomationCoordinator
|
|||||||
// AutoCAD's direct Application.Quit can leave a startup-script host alive.
|
// AutoCAD's direct Application.Quit can leave a startup-script host alive.
|
||||||
// Dispatching the native QUIT command from the next quiescent Idle cycle
|
// Dispatching the native QUIT command from the next quiescent Idle cycle
|
||||||
// preserves normal command shutdown semantics.
|
// preserves normal command shutdown semantics.
|
||||||
private void RequestControlledExit()
|
private void RequestControlledExit(bool idleSafe = false)
|
||||||
{
|
{
|
||||||
if (exitQueued) return;
|
if (exitQueued) return;
|
||||||
exitQueued = true;
|
exitQueued = true;
|
||||||
Transition(CoordinatorState.ExitQueued, "ExitQueued");
|
Transition(CoordinatorState.ExitQueued, "ExitQueued");
|
||||||
|
if (idleSafe)
|
||||||
|
{
|
||||||
|
DispatchNativeQuit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
AcadApplication.Idle += OnExitIdle;
|
AcadApplication.Idle += OnExitIdle;
|
||||||
exitHandlerSubscribed = true;
|
exitHandlerSubscribed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnExitIdle(object? sender, EventArgs args)
|
private void OnExitIdle(object? sender, EventArgs args)
|
||||||
{
|
{
|
||||||
RunCallback("ControlledExitIdle", () =>
|
RunCallback("ControlledExitIdle", DispatchNativeQuit);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DispatchNativeQuit()
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
if (exitHandlerSubscribed) AcadApplication.Idle -= OnExitIdle;
|
if (exitHandlerSubscribed) AcadApplication.Idle -= OnExitIdle;
|
||||||
exitHandlerSubscribed = false;
|
exitHandlerSubscribed = false;
|
||||||
@@ -306,7 +319,13 @@ internal sealed class FirstLimitedApplyAutomationCoordinator
|
|||||||
if (active is null) { AcadApplication.Quit(); return; }
|
if (active is null) { AcadApplication.Quit(); return; }
|
||||||
transitions.Add("NativeQuitDispatched");
|
transitions.Add("NativeQuitDispatched");
|
||||||
active.SendStringToExecute("_.QUIT _N ", true, false, false);
|
active.SendStringToExecute("_.QUIT _N ", true, false, false);
|
||||||
});
|
}
|
||||||
|
catch (System.Exception exception)
|
||||||
|
{
|
||||||
|
// This is terminal cleanup: contain the exception and leave process
|
||||||
|
// cleanup to Launcher rather than re-entering document APIs.
|
||||||
|
FailFromCallback("ControlledExitIdle", exception, "AUTOMATION_CONTROLLED_EXIT_FAILED");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsTerminal => state is CoordinatorState.Completed or CoordinatorState.Failed or CoordinatorState.ExitQueued;
|
private bool IsTerminal => state is CoordinatorState.Completed or CoordinatorState.Failed or CoordinatorState.ExitQueued;
|
||||||
|
|||||||
Reference in New Issue
Block a user