diff --git a/simgear/debug/logstream.cxx b/simgear/debug/logstream.cxx index e459a569..e843a659 100644 --- a/simgear/debug/logstream.cxx +++ b/simgear/debug/logstream.cxx @@ -262,6 +262,7 @@ private: const char* file; const int line; const std::string message; + bool freeFilename = false; }; /** @@ -473,6 +474,10 @@ public: (*cb)(entry.debugClass, entry.debugPriority, entry.file, entry.line, entry.message); } + + if (entry.freeFilename) { + free(const_cast(entry.file)); + } } // of main thread loop } @@ -486,7 +491,7 @@ public: // log a special marker value, which will cause the thread to wakeup, // and then exit - log(SG_NONE, SG_ALERT, "done", -1, ""); + log(SG_NONE, SG_ALERT, "done", -1, "", false); } join(); @@ -551,7 +556,8 @@ public: } void log( sgDebugClass c, sgDebugPriority p, - const char* fileName, int line, const std::string& msg) + const char* fileName, int line, const std::string& msg, + bool freeFilename) { p = translatePriority(p); if (!m_fileLine) { @@ -559,6 +565,7 @@ public: line = -line; } LogEntry entry(c, p, fileName, line, msg); + entry.freeFilename = freeFilename; m_entries.push(entry); } @@ -625,7 +632,14 @@ void logstream::log( sgDebugClass c, sgDebugPriority p, const char* fileName, int line, const std::string& msg) { - d->log(c, p, fileName, line, msg); + d->log(c, p, fileName, line, msg, false); +} + +void +logstream::logCopyingFilename( sgDebugClass c, sgDebugPriority p, + const char* fileName, int line, const std::string& msg) +{ + d->log(c, p, strdup(fileName), line, msg, true); } diff --git a/simgear/debug/logstream.hxx b/simgear/debug/logstream.hxx index fef41d05..3c2ef1ad 100644 --- a/simgear/debug/logstream.hxx +++ b/simgear/debug/logstream.hxx @@ -129,6 +129,14 @@ public: void log( sgDebugClass c, sgDebugPriority p, const char* fileName, int line, const std::string& msg); + // overload of above, which can transfer ownership of the file-name. + // this is unecesary overhead when logging from C++, since __FILE__ points + // to constant data, but it's needed when the filename is Nasal data (for + // example) since during shutdown the filename is freed by Nasal GC + // asynchronously with the logging thread. + void logCopyingFilename( sgDebugClass c, sgDebugPriority p, + const char* fileName, int line, const std::string& msg); + /** * output formatted hex dump of memory block */