-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathlogger.cpp
More file actions
112 lines (88 loc) · 2.34 KB
/
logger.cpp
File metadata and controls
112 lines (88 loc) · 2.34 KB
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include "logger.h"
using namespace Simulator;
Logger::~Logger()
{
requestStop();
waitForStop();
}
bool Logger::start(const std::string& log_file_name, std::string& out_error_message)
{
out_error_message.clear();
std::lock_guard lock(m_worker_thread_mutex);
if (m_worker_thread_state != ThreadState::STOPPED) {
out_error_message = "Log file is already open.";
return false;
}
if (m_worker_thread.joinable()) {
m_worker_thread.join();
}
m_file.open(log_file_name, std::ofstream::out | std::ofstream::trunc);
if (!m_file.is_open()) {
out_error_message = "Failed to create log file.";
return false;
}
m_worker_thread_state = ThreadState::STARTING;
m_worker_thread = std::thread(logProcess, this);
return true;
}
void Logger::logWrite(const std::string& message)
{
{
std::lock_guard lock(m_worker_thread_mutex);
if (m_worker_thread_state != ThreadState::RUNNING) {
return;
}
m_message_fifo.push(message);
}
m_worker_thread_wait_variable.notify_all();
}
void Logger::requestStop()
{
{
std::lock_guard lock(m_worker_thread_mutex);
if ((m_worker_thread_state == ThreadState::STOPPING) ||
(m_worker_thread_state == ThreadState::STOPPED)) {
return;
}
m_worker_thread_state = ThreadState::STOPPING;
}
m_worker_thread_wait_variable.notify_all();
}
void Logger::waitForStop()
{
std::unique_lock<std::mutex> lock(m_worker_thread_mutex);
m_stop_wait_variable.wait(lock,
[=]()
{
return (m_worker_thread_state == ThreadState::STOPPED);
}
);
if (m_worker_thread.joinable()) {
m_worker_thread.join();
}
}
void Logger::logProcess(Logger* logger)
{
while (true) {
std::unique_lock<std::mutex> lock(logger->m_worker_thread_mutex);
logger->m_worker_thread_wait_variable.wait(lock,
[logger]()
{
return (!logger->m_message_fifo.empty()) || (logger->m_worker_thread_state != ThreadState::RUNNING);
}
);
if (logger->m_worker_thread_state == ThreadState::STARTING) {
logger->m_worker_thread_state = ThreadState::RUNNING;
}
if (!logger->m_message_fifo.empty()) {
logger->m_file << logger->m_message_fifo.front() << std::endl;
logger->m_message_fifo.pop();
}
if (logger->m_message_fifo.empty() && (logger->m_worker_thread_state != ThreadState::RUNNING)) {
logger->m_worker_thread_state = ThreadState::STOPPED;
lock.unlock();
logger->m_stop_wait_variable.notify_all();
return;
}
}
}