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.master
parent
9be88050e6
commit
01317a2fad
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue