1 | #include "ZydecoCommon.hpp" |
2 | #include "ThreadLooping.hpp" |
3 | #include "IUpdateable.hpp" |
4 |
|
5 |
|
6 | static Logger LOGGER("THREAD_LOOPING"); |
7 |
|
8 |
|
9 | ThreadLooping::ThreadLooping(std::string thread_name, IUpdateable& thread_update): |
10 | m_threadName(thread_name), |
11 | m_rThreadUpdate(thread_update) |
12 | { |
13 | LOGGER.Log(Logger::VERBOSE, "Creating ThreadLooping '{}'", m_threadName); |
14 |
|
15 | std::atomic_init(&m_aShouldThreadTerminate, false); |
16 | std::atomic_init(&m_aIsThreadRunning, false); |
17 | } |
18 |
|
19 | ThreadLooping::~ThreadLooping() |
20 | { |
21 | LOGGER.Log(Logger::VERBOSE, "Destroying ThreadLooping '{}'", m_threadName); |
22 | if (IsRunning()) |
23 | { |
24 | Terminate(); |
25 | WaitUntilFinished(); |
26 | } |
27 | } |
28 |
|
29 | void ThreadLooping::Start() |
30 | { |
31 | if (m_aIsThreadRunning.load() == false) |
32 | { |
33 | LOGGER.Log(Logger::VERBOSE, "Spawning ThreadLooping '{}'", m_threadName); |
34 | m_thread = std::thread(&ThreadLooping::ThreadRunLoop, this); |
35 | } |
36 | else |
37 | { |
38 | LOGGER.Log(Logger::WARNING, "Attempt to start ThreadLooping '{}' ignored (already started)", m_threadName); |
39 | } |
40 | } |
41 |
|
42 | void ThreadLooping::Terminate() |
43 | { |
44 | LOGGER.Log(Logger::VERBOSE, "Attempting to externally terminate ThreadLooping '{}'", m_threadName); |
45 | m_aShouldThreadTerminate.store(true); |
46 | } |
47 |
|
48 | bool ThreadLooping::IsRunning() |
49 | { |
50 | return m_thread.joinable(); |
51 | } |
52 |
|
53 | void ThreadLooping::WaitUntilFinished() |
54 | { |
55 | if (IsRunning()) |
56 | { |
57 | LOGGER.Log(Logger::VERBOSE, "Waiting for end of ThreadLooping '{}'", m_threadName); |
58 | m_thread.join(); |
59 | } |
60 | LOGGER.Log(Logger::VERBOSE, "ThreadLooping '{}' finished", m_threadName); |
61 | } |
62 |
|
63 | void ThreadLooping::ThreadRunLoop() |
64 | { |
65 | m_aIsThreadRunning.store(true); |
66 |
|
67 | while (m_aShouldThreadTerminate.load() == false) |
68 | { |
69 | bool should_exit = m_rThreadUpdate.Update(0); |
70 | if (should_exit) { break; } |
71 | } |
72 |
|
73 | m_aIsThreadRunning.store(false); |
74 | } |
75 |
|