diff options
author | Nat Goodspeed <nat@lindenlab.com> | 2021-11-15 14:34:30 -0500 |
---|---|---|
committer | Nat Goodspeed <nat@lindenlab.com> | 2021-11-15 14:34:30 -0500 |
commit | a633efdc0b62f28f145ec26c2efa8dfc06a3729e (patch) | |
tree | f320cd1260ab7764fbbf1f75c933de2ace24d55f /indra | |
parent | 1a39a8f7d953a28b03bad0921a8877e21e1e2c61 (diff) |
SL-16094: In LLWindowWin32::recreateWindow(), kick window thread
before blocking on the pending future. Otherwise the window thread can remain
blocked in a GetMessage() call and deadlock the app.
Diffstat (limited to 'indra')
-rw-r--r-- | indra/llwindow/llwindowwin32.cpp | 29 | ||||
-rw-r--r-- | indra/llwindow/llwindowwin32.h | 1 |
2 files changed, 22 insertions, 8 deletions
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 3f3dd43daf..b845f75ce4 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -346,7 +346,7 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool getQueue().post(std::forward<CALLABLE>(func)); } - // call PeekMessage and pull enqueue messages for later processing + // call GetMessage() and pull enqueue messages for later processing void gatherInput(); HWND mWindowHandle = NULL; HDC mhDC = 0; @@ -1671,6 +1671,13 @@ void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw } ); + // Having posted work to mWindowThread, bump it out of blocked + // GetMessage() call. Normally we could just wait for the next + // gatherInput() call to notice the pending work item and call + // kickWindowThread(), but that would be on THIS calling thread, and we're + // about to block this thread until we get a result from mWindowThread. + kickWindowThread(oldHandle); + auto future = promise.get_future(); // This blocks until mWindowThread processes CreateWindowEx() and calls // promise.set_value(). @@ -2035,13 +2042,7 @@ void LLWindowWin32::gatherInput() if (mWindowThread->getQueue().size()) { LL_PROFILE_ZONE_NAMED("gi - PostMessage"); - if (mWindowHandle) - { - // post a nonsense user message to wake up the Window Thread in - // case any functions are pending and no windows events came - // through this frame - PostMessage(mWindowHandle, WM_USER + 0x0017, 0xB0B0, 0x1337); - } + kickWindowThread(); } while (mWindowThread->mMessageQueue.tryPopBack(msg)) @@ -4470,3 +4471,15 @@ void LLWindowWin32::postMouseButtonEvent(const std::function<void()>& func) mMouseQueue.pushFront(func); } +void LLWindowWin32::kickWindowThread(HWND windowHandle) +{ + if (! windowHandle) + windowHandle = mWindowHandle; + if (windowHandle) + { + // post a nonsense user message to wake up the Window Thread in + // case any functions are pending and no windows events came + // through this frame + PostMessage(windowHandle, WM_USER + 0x0017, 0xB0B0, 0x1337); + } +} diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index 5966061177..b02815e990 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -244,6 +244,7 @@ protected: void post(const std::function<void()>& func); void postMouseButtonEvent(const std::function<void()>& func); void recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw_style); + void kickWindowThread(HWND windowHandle=0); friend class LLWindowManager; }; |