From 09586d760833dac680ba8837b0b695ed3900c96d Mon Sep 17 00:00:00 2001 From: Mihai Moldovan Date: Sat, 30 Sep 2017 15:30:53 +0200 Subject: nxcomp/src/Log.{cpp,h}: port to std::stack as internal buffer structure. This has one drawback: after flushing log data to its underlying output, a new NXLogStamp object MUST be written to the NXLog object in order to create a new entry within the stack. This can be changed if necessary. For now I'd like to keep it as-is. --- nxcomp/src/Log.cpp | 8 +++----- nxcomp/src/Log.h | 52 ++++++++++++++++++++++++++++++++++------------------ 2 files changed, 37 insertions(+), 23 deletions(-) diff --git a/nxcomp/src/Log.cpp b/nxcomp/src/Log.cpp index 66ae1bd78..83e11b98a 100644 --- a/nxcomp/src/Log.cpp +++ b/nxcomp/src/Log.cpp @@ -109,14 +109,12 @@ NXLog& operator<< (NXLog& out, const NXLogStamp& value) out.current_file( value.file() ); // Writing an NXLogStamp to the stream indicates the start of a new entry. - // If there's any content in the buffer, we flush it to finalize the previous - // log entry. + // If there's any content in the buffer, create a new entry in the output + // queue. if ( out.synchronized() ) - out.flush(); - + out.new_stack_entry(); out << out.stamp_to_string(value); return out; } - diff --git a/nxcomp/src/Log.h b/nxcomp/src/Log.h index 44c43a47b..ecc6ea9ed 100644 --- a/nxcomp/src/Log.h +++ b/nxcomp/src/Log.h @@ -35,6 +35,8 @@ #include #include #include +#include +#include /** Log severity level */ enum NXLogLevel @@ -138,11 +140,11 @@ class NXLog typedef struct per_thread_data_s { - NXLogLevel current_level; - std::string* current_file; - std::string* thread_name; - std::stringstream* buffer; - NXLog* log_obj; + NXLogLevel current_level; + std::string* current_file; + std::string* thread_name; + std::stack buffer; + NXLog* log_obj; } per_thread_data; @@ -160,7 +162,11 @@ class NXLog delete pdt->current_file; delete pdt->thread_name; - delete pdt->buffer; + + while (!pdt->buffer.empty()) { + (void) pdt->buffer.pop (); + } + delete pdt; } @@ -172,7 +178,6 @@ class NXLog { ret = new per_thread_data; ret->current_level = NXDEBUG; - ret->buffer = new std::stringstream(); ret->current_file = new std::string(); ret->thread_name = new std::string(); ret->log_obj = const_cast(this); @@ -195,6 +200,12 @@ class NXLog /** Convert NXLogStamp to string according to the current configuration */ std::string stamp_to_string(const NXLogStamp& stamp) const; + void new_stack_entry() + { + per_thread_data *pdt = get_data(); + pdt->buffer.push(new std::stringstream()); + } + /** * Internal flush function * @@ -207,15 +218,18 @@ class NXLog */ void flush(per_thread_data *pdt) { - const std::string str = pdt->buffer->str(); + if (!pdt->buffer.empty ()) { + const std::string str = pdt->buffer.top()->str(); - if (!str.empty()) - { - pthread_mutex_lock(&output_lock_); - (*stream()) << str; - pthread_mutex_unlock(&output_lock_); - pdt->buffer->str(std::string()); - pdt->buffer->clear(); + if (!str.empty()) + { + pthread_mutex_lock(&output_lock_); + (*stream()) << str; + pthread_mutex_unlock(&output_lock_); + } + + /* Remove from stack. */ + pdt->buffer.pop(); } } @@ -404,7 +418,8 @@ class NXLog if ( synchronized() ) { per_thread_data *pdt = get_data(); - (*pdt->buffer) << F; + assert (!pdt->buffer.empty ()); + (*pdt->buffer.top()) << F; flush(); } else @@ -484,9 +499,10 @@ NXLog& operator<<(NXLog& out, const T& value) // gets full. Then we dump the whole thing at once to the output stream, synchronizing // with a mutex. NXLog::per_thread_data *pdt = out.get_data(); - (*pdt->buffer) << value; + assert (!pdt->buffer.empty ()); + (*pdt->buffer.top()) << value; - if ( ss_length(pdt->buffer) >= out.thread_buffer_size_ || has_newline(value) ) + if ( ss_length(pdt->buffer.top()) >= out.thread_buffer_size_ || has_newline(value) ) out.flush(); } -- cgit v1.2.3