diff options
author | andreykproductengine <akleshchev@productengine.com> | 2017-04-25 17:48:34 +0300 |
---|---|---|
committer | andreykproductengine <akleshchev@productengine.com> | 2017-04-25 17:48:34 +0300 |
commit | 0dcb423cf3dc42e11621eece972801b036657e91 (patch) | |
tree | 88b0493918f6340d2e038b9cc0cde1cad6f493ff /indra/llcommon/llsingleton.cpp | |
parent | 288f93c7e0aa605464ddb09a3cdca504c0805c48 (diff) |
MAINT-7145 Eliminate LLSingleton circular references
Diffstat (limited to 'indra/llcommon/llsingleton.cpp')
-rw-r--r-- | indra/llcommon/llsingleton.cpp | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp index 9025e53bb2..a3a87edd88 100644 --- a/indra/llcommon/llsingleton.cpp +++ b/indra/llcommon/llsingleton.cpp @@ -220,6 +220,9 @@ void LLSingletonBase::capture_dependency(list_t& initializing, EInitState initSt std::find(initializing.begin(), initializing.end(), this); if (found != initializing.end()) { + list_t::const_iterator it_next = found; + it_next++; + // Report the circularity. Requiring the coder to dig through the // logic to diagnose exactly how we got here is less than helpful. std::ostringstream out; @@ -238,11 +241,30 @@ void LLSingletonBase::capture_dependency(list_t& initializing, EInitState initSt // otherwise we'd be returning a pointer to a partially- // constructed object! But from initSingleton() is okay: that // method exists specifically to support circularity. - // Decide which log helper to call based on initState. They have - // identical signatures. - ((initState == CONSTRUCTING)? logerrs : logwarns) - ("LLSingleton circularity: ", out.str().c_str(), - demangle(typeid(*this).name()).c_str(), ""); + // Decide which log helper to call. + if (initState == CONSTRUCTING) + { + logerrs("LLSingleton circularity in Constructor: ", out.str().c_str(), + demangle(typeid(*this).name()).c_str(), ""); + } + else if (it_next == initializing.end()) + { + // Points to self after construction, but during initialization. + // Singletons can initialize other classes that depend onto them, + // so this is expected. + // + // Example: LLNotifications singleton initializes default channels. + // Channels register themselves with singleton once done. + logdebugs("LLSingleton circularity: ", out.str().c_str(), + demangle(typeid(*this).name()).c_str(), ""); + } + else + { + // Actual circularity with other singleton (or single singleton is used extensively). + // Dependency can be unclear. + logwarns("LLSingleton circularity: ", out.str().c_str(), + demangle(typeid(*this).name()).c_str(), ""); + } } else { |