Let me introduce the context. A FSX plugin using FSUIPC Internal library. That plugin invokes FSUIPC_Open2() when loaded, and runs a new execution thread in background that loops on read/write operations with the corresponding calls to FSUIPC_Process(). On FSX exit, the plugin is stopped and it tries to break the thread's loop and wait for it to finish (thread join). But the loop cannot be break since the thread is permanently blocked in a call to FSUIPC_Process(). That deadlock prevents FSX to be closed.
After some investigation I realized that the problems is caused by the fact that FSUIPC plugin is stopped before my plugin. When FSUIPC shuts down, the call to FSUIPC_Process() never returns. Looking into the implementation of that function I see the following call.
dwError = SendMessage(m_hWnd, WM_IPCTHREADACCESS, (WPARAM) (m_pNext - m_pView - 4), (LPARAM) m_pView);
According to Microsoft documentation, "the sending thread is blocked until the receiving thread processes the message." So my suspect seems to be right. I tried to replace the call to SendMessage() by a call to SendMessageTimeout(), which returns with an error if there is no response after a timeout passed as argument (e.g., 1000 milliseconds).
dwError = SendMessageTimeout(
m_hWnd, WM_IPCTHREADACCESS, (WPARAM) (m_pNext - m_pView - 4), (LPARAM) m_pView, SMTO_BLOCK, 1000, NULL);
Fortunately, it works with this change, FSUIPC_Process() returns with an error when FSUIPC plugin is not up and running anymore.
I think it would be useful to replace the call to SendMessage() by SendMessageTimeout() in future versions of FSUIPC distribution. Is there any contribution policy or procedure to follow?
Thanks in advance,
-- Álvaro