diff options
author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2024-04-16 23:25:01 +0300 |
---|---|---|
committer | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2024-04-17 22:55:05 +0300 |
commit | 21947778baaca205615a71a97ac8f563c998fdd3 (patch) | |
tree | 58964b6ebfbe2596a509327608da8d9fa8a791d2 /indra | |
parent | 505ed20da32df3ab96f8b199e30be3c50e88a1e2 (diff) |
SL-18721 Window shutdown adjustments
On viewer shutdown
1. Instead of handling potential WM_* messages viewer is no longer
equiped to handle drop window's pointer and expect only WM_DESTROY
2. Detach thread and let it do its own thing, thread will delete itself
3. Reverts commit 1161262029f9619fb02d81575382b64d82d9cd09
Reason for the change: window was closing too early (as son as "LLApp"
status changes) without proper cleanup
Diffstat (limited to 'indra')
-rw-r--r-- | indra/llcommon/threadpool.h | 2 | ||||
-rw-r--r-- | indra/llwindow/llwindowwin32.cpp | 102 |
2 files changed, 37 insertions, 67 deletions
diff --git a/indra/llcommon/threadpool.h b/indra/llcommon/threadpool.h index 74056aea17..b8be7bb81a 100644 --- a/indra/llcommon/threadpool.h +++ b/indra/llcommon/threadpool.h @@ -55,7 +55,7 @@ namespace LL * ThreadPool listens for application shutdown messages on the "LLApp" * LLEventPump. Call close() to shut down this ThreadPool early. */ - virtual void close(); + void close(); std::string getName() const { return mName; } size_t getWidth() const { return mThreads.size(); } diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 54e5f43e87..3ffc7d3354 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -351,10 +351,9 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool LLWindowWin32Thread(); void run() override; - void close() override; // closes queue, wakes thread, waits until thread closes - void wakeAndDestroy(); + bool wakeAndDestroy(); void glReady() { @@ -425,6 +424,7 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool // *HACK: Attempt to prevent startup crashes by deferring memory accounting // until after some graphics setup. See SL-20177. -Cosmic,2023-09-18 bool mGLReady = false; + bool mDeleteOnExit = false; // best guess at available video memory in MB std::atomic<U32> mAvailableVRAM; @@ -997,7 +997,11 @@ void LLWindowWin32::close() mhDC = NULL; mWindowHandle = NULL; - mWindowThread->wakeAndDestroy(); + if (mWindowThread->wakeAndDestroy()) + { + // thread will delete itselfs once done + mWindowThread = NULL; + } } BOOL LLWindowWin32::isValid() @@ -3104,10 +3108,17 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ break; } } - else + else // (NULL == window_imp) { - // (NULL == window_imp) - LL_DEBUGS("Window") << "No window implementation to handle message with, message code: " << U32(u_msg) << LL_ENDL; + if (u_msg == WM_DESTROY) + { + PostQuitMessage(0); // Posts WM_QUIT with an exit code of 0 + return 0; + } + else + { + LL_DEBUGS("Window") << "No window implementation to handle message with, message code: " << U32(u_msg) << LL_ENDL; + } } // pass unhandled messages down to Windows @@ -4563,25 +4574,11 @@ U32 LLWindowWin32::getAvailableVRAMMegabytes() #endif // LL_WINDOWS inline LLWindowWin32::LLWindowWin32Thread::LLWindowWin32Thread() - : LL::ThreadPool("Window Thread", 1, MAX_QUEUE_SIZE, true /*should be false, temporary workaround for SL-18721*/) + : LL::ThreadPool("Window Thread", 1, MAX_QUEUE_SIZE, false) { LL::ThreadPool::start(); } -void LLWindowWin32::LLWindowWin32Thread::close() -{ - if (!mQueue->isClosed()) - { - LL_WARNS() << "Closing window thread without using destroy_window_handler" << LL_ENDL; - LL::ThreadPool::close(); - - // Workaround for SL-18721 in case window closes too early and abruptly - LLSplashScreen::show(); - LLSplashScreen::update("..."); // will be updated later - } -} - - /** * LogChange is to log changes in status while trying to avoid spamming the * log with repeated messages, especially in a tight loop. It refuses to log @@ -4926,14 +4923,19 @@ void LLWindowWin32::LLWindowWin32Thread::run() } cleanupDX(); + + if (mDeleteOnExit) + { + delete this; + } } -void LLWindowWin32::LLWindowWin32Thread::wakeAndDestroy() +bool LLWindowWin32::LLWindowWin32Thread::wakeAndDestroy() { if (mQueue->isClosed()) { - LL_WARNS() << "Tried to close Queue. Win32 thread Queue already closed." << LL_ENDL; - return; + LL_WARNS() << "Tried to close Queue. Win32 thread Queue already closed." <<LL_ENDL; + return false; } // Make sure we don't leave a blank toolbar button. @@ -4972,6 +4974,15 @@ void LLWindowWin32::LLWindowWin32Thread::wakeAndDestroy() mGLReady = false; }); + mDeleteOnExit = true; + SetWindowLongPtr(old_handle, GWLP_USERDATA, NULL); + + // Let thread finish on its own and don't block main thread. + for (auto& pair : mThreads) + { + pair.second.detach(); + } + LL_DEBUGS("Window") << "Closing window's pool queue" << LL_ENDL; mQueue->close(); @@ -4986,49 +4997,8 @@ void LLWindowWin32::LLWindowWin32Thread::wakeAndDestroy() PostMessage(old_handle, WM_DUMMY_, wparam, 0x1337); } - // There are cases where window will refuse to close, - // can't wait forever on join, check state instead - LLTimer timeout; - timeout.setTimerExpirySec(2.0); - while (!getQueue().done() && !timeout.hasExpired() && mWindowHandleThrd) - { - ms_sleep(100); - } - - if (getQueue().done() || mWindowHandleThrd == NULL) - { - // Window is closed, started closing or is cleaning up - // now wait for our single thread to die. - if (mWindowHandleThrd) - { - LL_INFOS("Window") << "Window is closing, waiting on pool's thread to join, time since post: " << timeout.getElapsedSeconds() << "s" << LL_ENDL; - } - else - { - LL_DEBUGS("Window") << "Waiting on pool's thread, time since post: " << timeout.getElapsedSeconds() << "s" << LL_ENDL; - } - for (auto& pair : mThreads) - { - pair.second.join(); - } - } - else - { - // Something suspended window thread, can't afford to wait forever - // so kill thread instead - // Ex: This can happen if user starts dragging window arround (if it - // was visible) or a modal notification pops up - LL_WARNS("Window") << "Window is frozen, couldn't perform clean exit" << LL_ENDL; - - for (auto& pair : mThreads) - { - // very unsafe - TerminateThread(pair.second.native_handle(), 0); - pair.second.detach(); - cleanupDX(); - } - } LL_DEBUGS("Window") << "thread pool shutdown complete" << LL_ENDL; + return true; } void LLWindowWin32::post(const std::function<void()>& func) |