diff options
author | Nat Goodspeed <nat@lindenlab.com> | 2016-08-30 16:28:21 -0400 |
---|---|---|
committer | Nat Goodspeed <nat@lindenlab.com> | 2016-08-30 16:28:21 -0400 |
commit | dcdccb3ef1b42b36042fa6f3fe61849124e1728f (patch) | |
tree | d575f09660a55c40a23eec08af31a8191981bde2 | |
parent | e934e867bd76b7929b107a3174c35b00c21bac5f (diff) |
MAINT-5232: Move "llerror.h" out of llcleanup.h, llinitdestroyclass.h
Introduce corresponding llcleanup.cpp, llinitdestroyclass.cpp modules to
contain code that performs logging calls.
Track class::method names for LLInitClass<T> and LLDestroyClass<T> subclasses,
and log them when called. The order in which these calls occur could be
relevant to bugs, and could surface the need to convert to LLSingleton
dependencies.
-rw-r--r-- | indra/llcommon/CMakeLists.txt | 3 | ||||
-rw-r--r-- | indra/llcommon/llcleanup.cpp | 28 | ||||
-rw-r--r-- | indra/llcommon/llcleanup.h | 7 | ||||
-rw-r--r-- | indra/llcommon/llinitdestroyclass.cpp | 30 | ||||
-rw-r--r-- | indra/llcommon/llinitdestroyclass.h | 59 |
5 files changed, 90 insertions, 37 deletions
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 556f879634..e1261ee17d 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -40,6 +40,7 @@ set(llcommon_SOURCE_FILES llbase64.cpp llbitpack.cpp llcallbacklist.cpp + llcleanup.cpp llcommon.cpp llcommonutils.cpp llcoros.cpp @@ -66,6 +67,7 @@ set(llcommon_SOURCE_FILES llframetimer.cpp llheartbeat.cpp llinitparam.cpp + llinitdestroyclass.cpp llinstancetracker.cpp llleap.cpp llleaplistener.cpp @@ -134,6 +136,7 @@ set(llcommon_HEADER_FILES llbitpack.h llboost.h llcallbacklist.h + llcleanup.h llcommon.h llcommonutils.h llcoros.h diff --git a/indra/llcommon/llcleanup.cpp b/indra/llcommon/llcleanup.cpp new file mode 100644 index 0000000000..f45f4925ce --- /dev/null +++ b/indra/llcommon/llcleanup.cpp @@ -0,0 +1,28 @@ +/** + * @file llcleanup.cpp + * @author Nat Goodspeed + * @date 2016-08-30 + * @brief Implementation for llcleanup. + * + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Copyright (c) 2016, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "llcleanup.h" +// STL headers +// std headers +// external library headers +// other Linden headers +#include "llerror.h" + +void log_subsystem_cleanup(const char* file, int line, const char* function, + const char* classname) +{ + LL_INFOS("Cleanup") << file << "(" << line << "): calling " + << classname << "::cleanupClass() in " + << function << LL_ENDL; +} diff --git a/indra/llcommon/llcleanup.h b/indra/llcommon/llcleanup.h index 8eda9a7fb3..a319171b5f 100644 --- a/indra/llcommon/llcleanup.h +++ b/indra/llcommon/llcleanup.h @@ -12,7 +12,7 @@ #if ! defined(LL_LLCLEANUP_H) #define LL_LLCLEANUP_H -#include "llerror.h" +#include <boost/current_function.hpp> // Instead of directly calling SomeClass::cleanupClass(), use // SUBSYSTEM_CLEANUP(SomeClass); @@ -21,10 +21,13 @@ // shutdown schemes. #define SUBSYSTEM_CLEANUP(CLASSNAME) \ do { \ - LL_INFOS("Cleanup") << "Calling " #CLASSNAME "::cleanupClass()" << LL_ENDL; \ + log_subsystem_cleanup(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, #CLASSNAME); \ CLASSNAME::cleanupClass(); \ } while (0) // Use ancient do { ... } while (0) macro trick to permit a block of // statements with the same syntax as a single statement. +void log_subsystem_cleanup(const char* file, int line, const char* function, + const char* classname); + #endif /* ! defined(LL_LLCLEANUP_H) */ diff --git a/indra/llcommon/llinitdestroyclass.cpp b/indra/llcommon/llinitdestroyclass.cpp new file mode 100644 index 0000000000..e6382a7924 --- /dev/null +++ b/indra/llcommon/llinitdestroyclass.cpp @@ -0,0 +1,30 @@ +/** + * @file llinitdestroyclass.cpp + * @author Nat Goodspeed + * @date 2016-08-30 + * @brief Implementation for llinitdestroyclass. + * + * $LicenseInfo:firstyear=2016&license=viewerlgpl$ + * Copyright (c) 2016, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" +// associated header +#include "llinitdestroyclass.h" +// STL headers +// std headers +// external library headers +// other Linden headers +#include "llerror.h" + +void LLCallbackRegistry::fireCallbacks() const +{ + for (FuncList::const_iterator fi = mCallbacks.begin(), fe = mCallbacks.end(); + fi != fe; ++fi) + { + LL_INFOS("LLInitDestroyClass") << "calling " << fi->first << "()" << LL_ENDL; + fi->second(); + } +} diff --git a/indra/llcommon/llinitdestroyclass.h b/indra/llcommon/llinitdestroyclass.h index 49bcefc33d..9c66211475 100644 --- a/indra/llcommon/llinitdestroyclass.h +++ b/indra/llcommon/llinitdestroyclass.h @@ -36,34 +36,35 @@ #if ! defined(LL_LLINITDESTROYCLASS_H) #define LL_LLINITDESTROYCLASS_H -#include "llerror.h" #include "llsingleton.h" #include <boost/function.hpp> -#include <boost/signals2/signal.hpp> #include <typeinfo> +#include <vector> +#include <utility> // std::pair /** * LLCallbackRegistry is an implementation detail base class for - * LLInitClassList and LLDestroyClassList. It's a very thin wrapper around a - * Boost.Signals2 signal object. + * LLInitClassList and LLDestroyClassList. It accumulates the initClass() or + * destroyClass() callbacks for registered classes. */ class LLCallbackRegistry { public: - typedef boost::signals2::signal<void()> callback_signal_t; - - void registerCallback(const callback_signal_t::slot_type& slot) - { - mCallbacks.connect(slot); - } + typedef boost::function<void()> func_t; - void fireCallbacks() + void registerCallback(const std::string& name, const func_t& func) { - mCallbacks(); + mCallbacks.push_back(FuncList::value_type(name, func)); } + void fireCallbacks() const; + private: - callback_signal_t mCallbacks; + // Arguably this should be a boost::signals2::signal, which is, after all, + // a sequence of callables. We manage it by hand so we can log a name for + // each registered function we call. + typedef std::vector< std::pair<std::string, func_t> > FuncList; + FuncList mCallbacks; }; /** @@ -108,9 +109,9 @@ template<typename T> class LLRegisterWith { public: - LLRegisterWith(boost::function<void ()> func) + LLRegisterWith(const std::string& name, const LLCallbackRegistry::func_t& func) { - T::instance().registerCallback(func); + T::instance().registerCallback(name, func); } // this avoids a MSVC bug where non-referenced static members are "optimized" away @@ -141,15 +142,6 @@ public: // When this static member is initialized, the subclass initClass() method // is registered on LLInitClassList. See sRegister definition below. static LLRegisterWith<LLInitClassList> sRegister; -private: - - // Provide a default initClass() method in case subclass misspells (or - // omits) initClass(). This turns a potential build error into a fatal - // runtime error. - static void initClass() - { - LL_ERRS() << "No static initClass() method defined for " << typeid(T).name() << LL_ENDL; - } }; /** @@ -171,20 +163,17 @@ public: // method is registered on LLInitClassList. See sRegister definition // below. static LLRegisterWith<LLDestroyClassList> sRegister; -private: - - // Provide a default destroyClass() method in case subclass misspells (or - // omits) destroyClass(). This turns a potential build error into a fatal - // runtime error. - static void destroyClass() - { - LL_ERRS() << "No static destroyClass() method defined for " << typeid(T).name() << LL_ENDL; - } }; // Here's where LLInitClass<T> specifies the subclass initClass() method. -template <typename T> LLRegisterWith<LLInitClassList> LLInitClass<T>::sRegister(&T::initClass); +template <typename T> +LLRegisterWith<LLInitClassList> +LLInitClass<T>::sRegister(std::string(typeid(T).name()) + "::initClass", + &T::initClass); // Here's where LLDestroyClass<T> specifies the subclass destroyClass() method. -template <typename T> LLRegisterWith<LLDestroyClassList> LLDestroyClass<T>::sRegister(&T::destroyClass); +template <typename T> +LLRegisterWith<LLDestroyClassList> +LLDestroyClass<T>::sRegister(std::string(typeid(T).name()) + "::destroyClass", + &T::destroyClass); #endif /* ! defined(LL_LLINITDESTROYCLASS_H) */ |