summaryrefslogtreecommitdiff
path: root/indra
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 /indra
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.
Diffstat (limited to 'indra')
-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) */