segfault using boost::thread_specific_ptr
Hello, I’m trying to implement a thread-safe logger that uses a boost::thread_specific_ptr to a std::stringstream as a logging buffer. static boost::thread_specific_ptrstd::stringstream tls_buffer; class MLoggerHandler { public: MLoggerHandler(boost::mutex& mutex, std::ostream& ostream); ~MLoggerHandler(); void setLevel(int level); template <class T> // For handling << from any object. MLoggerHandler& operator <<(T input) { std::cerr << "Adding to buffer" << std::endl; if (m_start) { *tls_buffer << localDateTime() << " " << input; <================= SEGFAULT m_start = false; } else { *tls_buffer << input; } std::cerr << "On buffer: " << tls_buffer->str() << std::endl; return *this; } // For handling std::endl std::ostream& operator <<(std::ostream& (*f)(std::ostream&)) { std::cerr << "Flushing buffer" << std::endl; m_start = true; std::ostream& rv = f(m_ostream); m_mutex.lock(); m_ostream << tls_buffer->str(); m_mutex.unlock(); tls_buffer->str(""); return rv; } private: // A flag to indicate the beginning of a new line. bool m_start = true; // A mutex passed in from the main logger for synchronization. boost::mutex& m_mutex; // The logging level. int m_level; // The output stream. std::ostream& m_ostream; // Return the current date and time as a localized string. const std::string localDateTime(); }; The initial idea, was to flush the buffer and write when a terminating std::endl was encountered. But, just trying to dereference the pointer and write to the std::stringstream is crashing. Do I need to initialize the std::stringstream, or is it initialized in constructor? Thanks, Mike
tls_buffer is not initialized, thread_specific_ptr will not allocate memory for you (it will call delete on thread exit tough) if (!tls_buffer) { tls_buffer.reset(new std::stringstream()); } The previous must be done before any attempt to use that variable On Mon, Dec 21, 2015 at 11:34 AM, Michael P. Soulier < msoulier@digitaltorque.ca> wrote:
Hello,
I’m trying to implement a thread-safe logger that uses a boost::thread_specific_ptr to a std::stringstream as a logging buffer.
static boost::thread_specific_ptrstd::stringstream tls_buffer;
class MLoggerHandler { public: MLoggerHandler(boost::mutex& mutex, std::ostream& ostream); ~MLoggerHandler(); void setLevel(int level);
template <class T> // For handling << from any object. MLoggerHandler& operator <<(T input) { std::cerr << "Adding to buffer" << std::endl; if (m_start) { *tls_buffer << localDateTime() << " " << input; <================= SEGFAULT m_start = false; } else { *tls_buffer << input; } std::cerr << "On buffer: " << tls_buffer->str() << std::endl; return *this; } // For handling std::endl std::ostream& operator <<(std::ostream& (*f)(std::ostream&)) { std::cerr << "Flushing buffer" << std::endl; m_start = true; std::ostream& rv = f(m_ostream); m_mutex.lock(); m_ostream << tls_buffer->str(); m_mutex.unlock(); tls_buffer->str(""); return rv; } private: // A flag to indicate the beginning of a new line. bool m_start = true; // A mutex passed in from the main logger for synchronization. boost::mutex& m_mutex; // The logging level. int m_level; // The output stream. std::ostream& m_ostream; // Return the current date and time as a localized string. const std::string localDateTime(); };
The initial idea, was to flush the buffer and write when a terminating std::endl was encountered. But, just trying to dereference the pointer and write to the std::stringstream is crashing. Do I need to initialize the std::stringstream, or is it initialized in constructor?
Thanks, Mike _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Juan :wq
Ah thanks. I had to change the check to if (! tls_buffer.get()) or In file included from ./EventWorker.h:13: ./Util.h:85:13: error: invalid argument type 'boost::thread_specific_ptrstd::stringstream' to unary expression if (! tls_buffer) { ^ ~~~~~~~~~~ 1 error generated. make: *** [EventWorker.o] Error 1 but it seems to work now. Mike
On Dec 21, 2015, at 10:04 AM, Juan Ramírez
wrote: tls_buffer is not initialized, thread_specific_ptr will not allocate memory for you (it will call delete on thread exit tough)
if (!tls_buffer) { tls_buffer.reset(new std::stringstream()); }
The previous must be done before any attempt to use that variable
On Mon, Dec 21, 2015 at 11:34 AM, Michael P. Soulier
wrote: Hello, I’m trying to implement a thread-safe logger that uses a boost::thread_specific_ptr to a std::stringstream as a logging buffer.
static boost::thread_specific_ptrstd::stringstream tls_buffer;
class MLoggerHandler { public: MLoggerHandler(boost::mutex& mutex, std::ostream& ostream); ~MLoggerHandler(); void setLevel(int level);
template <class T> // For handling << from any object. MLoggerHandler& operator <<(T input) { std::cerr << "Adding to buffer" << std::endl; if (m_start) { *tls_buffer << localDateTime() << " " << input; <================= SEGFAULT m_start = false; } else { *tls_buffer << input; } std::cerr << "On buffer: " << tls_buffer->str() << std::endl; return *this; } // For handling std::endl std::ostream& operator <<(std::ostream& (*f)(std::ostream&)) { std::cerr << "Flushing buffer" << std::endl; m_start = true; std::ostream& rv = f(m_ostream); m_mutex.lock(); m_ostream << tls_buffer->str(); m_mutex.unlock(); tls_buffer->str(""); return rv; } private: // A flag to indicate the beginning of a new line. bool m_start = true; // A mutex passed in from the main logger for synchronization. boost::mutex& m_mutex; // The logging level. int m_level; // The output stream. std::ostream& m_ostream; // Return the current date and time as a localized string. const std::string localDateTime(); };
The initial idea, was to flush the buffer and write when a terminating std::endl was encountered. But, just trying to dereference the pointer and write to the std::stringstream is crashing. Do I need to initialize the std::stringstream, or is it initialized in constructor?
Thanks, Mike _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Juan :wq
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
yeah, sorry for that! I was writing from memory :P On Mon, Dec 21, 2015 at 3:24 PM, Michael P. Soulier < msoulier@digitaltorque.ca> wrote:
Ah thanks. I had to change the check to if (! tls_buffer.get()) or
In file included from ./EventWorker.h:13: ./Util.h:85:13: error: invalid argument type 'boost::thread_specific_ptrstd::stringstream' to unary expression if (! tls_buffer) { ^ ~~~~~~~~~~ 1 error generated. make: *** [EventWorker.o] Error 1
but it seems to work now.
Mike
On Dec 21, 2015, at 10:04 AM, Juan Ramírez
wrote: tls_buffer is not initialized, thread_specific_ptr will not allocate memory for you (it will call delete on thread exit tough)
if (!tls_buffer) { tls_buffer.reset(new std::stringstream()); }
The previous must be done before any attempt to use that variable
On Mon, Dec 21, 2015 at 11:34 AM, Michael P. Soulier < msoulier@digitaltorque.ca> wrote: Hello,
I’m trying to implement a thread-safe logger that uses a boost::thread_specific_ptr to a std::stringstream as a logging buffer.
static boost::thread_specific_ptrstd::stringstream tls_buffer;
class MLoggerHandler { public: MLoggerHandler(boost::mutex& mutex, std::ostream& ostream); ~MLoggerHandler(); void setLevel(int level);
template <class T> // For handling << from any object. MLoggerHandler& operator <<(T input) { std::cerr << "Adding to buffer" << std::endl; if (m_start) { *tls_buffer << localDateTime() << " " << input; <================= SEGFAULT m_start = false; } else { *tls_buffer << input; } std::cerr << "On buffer: " << tls_buffer->str() << std::endl; return *this; } // For handling std::endl std::ostream& operator <<(std::ostream& (*f)(std::ostream&)) { std::cerr << "Flushing buffer" << std::endl; m_start = true; std::ostream& rv = f(m_ostream); m_mutex.lock(); m_ostream << tls_buffer->str(); m_mutex.unlock(); tls_buffer->str(""); return rv; } private: // A flag to indicate the beginning of a new line. bool m_start = true; // A mutex passed in from the main logger for synchronization. boost::mutex& m_mutex; // The logging level. int m_level; // The output stream. std::ostream& m_ostream; // Return the current date and time as a localized string. const std::string localDateTime(); };
The initial idea, was to flush the buffer and write when a terminating std::endl was encountered. But, just trying to dereference the pointer and write to the std::stringstream is crashing. Do I need to initialize the std::stringstream, or is it initialized in constructor?
Thanks, Mike _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Juan :wq
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Juan :wq
participants (2)
-
Juan Ramírez
-
Michael P. Soulier