Fix potential initialization/termination deadlock in nvdaHelperRemote. (#20297)
Re #19292.
Summary of the issue:
When nvdaHelperRemote initializes in the application's UI thread, it sets up a new manager thread.
That thread waits on a mutex to guarantee that only one of these manager threads runs at any given time.
The UI thread waits until the new manager thread is initialized.
If an old manager thread is terminating, that thread (which still holds the mutex in (2)) might try to post a window message to the UI thread to terminate IA2 support and then waits for that termination to complete.
But the UI thread is blocked because of (3), which is blocked because of (2), which is blocked because of (4).
Deadlock!
This deadlock occurs infrequently, but I'm fairly sure it has been spotted in the wild. We have a timeout of 10 seconds for these waits, so we deadlock for a maximum of 10 seconds. This deadlock is most visible when it occurs in Explorer, since alt+tab won't be reported properly for at least 10 seconds after restarting NVDA.
Furthermore, this deadlock prevents us from enabling IA2 support in Windows Store applications, which was the workaround implemented for this deadlock in #5417. However, the inability to enable IA2 support for Windows Store applications causes problems like #19292.
Description of user facing changes:
None, as it isn't clear when this occurs, even though there's potential for it. This is a correctness fix, as well as paving the way for a future fix for #19292.
Description of development approach:
Make IA2Support_inProcess_terminate use execInThread instead of its own window message. It needs to wait for execution in the target thread, which is functionality that execInThread already provides.
Make it possible for injection.cpp to access wm_execInThread.
In initInprocManagerThreadIfNeeded, while waiting for the manager thread to initialize, dispatch wm_execInThread messages only. This ensures that a previous instance of nvdaHelperRemote can uninstall IA2 support on the UI thread without causing a deadlock.