/** prevent waiting for a task from inside a task */ #ifdefined DBG_UTIL && (defined LINUX || defined _WIN32) static thread_local bool gbIsWorkerThread; #endif
// used to group thread-tasks for waiting in waitTillDone() class ThreadTaskTag
{
std::mutex maMutex;
sal_Int32 mnTasksWorking;
std::condition_variable maTasksComplete;
ThreadPool::~ThreadPool()
{ // note: calling shutdown from global variable dtor blocks forever on Win7 // note2: there isn't enough MSVCRT left on exit to call assert() properly // so these asserts just print something to stderr but exit status is // still 0, but hopefully they will be more helpful on non-WNT platforms
assert(mbTerminate);
assert(maTasks.empty());
assert(mnBusyWorkers == 0);
}
// Used to order shutdown, and to ensure there are no lingering // threads after LibreOfficeKit pre-init. void ThreadPool::shutdown()
{ // if (mbTerminate) // return;
void ThreadPool::shutdownLocked(std::unique_lock<std::mutex>& aGuard)
{ if( maWorkers.empty() )
{ // no threads at all -> execute the work in-line
std::unique_ptr<ThreadTask> pTask; while ( ( pTask = popWorkLocked(aGuard, false) ) )
{
std::shared_ptr<ThreadTaskTag> pTag(pTask->mpTag);
pTask->exec();
pTag->onTaskWorkerDone();
}
} else
{ while( !maTasks.empty() )
{
maTasksChanged.wait( aGuard ); // In the (unlikely but possible?) case pushTask() gets called meanwhile, // its notify_one() call is meant to wake a up a thread and process the task. // But if this code gets woken up instead, it could lead to a deadlock. // Pass on the notification.
maTasksChanged.notify_one();
}
}
assert( maTasks.empty() );
// coverity[missing_lock] - on purpose
mbTerminate = true;
// Worked on tasks are already removed from maTasks, so include the count of busy workers. if (maWorkers.size() < mnMaxWorkers && maWorkers.size() <= maTasks.size() + mnBusyWorkers)
{
maWorkers.push_back( new ThreadWorker( this ) );
maWorkers.back()->launch();
}
void ThreadPool::waitUntilDone(const std::shared_ptr<ThreadTaskTag>& rTag, bool bJoin)
{ #ifdefined DBG_UTIL && (defined LINUX || defined _WIN32)
assert(!gbIsWorkerThread && "cannot wait for tasks from inside a task"); #endif
{
std::unique_lock< std::mutex > aGuard( maMutex );
if( maWorkers.empty() )
{ // no threads at all -> execute the work in-line while (!rTag->isDone())
{
std::unique_ptr<ThreadTask> pTask = popWorkLocked(aGuard, false); if (!pTask) break;
std::shared_ptr<ThreadTaskTag> pTag(pTask->mpTag);
pTask->exec();
pTag->onTaskWorkerDone();
}
}
}
rTag->waitUntilDone();
if (bJoin)
joinThreadsIfIdle();
}
bool ThreadPool::joinThreadsIfIdle()
{
std::unique_lock< std::mutex > aGuard( maMutex ); if (isIdle()) // check if there are still tasks from another tag
{
shutdownLocked(aGuard); returntrue;
} returnfalse;
}
void ThreadTaskTag::waitUntilDone()
{
std::unique_lock< std::mutex > aGuard( maMutex ); while( mnTasksWorking > 0 )
{ #ifdefined DBG_UTIL && !defined NDEBUG // 10 minute timeout in debug mode, unless the code is built with // sanitizers or debugged in valgrind or gdb, in which case the threads // should not time out in the middle of a debugging session int maxTimeout = 10 * 60; #if !ENABLE_RUNTIME_OPTIMIZATIONS
maxTimeout = 30 * 60; #endif #ifdefined HAVE_VALGRIND_HEADERS if( RUNNING_ON_VALGRIND )
maxTimeout = 30 * 60; #endif if( isDebuggerAttached())
maxTimeout = 300 * 60;
std::cv_status result = maTasksComplete.wait_for(
aGuard, std::chrono::seconds( maxTimeout ));
assert(result != std::cv_status::timeout); #else // 10 minute timeout in production so the app eventually throws some kind of error if (maTasksComplete.wait_for(
aGuard, std::chrono::seconds( 10 * 60 )) == std::cv_status::timeout) throw std::runtime_error("timeout waiting for threadpool tasks"); #endif
}
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.12Bemerkung:
(vorverarbeitet am 2026-10-02)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.