Skip to content
Snippets Groups Projects
  1. Apr 09, 2020
  2. Aug 20, 2019
    • Nat Goodspeed's avatar
      DRTVWR-493: Clarify capturing LLError::getFatalFunction() in a var. · 5b5eb55f
      Nat Goodspeed authored
      VS 2013 thought we were storing an initialization-list.
      5b5eb55f
    • Nat Goodspeed's avatar
      DRTVWR-493: Defend LL[Param]Singleton against ctor/init exceptions. · 54b98cb8
      Nat Goodspeed authored
      An exception in the LLSingleton subclass constructor, or in its
      initSingleton() method, could leave the LLSingleton machinery in a bad state:
      the failing instance would remain in the MasterList, also on the stack of
      initializing LLSingletons. Catch exceptions in either and perform relevant
      cleanup.
      
      This problem is highlighted by test programs, in which LL_ERRS throws an
      exception rather than crashing the whole process.
      
      In the relevant catch clauses, clean up the initializing stack BEFORE logging.
      Otherwise we get tangled up recording bogus dependencies.
      
      Move capture_dependency() out of finishInitializing(): it must be called by
      every valid getInstance() call, both from LLSingleton and LLParamSingleton.
      
      Introduce new CONSTRUCTED EInitState value to distinguish "have called the
      constructor but not yet the initSingleton() method" from "currently within
      initSingleton() method." This is transient, but we execute the 'switch' on
      state within that moment. One could argue that the previous enum used
      INITIALIZING for current CONSTRUCTED, and INITIALIZED meant INITIALIZING too,
      but this is clearer.
      
      Introduce template LLSingletonBase::classname() helper methods to clarify
      verbose demangle(typeid(stuff).name()) calls.
      
      Similarly, introduce LLSingleton::pop_initializing() shorthand method.
      54b98cb8
  3. Aug 19, 2019
    • Nat Goodspeed's avatar
      DRTVWR-493: Improve exception safety of LLSingleton initialization. · 310db14b
      Nat Goodspeed authored
      Add try/catch clauses to constructSingleton() (to catch exceptions in the
      subclass constructor) and finishInitializing() (to catch exceptions in the
      subclass initSingleton() method). Each of these catch clauses rethrows the
      exception -- they're for cleanup, not for ultimate handling.
      
      Introduce LLSingletonBase::reset_initializing(list_t::size_t). The idea is
      that since we can't know whether the exception happened before or after the
      push_initializing() call in LLSingletonBase's constructor, we can't just pop
      the stack. Instead, constructSingleton() captures the stack size before
      attempting to construct the new LLSingleton subclass. On exception, it calls
      reset_initializing() to restore the stack to that size.
      
      Naturally that requires a corresponding LLSingleton_manage_master method,
      whose MasterList specialization is a no-op.
      
      finishInitializing()'s exception handling is a bit simpler because it has a
      constructed LLSingleton subclass instance in hand, therefore
      push_initializing() has definitely been called, therefore it can call
      pop_initializing().
      
      Break out new static capture_dependency() method from finishInitializing()
      because, in the previous LLSingleton::getInstance() implementation, the logic
      now wrapped in capture_dependency() was reached even in the INITIALIZED case.
      TODO: Add a new EInitState to differentiate "have been constructed, now
      calling initSingleton()" from "fully initialized, normal case" -- in the
      latter control path we should not be calling capture_dependency().
      
      The LLSingleton_manage_master<LLSingletonBase::MasterList> specialization's
      get_initializing() function (which called get_initializing_from()) was
      potentially dangerous. get_initializing() is called by push_initializing(),
      which (in the general case) is called by LLSingletonBase's constructor. If
      somehow the MasterList's LLSingletonBase constructor ended up calling
      get_initializing(), it would have called get_initializing_from(), passing an
      LLSingletonBase which had not yet been constructed into the MasterList. In
      particular, its mInitializing map would not yet have been initialized at all.
      
      Since the MasterList must not, by design, depend on any other LLSingletons,
      LLSingleton_manage_master<LLSingletonBase::MasterList>::get_initializing()
      need not return a list from the official mInitializing map anyway. It can, and
      should, and now does, return a static dummy list. That obviates
      get_initializing_from(), which is removed.
      
      That in turn means we no longer need to pass get_initializing() an
      LLSingletonBase*. Remove that parameter.
      310db14b
  4. Apr 24, 2017
    • Nat Goodspeed's avatar
      DRTVWR-418: Remove final shutdown cleanup as a cause of crashes. · d415e019
      Nat Goodspeed authored
      The recent LLSingleton work added a hook that would run during the C++
      runtime's final destruction of static objects. When the LAST LLSingleton in
      any module was destroyed, its destructor would call
      LLSingletonBase::deleteAll(). That mechanism was intended to permit an
      application consuming LLSingletons to skip making an explicit deleteAll()
      call, knowing that all instantiated LLSingleton instances would eventually be
      cleaned up anyway.
      
      However -- experience proves that kicking off deleteAll() processing during
      the C++ runtime's final cleanup is too late. Too much has already been
      destroyed. That call tends to cause more shutdown crashes than it resolves.
      
      This commit deletes that whole mechanism. Going forward, if you want to clean
      up LLSingleton instances, you must explicitly call
      LLSingletonBase::deleteAll() during the application lifetime. If you don't,
      LLSingleton instances will simply be leaked -- which might be okay,
      considering the application is terminating anyway.
      d415e019
  5. Apr 25, 2017
  6. Sep 15, 2016
    • Nat Goodspeed's avatar
      MAINT-5232: Normalize LLSingleton subclasses. · d2c3c2f9
      Nat Goodspeed authored
      A shocking number of LLSingleton subclasses had public constructors -- and in
      several instances, were being explicitly instantiated independently of the
      LLSingleton machinery. This breaks the new LLSingleton dependency-tracking
      machinery. It seems only fair that if you say you want an LLSingleton, there
      should only be ONE INSTANCE!
      
      Introduce LLSINGLETON() and LLSINGLETON_EMPTY_CTOR() macros. These handle the
      friend class LLSingleton<whatevah>;
      and explicitly declare a private nullary constructor.
      
      To try to enforce the LLSINGLETON() convention, introduce a new pure virtual
      LLSingleton method you_must_use_LLSINGLETON_macro() which is, as you might
      suspect, defined by the macro. If you declare an LLSingleton subclass without
      using LLSINGLETON() or LLSINGLETON_EMPTY_CTOR() in the class body, you can't
      instantiate the subclass for lack of a you_must_use_LLSINGLETON_macro()
      implementation -- which will hopefully remind the coder.
      
      Trawl through ALL LLSingleton subclass definitions, sprinkling in
      LLSINGLETON() or LLSINGLETON_EMPTY_CTOR() as appropriate. Remove all explicit
      constructor declarations, public or private, along with relevant 'friend class
      LLSingleton<myself>' declarations. Where destructors are declared, move them
      into private section as well. Where the constructor was inline but nontrivial,
      move out of class body.
      
      Fix several LLSingleton abuses revealed by making ctors/dtors private:
      
      LLGlobalEconomy was both an LLSingleton and the base class for
      LLRegionEconomy, a non-LLSingleton. (Therefore every LLRegionEconomy instance
      contained another instance of the LLGlobalEconomy "singleton.") Extract
      LLBaseEconomy; LLGlobalEconomy is now a trivial subclass of that.
      LLRegionEconomy, as you might suspect, now derives from LLBaseEconomy.
      
      LLToolGrab, an LLSingleton, was also explicitly instantiated by
      LLToolCompGun's constructor. Extract LLToolGrabBase, explicitly instantiated,
      with trivial subclass LLToolGrab, the LLSingleton instance.
      
      (WARNING: LLToolGrabBase methods have an unnerving tendency to go after
      LLToolGrab::getInstance(). I DO NOT KNOW what should be the relationship
      between the instance in LLToolCompGun and the LLToolGrab singleton instance.)
      
      LLGridManager declared a variant constructor accepting (const std::string&),
      with the comment:
      // initialize with an explicity grid file for testing.
      As there is no evidence of this being called from anywhere, delete it.
      
      LLChicletBar's constructor accepted an optional (const LLSD&). As the LLSD
      parameter wasn't used, and as there is no evidence of it being passed from
      anywhere, delete the parameter.
      
      LLViewerWindow::shutdownViews() was checking LLNavigationBar::
      instanceExists(), then deleting its getInstance() pointer -- leaving a
      dangling LLSingleton instance pointer, a land mine if any subsequent code
      should attempt to reference it. Use deleteSingleton() instead.
      
      ~LLAppViewer() was calling LLViewerEventRecorder::instance() and then
      explicitly calling ~LLViewerEventRecorder() on that instance -- leaving the
      LLSingleton instance pointer pointing to an allocated-but-destroyed instance.
      Use deleteSingleton() instead.
      d2c3c2f9
  7. Sep 06, 2016
    • Nat Goodspeed's avatar
      MAINT-5232: Prevent runaway LLSingletonBase::MasterList growth. · 1cadeb40
      Nat Goodspeed authored
      Until we reimplement LLCoros on Boost.Fiber, we must hand-implement
      coroutine-local data. That presently takes the form of a map keyed on
      llcoro::id, whose values are the stacks of currently-initializing LLSingleton
      instances.
      
      But since the viewer launches an open-ended number of coroutines, we could end
      up with an open-ended number of map entries unless we intentionally prune the
      map. So every time we pop the stack to empty, remove that map entry.
      
      This could result in thrashing, a given coroutine's 'initializing' stack being
      created and deleted for almost every LLSingleton instantiated by that
      coroutine -- but the number of different LLSingletons is necessarily static,
      and the lifespan of each is the entire rest of the process. Even a couple
      dozen LLSingletons won't thrash that badly.
      1cadeb40
    • Nat Goodspeed's avatar
      MAINT-5232: Make LLSingleton's 'initializing' stack coro-specific. · 90f42498
      Nat Goodspeed authored
      The stack we maintain of which LLSingletons are currently initializing only
      makes sense when associated with a particular C++ call stack. But each
      coroutine introduces another C++ call stack!
      
      Move the initializing stack from function-static storage to
      LLSingletonBase::MasterList. Make it a map keyed by llcoro::id. Each coro then
      has a stack of its own.
      
      This introduces more dependencies on the MasterList singleton, requiring
      additional LLSingleton_manage_master workarounds.
      90f42498
  8. Sep 03, 2016
    • Nat Goodspeed's avatar
      MAINT-5232: Add DEBUG logging to LLSingleton dependency tracking. · c71e6222
      Nat Goodspeed authored
      Specifically, add DEBUG logging to the code that maintains the stack of
      LLSingletons currently being initialized. This involves passing
      LLSingletonBase's constructor the name of LLSingleton's template parameter
      subclass, since during that constructor typeid(*this).name() will only produce
      "LLSingletonBase".
      
      Also add logdebugs() and oktolog() helper functions.
      c71e6222
  9. Sep 01, 2016
  10. Aug 31, 2016
  11. Aug 30, 2016
  12. Nov 10, 2015
  13. Jun 26, 2015
  14. Jun 25, 2015
    • Nat Goodspeed's avatar
      MAINT-5232: Try to avoid circularity between LLError and LLSingleton. · 0ea1b2a1
      Nat Goodspeed authored
      Part of LLError's logging infrastructure is implemented with an LLSingleton.
      Therefore, attempts to log from within LLSingleton machinery could potentially
      go south if LLError's LLSingleton is not yet initialized.
      Introduce LLError::is_available() in llerrorcontrol.h and llerror.cpp.
      Make LLSingletonBase::logwarns() and logerrs() consult LLError::is_available()
      before attempting to use LL_WARNS or LL_ERRS, respectively.
      Moreover, make all LLSingleton internal logging use logwarns() and logerrs()
      instead of directly engaging LL_ERRS or LL_WARNS.
      0ea1b2a1
  15. Jun 24, 2015
    • Nat Goodspeed's avatar
      MAINT-5232: Introduce inter-LLSingleton dependency tracking. · d792baf9
      Nat Goodspeed authored
      Introduce LLSingleton::cleanupSingleton() canonical method as the place to put
      any subclass cleanup logic that might take nontrivial realtime or throw an
      exception. Neither is appropriate in a destructor.
      Track all extant LLSingleton subclass instances on a master list, which
      permits adding LLSingletonBase::cleanupAll() and deleteAll() methods.
      Also notice when any LLSingleton subclass constructor (or initSingleton()
      method) calls instance() or getInstance() for another LLSingleton, and capture
      that other LLSingleton instance as a dependency of the first. This permits
      cleanupAll() and deleteAll() to perform a dependency sort on the master list,
      thus cleaning up (or deleting) leaf LLSingletons AFTER the LLSingletons that
      depend on them.
      Make C++ runtime's final static destructor call LLSingletonBase::deleteAll()
      instead of deleting individual LLSingleton instances in arbitrary order.
      Eliminate "llerror.h" from llsingleton.h, a longstanding TODO.
      d792baf9
  16. Apr 24, 2013
  17. Mar 29, 2013
  18. Oct 13, 2010
  19. Sep 21, 2010
  20. Aug 13, 2010
  21. Aug 06, 2009
  22. Aug 05, 2009
  23. Jun 30, 2009
  24. Jun 21, 2009
  25. May 08, 2009
  26. Feb 25, 2009
    • Robert Knop's avatar
      svn merge -r108815:112761 svn+ssh://svn.lindenlab.com/svn/linden/branches/server/server-1.26 · c88b470a
      Robert Knop authored
      The biggest things in this are Scalable Space Servers and Maint-Server-6
      
      QAR-1209 : SSS
      QAR-1295 : maint-server-6
      
      Conflicts resolved by prospero:
      
      C    scripts/farm_distribute
      
      C    scripts/automated_build_scripts/build-linux.sh : resolved by
                           prospero, mostly kept the merge-right version in
                           the conflict, but there was one block of repeated
                           code from earlier that I removed.
      
      C    scripts/automated_build_scripts/build-mac.sh : kept merge-right
      
      C    indra/llcommon/llversionserver.h : svn revert
      
      C    indra/newsim/llsimparcel.h : kept *both*... working had "setArea",
                          merge-right had exportStream and importStream
      
      C    indra/newsim/llsimparcel.cpp : see llsimparcel.h
      
      C    indra/newsim/lltask.h : working had LLTask derived also from
                         LLScriptResourceConsumer, merge-right had LLTask
                         dervied also from LLAgentPosition.  To resolve
                         conflict, derive from both.
      
      C    indra/newsim/lllslmanager.h : kept merge-right (had an added comment)
      
      C    indra/llmessage/llhttpnode.h : kept working (added the definition
                         of method LLHTTPNode::extendedResult)
      
      C    indra/lscript/lscript_execute_mono/llscriptexecutemono.cpp
      C    indra/lscript/lscript_execute_mono/llscriptexecutemono.h
                        : These two were resolved by si, in consultation with daveh
      
      
      I also had to add the following stubs to
      indra/newsim/tests/llgodkickutils_test.cpp in order to get it to
      compile:
      
        // LLScriptResourceConsumer interface methods in LLTask
        LLScriptResource::LLScriptResource() { }
        LLScriptResourcePool::LLScriptResourcePool() { }
        LLScriptResourcePool LLScriptResourcePool::null;
      
        LLScriptResourceConsumer::LLScriptResourceConsumer() { }
        LLScriptResourcePool& LLScriptResourceConsumer::getScriptResourcePool() { return LLScriptResourcePool::null; }
        const LLScriptResourcePool& LLScriptResourceConsumer::getScriptResourcePool() const { return LLScriptResourcePool::null; }
        bool LLScriptResourceConsumer::switchScriptResourcePools(LLScriptResourcePool& new_pool) { return false; }
        bool LLScriptResourceConsumer::canUseScriptResourcePool(const LLScriptResourcePool& resource_pool) { return false; }
        bool LLScriptResourceConsumer::isInPool(const LLScriptResourcePool& resource_pool) { return false; }
        void LLScriptResourceConsumer::setScriptResourcePool(LLScriptResourcePool& pool) { }
      
        S32 LLTask::getUsedPublicURLs() const { return 0; }
        void LLTask::setScriptResourcePool(LLScriptResourcePool& pool) { }
      c88b470a
  27. Jan 07, 2009
  28. Oct 04, 2007
  29. Jan 02, 2007
Loading