diff options
| author | Nat Goodspeed <nat@lindenlab.com> | 2016-09-06 21:25:57 -0400 | 
|---|---|---|
| committer | Nat Goodspeed <nat@lindenlab.com> | 2016-09-06 21:25:57 -0400 | 
| commit | 1cadeb40df15c1eaef3410064f9a2b8e4489082d (patch) | |
| tree | c37d1d8a8d4941ae35eefed7dcbfc8e54f5c866b /indra | |
| parent | 90f424980a3aba06ac85cc23373795bc53a3fd87 (diff) | |
MAINT-5232: Prevent runaway LLSingletonBase::MasterList growth.
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.
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llcommon/llsingleton.cpp | 22 | 
1 files changed, 21 insertions, 1 deletions
| diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp index 3f65820f2e..24ccc8ddb4 100644 --- a/indra/llcommon/llsingleton.cpp +++ b/indra/llcommon/llsingleton.cpp @@ -94,6 +94,15 @@ public:          // here. It returns a reference to the selected mapped_type instance.          return mInitializing[llcoro::get_id()];      } + +    void cleanup_initializing_() +    { +        InitializingMap::iterator found = mInitializing.find(llcoro::get_id()); +        if (found != mInitializing.end()) +        { +            mInitializing.erase(found); +        } +    }  };  //static @@ -129,7 +138,7 @@ LLSingletonBase::list_t& LLSingletonBase::get_initializing()  //static  LLSingletonBase::list_t& LLSingletonBase::get_initializing_from(MasterList* master)  { -    return master->get_initializing_();; +    return master->get_initializing_();  }  LLSingletonBase::~LLSingletonBase() {} @@ -156,6 +165,17 @@ void LLSingletonBase::pop_initializing()      // and pop it      list.pop_back(); +    // The viewer launches an open-ended number of coroutines. While we don't +    // expect most of them to initialize LLSingleton instances, our present +    // get_initializing() logic could lead to an open-ended number of map +    // entries. So every time we pop the stack back to empty, delete the entry +    // entirely. +    if (list.empty()) +    { +        MasterList::instance().cleanup_initializing_(); +    } + +    // Now validate the newly-popped LLSingleton.      if (back != this)      {          logerrs("Push/pop mismatch in stack of currently-initializing LLSingletons: ", | 
