summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2021-11-15 14:34:30 -0500
committerNat Goodspeed <nat@lindenlab.com>2021-11-15 14:34:30 -0500
commita633efdc0b62f28f145ec26c2efa8dfc06a3729e (patch)
treef320cd1260ab7764fbbf1f75c933de2ace24d55f /indra
parent1a39a8f7d953a28b03bad0921a8877e21e1e2c61 (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.cpp29
-rw-r--r--indra/llwindow/llwindowwin32.h1
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;
};