ClickHouse/src/Interpreters/threadPoolCallbackRunner.cpp

41 lines
1.6 KiB
C++
Raw Normal View History

#include "threadPoolCallbackRunner.h"
2022-04-27 15:05:45 +00:00
#include <Common/scope_guard_safe.h>
#include <Common/CurrentThread.h>
namespace DB
{
2022-03-30 09:00:06 +00:00
CallbackRunner threadPoolCallbackRunner(ThreadPool & pool)
{
2022-03-30 09:00:06 +00:00
return [pool = &pool, thread_group = CurrentThread::getGroup()](auto callback) mutable
{
2022-03-30 08:15:20 +00:00
pool->scheduleOrThrow(
2022-03-30 09:00:06 +00:00
[&, callback = std::move(callback), thread_group]()
2022-03-30 08:15:20 +00:00
{
if (thread_group)
2022-03-30 08:15:20 +00:00
CurrentThread::attachTo(thread_group);
SCOPE_EXIT_SAFE({
if (thread_group)
CurrentThread::detachQueryIfNotDetached();
/// After we detached from the thread_group, parent for memory_tracker inside ThreadStatus will be reset to it's parent.
/// Typically, it may be changes from Process to User.
/// Usually it could be ok, because thread pool task is executed before user-level memory tracker is destroyed.
/// However, thread could stay alive inside the thread pool, and it's ThreadStatus as well.
/// When, finally, we destroy the thread (and the ThreadStatus),
/// it can use memory tracker in the ~ThreadStatus in order to alloc/free untracked_memory,
/// and by this time user-level memory tracker may be already destroyed.
///
/// As a work-around, reset memory tracker to total, which is always alive.
CurrentThread::get().memory_tracker.setParent(&total_memory_tracker);
});
callback();
});
};
}
}