From: <sv...@ww...> - 2004-06-27 17:57:16
|
Author: mkrose Date: 2004-06-27 10:57:10 -0700 (Sun, 27 Jun 2004) New Revision: 1079 Modified: trunk/CSP/SimData/CHANGES.current trunk/CSP/SimData/Include/SimData/ThreadLog.h Log: Clean up base class construction of ThreadLog, removing suspect references to 'this' in ctor initializer list. Browse at: https://www.zerobar.net/viewcvs/viewcvs.cgi?view=rev&rev=1079 Modified: trunk/CSP/SimData/CHANGES.current =================================================================== --- trunk/CSP/SimData/CHANGES.current 2004-06-27 17:34:40 UTC (rev 1078) +++ trunk/CSP/SimData/CHANGES.current 2004-06-27 17:57:10 UTC (rev 1079) @@ -6,6 +6,9 @@ * Added ThreadLog.h to setup.py + * Clean up base class construction of ThreadLog, removing suspect + references to 'this' in ctor initializer list. + 2004-06-26: onsight * Remove superflous logging in interface registry, and suppress swig warnings. Modified: trunk/CSP/SimData/Include/SimData/ThreadLog.h =================================================================== --- trunk/CSP/SimData/Include/SimData/ThreadLog.h 2004-06-27 17:34:40 UTC (rev 1078) +++ trunk/CSP/SimData/Include/SimData/ThreadLog.h 2004-06-27 17:57:10 UTC (rev 1079) @@ -52,17 +52,16 @@ int m_priority; const char *m_file; int m_line; + LogStream &m_log; void init() { m_buffer.reserve(1024); } -protected: - - // accessed directly by ThreadLog - LogStream &m_log; typedef ScopedLock<LogStream> ScopedLogLock; +public: + /** Default constructor, connects to the global simdata log. */ StringBuf(): m_category(LOG_ALL), m_priority(LOG_INFO), m_file(0), m_line(0), m_log(::simdata::log()) { @@ -75,6 +74,21 @@ init(); } + /** Cache the log entry parameters. + */ + inline void setPrefix(int priority, int category, const char *file, int line) { + m_priority = priority; + m_category = category; + m_file = file; + m_line = line; + } + + /** Retrieve the associated LogStream. + */ + inline LogStream &getLogStream() const { return m_log; } + +protected: + /** Overflow (cache characters internally) */ virtual int overflow(int c) { @@ -93,96 +107,111 @@ return 1; } - /** Cache the log entry parameters. - */ - inline void setPrefix(int priority, int category, const char *file, int line) { - m_priority = priority; - m_category = category; - m_file = file; - m_line = line; - } }; +/** A helper class for ThreadLog construction. + * + * A helper class that ensures a streambuf and ostream are constructed and + * destroyed in the correct order. The streambuf must be created before the + * ostream but bases are constructed before members. Thus, making this class + * a private base of ThreadLog, declared to the left of ostream, we ensure the + * correct order of construction and destruction. + */ +struct SIMDATA_EXPORT ThreadLogBase: public NonCopyable +{ +protected: + ThreadLogBase(): m_stringbuf() {} + ThreadLogBase(LogStream &base): m_stringbuf(base) {} + virtual ~ThreadLogBase() { } + + inline LogStream &getLogStream() const { return m_stringbuf.getLogStream(); } + + StringBuf m_stringbuf; +}; + + /** A thread-safe logging class that provides serialized access to an * underlying LogStream instance. The public interface is the same as * LogStream, and the logging macro as defined to use thread-specific * ThreadLog instances instead of the global LogStream whenever threading * is enabled. */ -class SIMDATA_EXPORT ThreadLog: private StringBuf, protected std::ostream +class SIMDATA_EXPORT ThreadLog: private ThreadLogBase, protected std::ostream { + typedef ScopedLock<LogStream> ScopedLogLock; + public: /** Default constructor, connects to the global simdata log. */ - ThreadLog(): std::ostream(this) {} + ThreadLog(): ThreadLogBase(), std::ostream(&m_stringbuf) {} /** Constructor, connects to the specified LogStream */ - ThreadLog(LogStream &base): StringBuf(base), std::ostream(this) {} + ThreadLog(LogStream &base): ThreadLogBase(base), std::ostream(&m_stringbuf) {} /** Close the underlying (shared) LogStream. */ void _close() { - ScopedLogLock lock(m_log); - m_log._close(); + ScopedLogLock lock(getLogStream()); + getLogStream()._close(); } /** Set the output stream used by the underlying (shared) LogStream. */ void setOutput(std::ostream& out_) { - ScopedLogLock lock(m_log); - m_log.setOutput(out_); + ScopedLogLock lock(getLogStream()); + getLogStream().setOutput(out_); } /** Set the output file used by the underlying (shared) LogStream. */ void setOutput(std::string const &filename) { - ScopedLogLock lock(m_log); - m_log.setOutput(filename); + ScopedLogLock lock(getLogStream()); + getLogStream().setOutput(filename); } /** Set the logging priority threshold of the underlying (shared) LogStream. */ void setLogPriority(int p) { - ScopedLogLock lock(m_log); - m_log.setLogPriority(p); + ScopedLogLock lock(getLogStream()); + getLogStream().setLogPriority(p); } /** Set the logging category mask of the underlying (shared) LogStream. */ void setLogCategory(int c) { - ScopedLogLock lock(m_log); - m_log.setLogCategory(c); + ScopedLogLock lock(getLogStream()); + getLogStream().setLogCategory(c); } /** Enable or disable point logging (source file and line number) by the * underlying (shared) LogStream. */ void setPointLogging(bool enabled) { - ScopedLogLock lock(m_log); - m_log.setPointLogging(enabled); + ScopedLogLock lock(getLogStream()); + getLogStream().setPointLogging(enabled); } /** Get the point logging state of the underlying (shared) LogStream. */ bool getPointLogging() const { - return m_log.getPointLogging(); + return getLogStream().getPointLogging(); } /** Enable or disable time stamping of log entries written to the * underlying (shared) LogStream. */ void setTimeLogging(bool enabled) { - ScopedLogLock lock(m_log); - m_log.setTimeLogging(enabled); + ScopedLogLock lock(getLogStream()); + getLogStream().setTimeLogging(enabled); } /** Get the time logging state of the underlying (shared) LogStream. */ bool getTimeLogging() const { - return m_log.getTimeLogging(); + return getLogStream().getTimeLogging(); } /** Method for logging a message to the underlying (shared) LogStream. @@ -194,7 +223,7 @@ * @return an output stream to receive the message contents. */ std::ostream & entry(int priority, int category=LOG_ALL, const char *file=0, int line=0) { - setPrefix(priority, category, file, line); + m_stringbuf.setPrefix(priority, category, file, line); return *this; } |