summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2016-08-30 16:28:21 -0400
committerNat Goodspeed <nat@lindenlab.com>2016-08-30 16:28:21 -0400
commitdcdccb3ef1b42b36042fa6f3fe61849124e1728f (patch)
treed575f09660a55c40a23eec08af31a8191981bde2
parente934e867bd76b7929b107a3174c35b00c21bac5f (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.txt3
-rw-r--r--indra/llcommon/llcleanup.cpp28
-rw-r--r--indra/llcommon/llcleanup.h7
-rw-r--r--indra/llcommon/llinitdestroyclass.cpp30
-rw-r--r--indra/llcommon/llinitdestroyclass.h59
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) */