Skip to content
Snippets Groups Projects
Commit dcdccb3e authored by Nat Goodspeed's avatar Nat Goodspeed
Browse files

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.
parent e934e867
No related branches found
No related tags found
No related merge requests found
...@@ -40,6 +40,7 @@ set(llcommon_SOURCE_FILES ...@@ -40,6 +40,7 @@ set(llcommon_SOURCE_FILES
llbase64.cpp llbase64.cpp
llbitpack.cpp llbitpack.cpp
llcallbacklist.cpp llcallbacklist.cpp
llcleanup.cpp
llcommon.cpp llcommon.cpp
llcommonutils.cpp llcommonutils.cpp
llcoros.cpp llcoros.cpp
...@@ -66,6 +67,7 @@ set(llcommon_SOURCE_FILES ...@@ -66,6 +67,7 @@ set(llcommon_SOURCE_FILES
llframetimer.cpp llframetimer.cpp
llheartbeat.cpp llheartbeat.cpp
llinitparam.cpp llinitparam.cpp
llinitdestroyclass.cpp
llinstancetracker.cpp llinstancetracker.cpp
llleap.cpp llleap.cpp
llleaplistener.cpp llleaplistener.cpp
...@@ -134,6 +136,7 @@ set(llcommon_HEADER_FILES ...@@ -134,6 +136,7 @@ set(llcommon_HEADER_FILES
llbitpack.h llbitpack.h
llboost.h llboost.h
llcallbacklist.h llcallbacklist.h
llcleanup.h
llcommon.h llcommon.h
llcommonutils.h llcommonutils.h
llcoros.h llcoros.h
......
/**
* @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;
}
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#if ! defined(LL_LLCLEANUP_H) #if ! defined(LL_LLCLEANUP_H)
#define LL_LLCLEANUP_H #define LL_LLCLEANUP_H
#include "llerror.h" #include <boost/current_function.hpp>
// Instead of directly calling SomeClass::cleanupClass(), use // Instead of directly calling SomeClass::cleanupClass(), use
// SUBSYSTEM_CLEANUP(SomeClass); // SUBSYSTEM_CLEANUP(SomeClass);
...@@ -21,10 +21,13 @@ ...@@ -21,10 +21,13 @@
// shutdown schemes. // shutdown schemes.
#define SUBSYSTEM_CLEANUP(CLASSNAME) \ #define SUBSYSTEM_CLEANUP(CLASSNAME) \
do { \ do { \
LL_INFOS("Cleanup") << "Calling " #CLASSNAME "::cleanupClass()" << LL_ENDL; \ log_subsystem_cleanup(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, #CLASSNAME); \
CLASSNAME::cleanupClass(); \ CLASSNAME::cleanupClass(); \
} while (0) } while (0)
// Use ancient do { ... } while (0) macro trick to permit a block of // Use ancient do { ... } while (0) macro trick to permit a block of
// statements with the same syntax as a single statement. // 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) */ #endif /* ! defined(LL_LLCLEANUP_H) */
/**
* @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();
}
}
...@@ -36,34 +36,35 @@ ...@@ -36,34 +36,35 @@
#if ! defined(LL_LLINITDESTROYCLASS_H) #if ! defined(LL_LLINITDESTROYCLASS_H)
#define LL_LLINITDESTROYCLASS_H #define LL_LLINITDESTROYCLASS_H
#include "llerror.h"
#include "llsingleton.h" #include "llsingleton.h"
#include <boost/function.hpp> #include <boost/function.hpp>
#include <boost/signals2/signal.hpp>
#include <typeinfo> #include <typeinfo>
#include <vector>
#include <utility> // std::pair
/** /**
* LLCallbackRegistry is an implementation detail base class for * LLCallbackRegistry is an implementation detail base class for
* LLInitClassList and LLDestroyClassList. It's a very thin wrapper around a * LLInitClassList and LLDestroyClassList. It accumulates the initClass() or
* Boost.Signals2 signal object. * destroyClass() callbacks for registered classes.
*/ */
class LLCallbackRegistry class LLCallbackRegistry
{ {
public: public:
typedef boost::signals2::signal<void()> callback_signal_t; typedef boost::function<void()> func_t;
void registerCallback(const callback_signal_t::slot_type& slot)
{
mCallbacks.connect(slot);
}
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: 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> ...@@ -108,9 +109,9 @@ template<typename T>
class LLRegisterWith class LLRegisterWith
{ {
public: 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 // this avoids a MSVC bug where non-referenced static members are "optimized" away
...@@ -141,15 +142,6 @@ class LLInitClass ...@@ -141,15 +142,6 @@ class LLInitClass
// When this static member is initialized, the subclass initClass() method // When this static member is initialized, the subclass initClass() method
// is registered on LLInitClassList. See sRegister definition below. // is registered on LLInitClassList. See sRegister definition below.
static LLRegisterWith<LLInitClassList> sRegister; 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 @@ class LLDestroyClass ...@@ -171,20 +163,17 @@ class LLDestroyClass
// method is registered on LLInitClassList. See sRegister definition // method is registered on LLInitClassList. See sRegister definition
// below. // below.
static LLRegisterWith<LLDestroyClassList> sRegister; 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. // 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. // 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) */ #endif /* ! defined(LL_LLINITDESTROYCLASS_H) */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment