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 | |
| 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.
| -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; | 
