SL-16400: Add ThreadPool::start() method, and call it.

It's sometimes important to finish other initialization before launching the
threads in the ThreadPool, so make that an explicit step. In particular, we
were launching the LLImageGL texture thread before initializing the GL
context, resulting in all gray textures.
meow-7.2.2
Nat Goodspeed 2021-11-23 20:39:32 -05:00
parent 6d36038e40
commit 2b96f89c2a
4 changed files with 18 additions and 7 deletions

View File

@ -23,11 +23,15 @@
LL::ThreadPool::ThreadPool(const std::string& name, size_t threads, size_t capacity):
mQueue(name, capacity),
mName("ThreadPool:" + name)
mName("ThreadPool:" + name),
mThreadCount(threads)
{}
void LL::ThreadPool::start()
{
for (size_t i = 0; i < threads; ++i)
for (size_t i = 0; i < mThreadCount; ++i)
{
std::string tname{ STRINGIZE(mName << ':' << (i+1) << '/' << threads) };
std::string tname{ stringize(mName, ':', (i+1), '/', mThreadCount) };
mThreads.emplace_back(tname, [this, tname]()
{
LL_PROFILER_SET_THREAD_NAME(tname.c_str());

View File

@ -32,6 +32,14 @@ namespace LL
ThreadPool(const std::string& name, size_t threads=1, size_t capacity=1024);
virtual ~ThreadPool();
/**
* Launch the ThreadPool. Until this call, a constructed ThreadPool
* launches no threads. That permits coders to derive from ThreadPool,
* or store it as a member of some other class, but refrain from
* launching it until all other construction is complete.
*/
void start();
/**
* ThreadPool listens for application shutdown messages on the "LLApp"
* LLEventPump. Call close() to shut down this ThreadPool early.
@ -54,6 +62,7 @@ namespace LL
WorkQueue mQueue;
std::string mName;
size_t mThreadCount;
std::vector<std::pair<std::string, std::thread>> mThreads;
};

View File

@ -2261,6 +2261,7 @@ LLImageGLThread::LLImageGLThread(LLWindow* window)
mFinished = false;
mContext = mWindow->createSharedContext();
ThreadPool::start();
}
void LLImageGLThread::run()
@ -2268,10 +2269,6 @@ void LLImageGLThread::run()
LL_PROFILE_ZONE_SCOPED;
// We must perform setup on this thread before actually servicing our
// WorkQueue, likewise cleanup afterwards.
while (mContext == nullptr)
{ // HACK -- wait for mContext to be initialized since this thread will usually start before mContext is set
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
mWindow->makeContextCurrent(mContext);
gGL.init();
ThreadPool::run();

View File

@ -4495,6 +4495,7 @@ std::vector<std::string> LLWindowWin32::getDynamicFallbackFontList()
inline LLWindowWin32::LLWindowWin32Thread::LLWindowWin32Thread()
: ThreadPool("Window Thread", 1, MAX_QUEUE_SIZE)
{
ThreadPool::start();
}
/**