diff options
author | Nat Goodspeed <nat@lindenlab.com> | 2021-11-30 15:22:26 -0500 |
---|---|---|
committer | Nat Goodspeed <nat@lindenlab.com> | 2021-11-30 17:00:09 -0500 |
commit | 01317a2faded53c79db7e0814426f1d8b2fd12fc (patch) | |
tree | 75e42096bc5ed2cdff78a4a7a58d873f9bff9a83 /indra/newview | |
parent | 9be88050e67edcb8578ce6edbee255ba66e553a1 (diff) |
SL-16421: Destroy the "General" ThreadPool as soon as cleanup starts.
Introduce LLAppViewer::onCleanup(), a method that accepts a nullary callable
to execute once viewer shutdown begins. Fire the collected callables in
LLAppViewer::cleanup().
In llstartup.cpp, instead of declaring a static unique_ptr and relying on
static object destruction to clean up the "General" ThreadPool, bind the
pointer to the new ThreadPool into an onCleanup() lambda that will delete it
when called. ~ThreadPool() takes care of orderly shutdown.
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/llappviewer.cpp | 5 | ||||
-rw-r--r-- | indra/newview/llappviewer.h | 14 | ||||
-rw-r--r-- | indra/newview/llstartup.cpp | 23 |
3 files changed, 31 insertions, 11 deletions
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 529db397b2..a5d32ba243 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1729,6 +1729,11 @@ void LLAppViewer::flushVFSIO() bool LLAppViewer::cleanup() { + // Since we don't know what functions are going to be queued by + // onCleanup(), we have to assume they might rely on some of the things + // we're about to destroy below. Run them first. + mOnCleanup(); + LLAtmosphere::cleanupClass(); //ditch LLVOAvatarSelf instance diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index d23a00be7f..f456cbbd36 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -49,6 +49,8 @@ #include "lltimer.h" #include "llappcorehttp.h" +#include <boost/signals2.hpp> + class LLCommandLineParser; class LLFrameTimer; class LLPumpIO; @@ -189,10 +191,20 @@ public: // On LoginCompleted callback typedef boost::signals2::signal<void (void)> login_completed_signal_t; login_completed_signal_t mOnLoginCompleted; - boost::signals2::connection setOnLoginCompletedCallback( const login_completed_signal_t::slot_type& cb ) { return mOnLoginCompleted.connect(cb); } + boost::signals2::connection setOnLoginCompletedCallback( const login_completed_signal_t::slot_type& cb ) + { + return mOnLoginCompleted.connect(cb); + } void addOnIdleCallback(const boost::function<void()>& cb); // add a callback to fire (once) when idle + typedef boost::signals2::signal<void()> cleanup_signal_t; + cleanup_signal_t mOnCleanup; + boost::signals2::connection onCleanup(const cleanup_signal_t::slot_type& cb) + { + return mOnCleanup.connect(cb); + } + void purgeUserDataOnExit() { mPurgeUserDataOnExit = true; } void purgeCache(); // Clear the local cache. void purgeCacheImmediate(); //clear local cache immediately. diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index adfa1b0c10..d8e68dbc1e 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -259,7 +259,6 @@ const F32 STATE_AGENT_WAIT_TIMEOUT = 240; //seconds std::unique_ptr<LLEventPump> LLStartUp::sStateWatcher(new LLEventStream("StartupState")); std::unique_ptr<LLStartupListener> LLStartUp::sListener(new LLStartupListener()); std::unique_ptr<LLViewerStats::PhaseMap> LLStartUp::sPhases(new LLViewerStats::PhaseMap); -std::unique_ptr<LL::ThreadPool> gGeneralThreadPool; // // local function declaration @@ -1495,15 +1494,19 @@ bool idle_startup() display_startup(); // start up the ThreadPool we'll use for textures et al. - LLSD poolSizes{ gSavedSettings.getLLSD("ThreadPoolSizes") }; - LLSD sizeSpec{ poolSizes["General"] }; - LLSD::Integer poolSize{ sizeSpec.isInteger()? sizeSpec.asInteger() : 3 }; - LL_DEBUGS("ThreadPool") << "Instantiating General pool with " - << poolSize << " threads" << LL_ENDL; - // We don't want anyone, especially the main thread, to have to block - // due to this ThreadPool being full. - gGeneralThreadPool.reset(new LL::ThreadPool("General", poolSize, 1024*1024)); - gGeneralThreadPool->start(); + { + LLSD poolSizes{ gSavedSettings.getLLSD("ThreadPoolSizes") }; + LLSD sizeSpec{ poolSizes["General"] }; + LLSD::Integer poolSize{ sizeSpec.isInteger()? sizeSpec.asInteger() : 3 }; + LL_DEBUGS("ThreadPool") << "Instantiating General pool with " + << poolSize << " threads" << LL_ENDL; + // We don't want anyone, especially the main thread, to have to block + // due to this ThreadPool being full. + auto pool = new LL::ThreadPool("General", poolSize, 1024*1024); + pool->start(); + // Once we start shutting down, destroy this ThreadPool. + LLAppViewer::instance()->onCleanup([pool](){ delete pool; }); + } // Initialize global class data needed for surfaces (i.e. textures) LL_DEBUGS("AppInit") << "Initializing sky..." << LL_ENDL; |