Ensure the C++ UIA rate limited event handler flusher thread is definitely terminated when NVDA shutts down (#16198)
Fixes #16072
Summary of the issue:
If any background threads remain after NVDA exits, the NVDA process will stay alive until those background threads complete. For Python threads, setting daemon to true on the thread causes Python to kill off the thread when the main thread exits. However, Python is unaware of C++ threads.
One particular C++ thread which has proven to keep NvDA alive for at least one person (see #16072) is the UIA rate limited event handler flusher thread.
We should try much harder to ensure that this thread is terminated during NVDA exit so that it does not keep the NVDA process alive after the main thread exits.
Description of user facing changes
The NVDA process is less likely to stay around after NvDA has exited, which means that NVDA should no longer freeze on restart and NvDA updates should be less likely to fail due to NVDA still running.
Description of development approach
UIA rate limited event handler: improve logic and logging of the flusher thread function to make it clearer as to why the thread will wake for flushes or when it should stop.
Add the ability to terminate UIA rate limited event handler's flusher thread upon request via a new terminate API call. This allows NvDA to ensure that the flusher thread can be terminated, even if it may not release the rate limited event handler COM object reference for some reason.
UIAHandler.terminate: specifically terminate the rate limited event handler from NvDA's main thread, before trying to terminate the UIA MTA thread. This ensures that the c++ UIA rate limitied event handler flusher thread is definitely terminated, even if there may be further errors terminating the UIA MTA Python thread.