From a86bdcfe3f9bfc832ac409701888539229d21f16 Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 3 Aug 2019 10:34:11 +0200 Subject: [PATCH] notify: support setting notify-output after static init time Previously it was only possible to set this in the default-loaded Config.prc file; now it is possible to set this at any time, though it can only be set once from its default value and not changed after it has already been set to something other than the default value. --- dtool/src/prc/notify.cxx | 24 +++++++++++++----------- dtool/src/prc/notifyCategory.cxx | 6 ++++++ 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/dtool/src/prc/notify.cxx b/dtool/src/prc/notify.cxx index f9c39135e8..690910ef4a 100644 --- a/dtool/src/prc/notify.cxx +++ b/dtool/src/prc/notify.cxx @@ -19,6 +19,7 @@ #include "filename.h" #include "config_prc.h" +#include #include #ifdef BUILD_IPHONE @@ -422,28 +423,29 @@ string_severity(const string &str) { */ void Notify:: config_initialized() { - static bool already_initialized = false; - if (already_initialized) { - nout << "Notify::config_initialized() called more than once.\n"; - return; - } - already_initialized = true; + // We allow this to be called more than once to allow the user to specify a + // notify-output even after the initial import of Panda3D modules. However, + // it cannot be changed after the first time it is set. if (_ostream_ptr == &cerr) { - ConfigVariableFilename notify_output + static ConfigVariableFilename notify_output ("notify-output", "", "The filename to which to write all the output of notify"); - if (!notify_output.empty()) { - if (notify_output == "stdout") { + // We use this to ensure that only one thread can initialize the output. + static std::atomic_flag initialized = ATOMIC_FLAG_INIT; + + std::string value = notify_output.get_value(); + if (!value.empty() && !initialized.test_and_set()) { + if (value == "stdout") { cout.setf(std::ios::unitbuf); set_ostream_ptr(&cout, false); - } else if (notify_output == "stderr") { + } else if (value == "stderr") { set_ostream_ptr(&cerr, false); } else { - Filename filename = notify_output; + Filename filename = value; filename.set_text(); #ifdef BUILD_IPHONE // On the iPhone, route everything through cerr, and then send cerr to diff --git a/dtool/src/prc/notifyCategory.cxx b/dtool/src/prc/notifyCategory.cxx index 3d856ceb08..86bf63f736 100644 --- a/dtool/src/prc/notifyCategory.cxx +++ b/dtool/src/prc/notifyCategory.cxx @@ -181,10 +181,16 @@ update_severity_cache() { } else { // Unless, of course, we're the root. _severity_cache = NS_info; + + // Take this opportunity to have Notify check whether the notify-output + // variable changed. + Notify::ptr()->config_initialized(); } } else { _severity_cache = _severity; + Notify::ptr()->config_initialized(); } + mark_cache_valid(_local_modified); }