You're not obliged to take any action upon CTRL_C_EVENT, are you? Command() has a reserved argument (reserved, at least from my POV). Couldn't it be (made to be) called in such a way that it ignores the INT 3 exception ... precisely for use by background threads? [I really don't know how it works so if I'm way off base, kindly scold me.]
No. Here's the situation:
First, there's no such thing as a "background" and "foreground" thread in the console process; they all have the same priority and the same privileges. The only differentiation is that one thread happened to be the one that at startup was responsible for accepting (but not necessarily executing) command line input. (But it is *not* the UI thread, which is another thread responsible for handling messages from Windows.)
Second, what happens in your scenario when you get a ^C is this (vastly simplified; there are actually a number of additional threads):
- Thread A is handling messages from Windows.
- Thread B is taking command line input.
- Thread C is handling tests for monitoring commands.
- Threads D (and potentially E, F, G, etc.) are executing (reentrant) calls to Command() triggered from threads B and C (and occasionally A).
- Threads G - Y are created by various internal commands spawned by threads A - G to handle internal tasks.
- Thread Z is created (by Windows) to call the console control handler for the process when Windows detects a ^C. (Very little can be done in this thread because it has a limited stack size; pretty much just set a flag and exit.)
- And TCC doesn't know or care what thread happened to call Command() when (somewhere in a deep and frequently reentrant stack) a ^C was detected and a throw was done. (Throws are passed from one catch to another, frequently unwinding nested 50+ function calls).
You want TCC to automagically say "I got a ^C, and I in my ineffable mystery know that it is only relevant to thread B." Leaving aside how
it could possible know that (and dodging for the moment complaints from users that they could never interrupt monitor commands), the ^C has already
been processed in Windows (and may have broken out of a long-running Windows API.
So to do what you want, TCC would have to:
- Turn off all default ^C processing and disable the console control handler (which will also make it impossible to break out of a stuck API).
- Check the keyboard input constantly for a ^C. (This will mean that sometimes you might not get a response to a ^C for a while; and possibly not at all depending on what TCC is doing.)
- Modify (at least) 10K+ lines of code in TCC to only apply a ^C to thread B. Or sometimes threads started by thread B, depending on what B was doing. (Should only take a few months ...)
- Ignore any frantic attempts by the user to abort threads C- Y.
- Forbid anybody to ever attempt to press ^Break (an even worse situation than ^C handling).
- Might be a good idea to ban plugins from creating threads, as they could never be stopped.
- And finally, it'd be best to not allow anyone to press ^C when they're running Take Command, as that's another canister of annelids.
Given all that, if you still want it and can convince a few thousand other users to support this request in the feedback forum, I'll consider it for a future version.