summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2021-11-23 20:48:44 -0500
committerNat Goodspeed <nat@lindenlab.com>2021-11-23 20:48:44 -0500
commit67ace0df9953ce3264048c3946720a9df492edfa (patch)
treeddc205f7b79109c306a328e912c270968f675439 /indra
parent2b96f89c2a374d72c0a8bc28a7b06ad4db7eae6e (diff)
SL-16400: Address a couple shutdown crashes.
It can happen that we try to post() work for LLWindowWin32's window thread after the thread's WorkQueue has been closed. Also, instead of giving the "General" ThreadPool static lifespan, put it on the heap, anchored with a static unique_ptr.
Diffstat (limited to 'indra')
-rw-r--r--indra/llwindow/llwindowwin32.cpp10
-rw-r--r--indra/newview/llstartup.cpp32
-rw-r--r--indra/newview/llstartup.h8
3 files changed, 27 insertions, 23 deletions
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index af7b8d91f0..7f8f88a749 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -351,7 +351,15 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool
template <typename CALLABLE>
void post(CALLABLE&& func)
{
- getQueue().post(std::forward<CALLABLE>(func));
+ try
+ {
+ getQueue().post(std::forward<CALLABLE>(func));
+ }
+ catch (const LLThreadSafeQueueInterrupt&)
+ {
+ // Shutdown timing is tricky. The main thread can end up trying
+ // to post a cursor position after having closed the WorkQueue.
+ }
}
/**
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 9a4149948c..2b94ab76ba 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -35,6 +35,7 @@
#else
# include <sys/stat.h> // mkdir()
#endif
+#include <memory> // std::unique_ptr
#include "llviewermedia_streamingaudio.h"
#include "llaudioengine.h"
@@ -255,9 +256,10 @@ static bool mBenefitsSuccessfullyInit = false;
const F32 STATE_AGENT_WAIT_TIMEOUT = 240; //seconds
-boost::scoped_ptr<LLEventPump> LLStartUp::sStateWatcher(new LLEventStream("StartupState"));
-boost::scoped_ptr<LLStartupListener> LLStartUp::sListener(new LLStartupListener());
-boost::scoped_ptr<LLViewerStats::PhaseMap> LLStartUp::sPhases(new LLViewerStats::PhaseMap);
+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
@@ -304,20 +306,6 @@ void callback_cache_name(const LLUUID& id, const std::string& full_name, bool is
// local classes
//
-void launchThreadPool()
-{
- LLSD poolSizes{ gSavedSettings.getLLSD("ThreadPoolSizes") };
- LLSD sizeSpec{ poolSizes["General"] };
- LLSD::Integer size{ sizeSpec.isInteger()? sizeSpec.asInteger() : 3 };
- LL_DEBUGS("ThreadPool") << "Instantiating General pool with "
- << size << " threads" << LL_ENDL;
- // Use a function-static ThreadPool: static duration, but instantiated
- // only on demand.
- // We don't want anyone, especially the main thread, to have to block
- // due to this ThreadPool being full.
- static LL::ThreadPool pool("General", size, 1024*1024);
-}
-
void update_texture_fetch()
{
LLAppViewer::getTextureCache()->update(1); // unpauses the texture cache thread
@@ -1507,7 +1495,15 @@ bool idle_startup()
display_startup();
// start up the ThreadPool we'll use for textures et al.
- launchThreadPool();
+ 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();
// Initialize global class data needed for surfaces (i.e. textures)
LL_DEBUGS("AppInit") << "Initializing sky..." << LL_ENDL;
diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h
index 116aeb36a7..fe8e215f76 100644
--- a/indra/newview/llstartup.h
+++ b/indra/newview/llstartup.h
@@ -27,7 +27,7 @@
#ifndef LL_LLSTARTUP_H
#define LL_LLSTARTUP_H
-#include <boost/scoped_ptr.hpp>
+#include <memory> // unique_ptr
class LLViewerTexture ;
class LLEventPump;
@@ -130,9 +130,9 @@ private:
static std::string startupStateToString(EStartupState state);
static EStartupState gStartupState; // Do not set directly, use LLStartup::setStartupState
- static boost::scoped_ptr<LLEventPump> sStateWatcher;
- static boost::scoped_ptr<LLStartupListener> sListener;
- static boost::scoped_ptr<LLViewerStats::PhaseMap> sPhases;
+ static std::unique_ptr<LLEventPump> sStateWatcher;
+ static std::unique_ptr<LLStartupListener> sListener;
+ static std::unique_ptr<LLViewerStats::PhaseMap> sPhases;
};