I'm trying to write a really simple thread-safe logger. Ideally, I wanted it to work just like std::cout, wherein you could just overload the << operator and have everything magically show up in the log. I'm on a Windows machine, so here's the approach I tried:
// Threadsafe logger class Logger { public: Logger() { InitializeCriticalSection(&s); } ~Logger() { DeleteCriticalSection(&s); } void Log(std::ostream const& os) { EnterCriticalSection(&s); //std::cout << static_cast<std::stringstream const&>(os).str(); std::cout << os.rdbuf(); LeaveCriticalSection(&s); } private: CRITICAL_SECTION s; }; Notice that I've tried two approaches to the Log() function. The reason I accept an ostream is because that's what a stringstream seems to produce after the << operator is called. Both variants of the Log() function fail in the same way when I run this code:
#include <iostream> #include <sstream> #include <Windows.h> int main(int argc, char* argv[]) { Logger logger; //logger.Log(std::stringstream("Test")); logger.Log(std::stringstream("Another ") << "test"); std::cin.get(); } Outputting the first line ("Test") works correctly and displays properly using both variants of the Log function. The second line outputs a mangled output:
testher
which is obviously test written over Another. What am I missing about the way these streams work? I tried making a flush call hoping that would fix things, but it did nothing.
How can I get this attempt at a thread-safe logger working correctly with the streams?
Log()function.<atomic>,<mutex>, and<thread>) to solve it though since they already have the appropriate RAII sematics you want for C++.fprintf(stdout,"%s\n",(std::stringstream() << "another" << " test").str().c_str());