From 7b3999b1661fc814f392cec41137e2a6c7b94816 Mon Sep 17 00:00:00 2001 From: crs Date: Sun, 18 Aug 2002 17:40:10 +0000 Subject: [PATCH] fixed win32 deadlock. when a client disconnects the server will warp the mouse to the primary screen. entering the primary screen causes the primary screen's window to be hidden. the deadlock occurs because hiding the window seems to post a message then wait for it to be handled (or possibly it won't send a message while a posted message is being handled). thread A locks the mutex, warps the mouse, the hides the window. thread B begins processing the mouse warp then tries to lock the mutex. thread A is waiting on the event loop owned by B while B is waiting on the mutex owned by A. this fix simply hides the window asynchronously. however, there may be other ways to cause a similar deadlock that have not been found. --- lib/server/CMSWindowsPrimaryScreen.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/server/CMSWindowsPrimaryScreen.cpp b/lib/server/CMSWindowsPrimaryScreen.cpp index 5fe8b1b0..b9622694 100644 --- a/lib/server/CMSWindowsPrimaryScreen.cpp +++ b/lib/server/CMSWindowsPrimaryScreen.cpp @@ -563,7 +563,19 @@ CMSWindowsPrimaryScreen::hideWindow() AttachThreadInput(myThread, m_lastActiveThread, FALSE); } } - ShowWindow(m_window, SW_HIDE); + + // hide the window. do not wait for it, though, since ShowWindow() + // waits for the event loop to process the show-window event, but + // that thread may need to lock the mutex that this thread has + // already locked. in particular, that deadlock will occur unless + // we use the asynchronous version of show window when a client + // disconnects: thread A will lock the mutex and enter the primary + // screen which warps the mouse and calls this method while thread B + // will handle the mouse warp event and call methods that try to + // lock the mutex. thread A owns the mutex and is waiting for the + // event loop, thread B owns the event loop and is waiting for the + // mutex causing deadlock. + ShowWindowAsync(m_window, SW_HIDE); } void