blob: 4291d1581640c4fe6b1208c4a1f84c2bd41c3ec9 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
// Copyright Epic Games, Inc. All Rights Reserved.
#include <zencore/workthreadpool.h>
#include <zencore/logging.h>
namespace zen {
namespace detail {
struct LambdaWork : IWork
{
LambdaWork(auto Work) : WorkFunction(Work) {}
virtual void Execute() override { WorkFunction(); }
std::function<void()> WorkFunction;
};
} // namespace detail
WorkerThreadPool::WorkerThreadPool(int InThreadCount)
{
for (int i = 0; i < InThreadCount; ++i)
{
m_WorkerThreads.emplace_back(&WorkerThreadPool::WorkerThreadFunction, this);
}
}
WorkerThreadPool::~WorkerThreadPool()
{
m_WorkQueue.CompleteAdding();
for (std::thread& Thread : m_WorkerThreads)
{
Thread.join();
}
m_WorkerThreads.clear();
}
void
WorkerThreadPool::ScheduleWork(Ref<IWork> Work)
{
m_WorkQueue.Enqueue(std::move(Work));
}
void
WorkerThreadPool::ScheduleWork(std::function<void()>&& Work)
{
m_WorkQueue.Enqueue(new detail::LambdaWork(Work));
}
[[nodiscard]] size_t
WorkerThreadPool::PendingWork() const
{
return m_WorkQueue.Size();
}
void
WorkerThreadPool::WorkerThreadFunction()
{
do
{
Ref<IWork> Work;
if (m_WorkQueue.WaitAndDequeue(Work))
{
try
{
Work->Execute();
}
catch (std::exception& e)
{
Work->m_Exception = std::current_exception();
ZEN_WARN("Caught exception in worker thread: {}", e.what());
}
}
else
{
return;
}
} while (true);
}
} // namespace zen
|