Skip to content

Commit 398701a

Browse files
committed
logger: make logger thread-safe
Current logger implementation is not thread-safe, so the commit rewrites it. Firstly, `localtime` is not thread-safe since it uses a static biffer under the hood. TODO...
1 parent ac10240 commit 398701a

File tree

1 file changed

+22
-13
lines changed

1 file changed

+22
-13
lines changed

src/Utils/Logger.hpp

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232

3333
#include <time.h>
3434

35-
#include <iostream>
35+
#include <sstream>
3636
#include <string_view>
3737

3838
enum LogLevel {
@@ -66,23 +66,32 @@ class Logger {
6666
Logger(LogLevel lvl) : m_LogLvl(lvl) {};
6767

6868
template <class... ARGS>
69-
void log(std::ostream& strm, LogLevel log_lvl,
70-
const char *file, int line, ARGS&& ...args)
69+
void log(int fd, LogLevel log_lvl, const char *file,
70+
int line, ARGS&& ...args)
7171
{
7272
if (!isLogPossible(log_lvl))
7373
return;
74-
time_t rawTime;
75-
time(&rawTime);
76-
struct tm *timeInfo = localtime(&rawTime);
77-
char timeString[10];
78-
strftime(timeString, sizeof(timeString), "%H:%M:%S", timeInfo);
79-
// The line below is commented for compatibility with previous
80-
// version. I'm not sure it was bug or feature, but the time,
81-
// filename and line was not printed.
74+
/* File and line were never printed (by mistake, I guess). */
8275
(void)file; (void)line;
83-
//strm << timeString << " " << file << ':' << line << ' ';
76+
/*
77+
* Standard streams (`cout` and `cerr`) are thread-safe
78+
* according to C++11 or more modern standards, but it turns
79+
* out that some compilers do not stick to this contract.
80+
*
81+
* Let's use `stringstream` to build a string and then write
82+
* it manually with `write` since it is guaranteed to be
83+
* thread-safe. Yes, that's slower because of unnnecessary
84+
* allocations and copies, but the log is used generally for
85+
* debug or logging exceptional cases (errors) anyway, so
86+
* that's not a big deal.
87+
*
88+
* Related: https://github.com/llvm/llvm-project/issues/51851
89+
*/
90+
std::stringstream strm;
8491
strm << log_lvl << ": ";
8592
(strm << ... << std::forward<ARGS>(args)) << '\n';
93+
std::string str = strm.str();
94+
(void)write(fd, std::data(str), std::size(str));
8695
}
8796
void setLogLevel(LogLevel lvl)
8897
{
@@ -106,7 +115,7 @@ template <class... ARGS>
106115
void
107116
log(LogLevel level, const char *file, int line, ARGS&& ...args)
108117
{
109-
gLogger.log(level == ERROR ? std::cerr : std::cout,
118+
gLogger.log(level == ERROR ? STDERR_FILENO : STDOUT_FILENO,
110119
level, file, line, std::forward<ARGS>(args)...);
111120
}
112121

0 commit comments

Comments
 (0)