Repository: microsoft/terminal
File: src/host/output.cpp (C++)

Code before:
    // Set window size.
    screenInfo.PostUpdateWindowSize();

    gci.ConsoleIme.RefreshAreaAttributes();

    // Write data to screen.
    WriteToScreen(screenInfo, screenInfo.GetViewport());
}

// TODO: MSFT 9450717 This should join the ProcessList class when CtrlEvents become moved into the server. https://osgvsowi/9450717
void CloseConsoleProcessState()
{
    auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
    // If there are no connected processes, sending control events is pointless as there's no one do send them to. In
    // this case we'll just exit conhost.

    // N.B. We can get into this state when a process has a reference to the console but hasn't connected. For example,
    //      when it's created suspended and never resumed.
    if (gci.ProcessHandleList.IsEmpty())
    {
        ServiceLocator::RundownAndExit(STATUS_SUCCESS);
    }

    HandleCtrlEvent(CTRL_CLOSE_EVENT);

    gci.ShutdownMidiAudio();

    // Jiggle the handle: (see MSFT:19419231)
    // When we call this function, we'll only actually close the console once
    //      we're totally unlocked. If our caller has the console locked, great,
    //      we'll dispatch the ctrl event once they unlock. However, if they're
    //      not running under lock (eg PtySignalInputThread::_GetData), then the
    //      ctrl event will never actually get dispatched.
    // So, lock and unlock here, to make sure the ctrl event gets handled.
    LockConsole();
    UnlockConsole();
}


Review comment (suggestion):
FYI, reading another PR, I just realized that this change isn't quite correct. This should still call `midiAudio.BeginSkip()`, just like `ControlCore` does on shutdown.

Code after:
    // Set window size.
    screenInfo.PostUpdateWindowSize();

    gci.ConsoleIme.RefreshAreaAttributes();

    // Write data to screen.
    WriteToScreen(screenInfo, screenInfo.GetViewport());
}

// TODO: MSFT 9450717 This should join the ProcessList class when CtrlEvents become moved into the server. https://osgvsowi/9450717
void CloseConsoleProcessState()
{
    auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
    // If there are no connected processes, sending control events is pointless as there's no one do send them to. In
    // this case we'll just exit conhost.

    // N.B. We can get into this state when a process has a reference to the console but hasn't connected. For example,
    //      when it's created suspended and never resumed.
    if (gci.ProcessHandleList.IsEmpty())
    {
        ServiceLocator::RundownAndExit(STATUS_SUCCESS);
    }

    HandleCtrlEvent(CTRL_CLOSE_EVENT);

    // Jiggle the handle: (see MSFT:19419231)
    // When we call this function, we'll only actually close the console once
    //      we're totally unlocked. If our caller has the console locked, great,
    //      we'll dispatch the ctrl event once they unlock. However, if they're
    //      not running under lock (eg PtySignalInputThread::_GetData), then the
    //      ctrl event will never actually get dispatched.
    // So, lock and unlock here, to make sure the ctrl event gets handled.
    LockConsole();
    UnlockConsole();
}