fix: exit lifecycle probe from verified idle

This commit is contained in:
codex
2026-08-03 17:02:18 +03:00
parent 79067b72de
commit d8e61b7a5e
@@ -180,7 +180,10 @@ internal sealed class FirstLimitedApplyAutomationCoordinator
{
transitions.Add("LifecycleProbeCompleted");
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);
@@ -285,18 +288,28 @@ internal sealed class FirstLimitedApplyAutomationCoordinator
// AutoCAD's direct Application.Quit can leave a startup-script host alive.
// Dispatching the native QUIT command from the next quiescent Idle cycle
// preserves normal command shutdown semantics.
private void RequestControlledExit()
private void RequestControlledExit(bool idleSafe = false)
{
if (exitQueued) return;
exitQueued = true;
Transition(CoordinatorState.ExitQueued, "ExitQueued");
if (idleSafe)
{
DispatchNativeQuit();
return;
}
AcadApplication.Idle += OnExitIdle;
exitHandlerSubscribed = true;
}
private void OnExitIdle(object? sender, EventArgs args)
{
RunCallback("ControlledExitIdle", () =>
RunCallback("ControlledExitIdle", DispatchNativeQuit);
}
private void DispatchNativeQuit()
{
try
{
if (exitHandlerSubscribed) AcadApplication.Idle -= OnExitIdle;
exitHandlerSubscribed = false;
@@ -306,7 +319,13 @@ internal sealed class FirstLimitedApplyAutomationCoordinator
if (active is null) { AcadApplication.Quit(); return; }
transitions.Add("NativeQuitDispatched");
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;