diff options
| -rw-r--r-- | indra/llcommon/threadpool.cpp | 17 | ||||
| -rw-r--r-- | indra/llcommon/threadpool.h | 10 | ||||
| -rw-r--r-- | indra/llwindow/llwindowwin32.cpp | 61 | ||||
| -rw-r--r-- | indra/newview/llappviewer.cpp | 8 | ||||
| -rwxr-xr-x | indra/newview/llviewerregion.cpp | 15 | 
5 files changed, 71 insertions, 40 deletions
| diff --git a/indra/llcommon/threadpool.cpp b/indra/llcommon/threadpool.cpp index 3a9a5a2062..a063a01b82 100644 --- a/indra/llcommon/threadpool.cpp +++ b/indra/llcommon/threadpool.cpp @@ -60,12 +60,15 @@ struct sleepy_robin: public boost::fibers::algo::round_robin  /*****************************************************************************  *   ThreadPoolBase  *****************************************************************************/ -LL::ThreadPoolBase::ThreadPoolBase(const std::string& name, size_t threads, -                                   WorkQueueBase* queue): +LL::ThreadPoolBase::ThreadPoolBase(const std::string& name, +                                   size_t threads, +                                   WorkQueueBase* queue, +                                   bool auto_shutdown):      super(name),      mName("ThreadPool:" + name),      mThreadCount(getConfiguredWidth(name, threads)), -    mQueue(queue) +    mQueue(queue), +    mAutomaticShutdown(auto_shutdown)  {}  void LL::ThreadPoolBase::start() @@ -79,6 +82,14 @@ void LL::ThreadPoolBase::start()                  run(tname);              });      } + +    if (!mAutomaticShutdown) +    { +        // Some threads, like main window's might need to run a bit longer +        // to wait for a proper shutdown message +        return; +    } +      // Listen on "LLApp", and when the app is shutting down, close the queue      // and join the workers.      LLEventPumps::instance().obtain("LLApp").listen( diff --git a/indra/llcommon/threadpool.h b/indra/llcommon/threadpool.h index 60f4a0ce1b..fa16c6fe71 100644 --- a/indra/llcommon/threadpool.h +++ b/indra/llcommon/threadpool.h @@ -40,7 +40,7 @@ namespace LL           * overrides this parameter.           */          ThreadPoolBase(const std::string& name, size_t threads, -                       WorkQueueBase* queue); +                       WorkQueueBase* queue, bool auto_shutdown = true);          virtual ~ThreadPoolBase();          /** @@ -87,6 +87,7 @@ namespace LL      protected:          std::unique_ptr<WorkQueueBase> mQueue; +        bool mAutomaticShutdown;      private:          void run(const std::string& name); @@ -117,8 +118,11 @@ namespace LL           * Constraining the queue can cause a submitter to block. Do not           * constrain any ThreadPool accepting work from the main thread.           */ -        ThreadPoolUsing(const std::string& name, size_t threads=1, size_t capacity=1024*1024): -            ThreadPoolBase(name, threads, new queue_t(name, capacity)) +        ThreadPoolUsing(const std::string& name, +                        size_t threads=1, +                        size_t capacity=1024*1024, +                        bool auto_shutdown = true): +            ThreadPoolBase(name, threads, new queue_t(name, capacity), auto_shutdown)          {}          ~ThreadPoolUsing() override {} diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 057d7a700e..0c1ed85477 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -412,8 +412,8 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool      using FuncType = std::function<void()>;      // call GetMessage() and pull enqueue messages for later processing      void gatherInput(); -    HWND mWindowHandle = NULL; -    HDC mhDC = 0; +    HWND mWindowHandleThrd = NULL; +    HDC mhDCThrd = 0;      // *HACK: Attempt to prevent startup crashes by deferring memory accounting      // until after some graphics setup. See SL-20177. -Cosmic,2023-09-18 @@ -987,23 +987,23 @@ void LLWindowWin32::close()  	LL_DEBUGS("Window") << "Destroying Window" << LL_ENDL; -    mWindowThread->post([=]() +    mWindowThread->post([this, self = mWindowThread]()          { -            if (IsWindow(mWindowHandle)) +            if (IsWindow(self->mWindowHandleThrd))              { -                if (mhDC) +                if (self->mhDCThrd)                  { -                    if (!ReleaseDC(mWindowHandle, mhDC)) +                    if (!ReleaseDC(self->mWindowHandleThrd, self->mhDCThrd))                      {                          LL_WARNS("Window") << "Release of ghDC failed!" << LL_ENDL;                      }                  }                  // Make sure we don't leave a blank toolbar button. -                ShowWindow(mWindowHandle, SW_HIDE); +                ShowWindow(self->mWindowHandleThrd, SW_HIDE);                  // This causes WM_DESTROY to be sent *immediately* -                if (!destroy_window_handler(mWindowHandle)) +                if (!destroy_window_handler(self->mWindowHandleThrd))                  {                      OSMessageBox(mCallbacks->translateString("MBDestroyWinFailed"),                          mCallbacks->translateString("MBShutdownErr"), @@ -1015,17 +1015,18 @@ void LLWindowWin32::close()                  // Something killed the window while we were busy destroying gl or handle somehow got broken                  LL_WARNS("Window") << "Failed to destroy Window, invalid handle!" << LL_ENDL;              } - +            self->mWindowHandleThrd = NULL; +            self->mhDCThrd = NULL; +            self->mGLReady = false;          }); -    // Window thread might be waiting for a getMessage(), give it -    // a push to enshure it will process destroy_window_handler -    kickWindowThread(); -    // Even though the above lambda might not yet have run, we've already -    // bound mWindowHandle into it by value, which should suffice for the -    // operations we're asking. That's the last time WE should touch it.      mhDC = NULL;      mWindowHandle = NULL; + +    // Window thread might be waiting for a getMessage(), give it +    // a push to enshure it will process destroy_window_handler +    kickWindowThread(); +          mWindowThread->close();  } @@ -1777,8 +1778,8 @@ void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw          ()          {              LL_DEBUGS("Window") << "recreateWindow(): window_work entry" << LL_ENDL; -            self->mWindowHandle = 0; -            self->mhDC = 0; +            self->mWindowHandleThrd = 0; +            self->mhDCThrd = 0;              if (oldWindowHandle)              { @@ -1813,20 +1814,20 @@ void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw              {                  // Failed to create window: clear the variables. This                  // assignment is valid because we're running on mWindowThread. -                self->mWindowHandle = NULL; -                self->mhDC = 0; +                self->mWindowHandleThrd = NULL; +                self->mhDCThrd = 0;              }              else              {                  // Update mWindowThread's own mWindowHandle and mhDC. -                self->mWindowHandle = handle; -                self->mhDC = GetDC(handle); +                self->mWindowHandleThrd = handle; +                self->mhDCThrd = GetDC(handle);              }              updateWindowRect();              // It's important to wake up the future either way. -            promise.set_value(std::make_pair(self->mWindowHandle, self->mhDC)); +            promise.set_value(std::make_pair(self->mWindowHandleThrd, self->mhDCThrd));              LL_DEBUGS("Window") << "recreateWindow(): window_work done" << LL_ENDL;          };      // But how we pass window_work to the window thread depends on whether we @@ -4589,7 +4590,7 @@ U32 LLWindowWin32::getAvailableVRAMMegabytes()  #endif // LL_WINDOWS  inline LLWindowWin32::LLWindowWin32Thread::LLWindowWin32Thread() -    : LL::ThreadPool("Window Thread", 1, MAX_QUEUE_SIZE) +    : LL::ThreadPool("Window Thread", 1, MAX_QUEUE_SIZE, false)  {      LL::ThreadPool::start();  } @@ -4745,7 +4746,7 @@ void LLWindowWin32::LLWindowWin32Thread::initD3D()  {      if (!mGLReady) { return; } -    if (mDXGIAdapter == NULL && mD3DDevice == NULL && mWindowHandle != 0) +    if (mDXGIAdapter == NULL && mD3DDevice == NULL && mWindowHandleThrd != 0)      {          mD3D = Direct3DCreate9(D3D_SDK_VERSION); @@ -4755,7 +4756,7 @@ void LLWindowWin32::LLWindowWin32Thread::initD3D()          d3dpp.Windowed = TRUE;          d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; -        HRESULT res = mD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, mWindowHandle, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &mD3DDevice); +        HRESULT res = mD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, mWindowHandleThrd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &mD3DDevice);          if (FAILED(res))          { @@ -4861,7 +4862,7 @@ void LLWindowWin32::LLWindowWin32Thread::run()          // lazily call initD3D inside this loop to catch when mGLReady has been set to true          initDX(); -        if (mWindowHandle != 0) +        if (mWindowHandleThrd != 0)          {              // lazily call initD3D inside this loop to catch when mWindowHandle has been set, and mGLReady has been set to true              // *TODO: Shutdown if this fails when mWindowHandle exists @@ -4869,16 +4870,16 @@ void LLWindowWin32::LLWindowWin32Thread::run()              MSG msg;              BOOL status; -            if (mhDC == 0) +            if (mhDCThrd == 0)              {                  LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("w32t - PeekMessage"); -                logger.onChange("PeekMessage(", std::hex, mWindowHandle, ")"); -                status = PeekMessage(&msg, mWindowHandle, 0, 0, PM_REMOVE); +                logger.onChange("PeekMessage(", std::hex, mWindowHandleThrd, ")"); +                status = PeekMessage(&msg, mWindowHandleThrd, 0, 0, PM_REMOVE);              }              else              {                  LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("w32t - GetMessage"); -                logger.always("GetMessage(", std::hex, mWindowHandle, ")"); +                logger.always("GetMessage(", std::hex, mWindowHandleThrd, ")");                  status = GetMessage(&msg, NULL, 0, 0);              }              if (status > 0) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 30fb0be46c..f094170ff5 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1892,6 +1892,9 @@ bool LLAppViewer::cleanup()  		LL_INFOS() << "ViewerWindow deleted" << LL_ENDL;  	} +    LLSplashScreen::show(); +    LLSplashScreen::update(LLTrans::getString("ShuttingDown")); +  	LL_INFOS() << "Cleaning up Keyboard & Joystick" << LL_ENDL;  	// viewer UI relies on keyboard so keep it aound until viewer UI isa gone @@ -2170,6 +2173,8 @@ bool LLAppViewer::cleanup()  	// deleteSingleton() methods.  	LLSingletonBase::deleteAll(); +    LLSplashScreen::hide(); +      LL_INFOS() << "Goodbye!" << LL_ENDL;  	removeDumpDir(); @@ -5059,6 +5064,9 @@ void LLAppViewer::idleShutdown()  		&& gLogoutTimer.getElapsedTimeF32() < SHUTDOWN_UPLOAD_SAVE_TIME  		&& !logoutRequestSent())  	{ +        gViewerWindow->setShowProgress(TRUE); +        gViewerWindow->setProgressPercent(100.f); +        gViewerWindow->setProgressString(LLTrans::getString("LoggingOut"));  		return;  	} diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 6c0e25ae39..ed5b809003 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -829,10 +829,17 @@ void LLViewerRegion::saveObjectCache()  		mCacheDirty = FALSE;  	} -	// Map of LLVOCacheEntry takes time to release, store map for cleanup on idle -	sRegionCacheCleanup.insert(mImpl->mCacheMap.begin(), mImpl->mCacheMap.end()); -	mImpl->mCacheMap.clear(); -	// TODO - probably need to do the same for overrides cache +    if (LLAppViewer::instance()->isQuitting()) +    { +        mImpl->mCacheMap.clear(); +    } +    else +    { +        // Map of LLVOCacheEntry takes time to release, store map for cleanup on idle +        sRegionCacheCleanup.insert(mImpl->mCacheMap.begin(), mImpl->mCacheMap.end()); +        mImpl->mCacheMap.clear(); +        // TODO - probably need to do the same for overrides cache +    }  }  void LLViewerRegion::sendMessage() | 
