DRTVWR-418: Make LLEventPumps an LLHandleProvider for LLEventPump.

LLEventPump's destructor was using LLEventPumps::instance() to unregister the
LLEventPump instance from LLEventPumps. Evidently, though, there are lingering
LLEventPump instances that persist even after the LLSingletonBase::deleteAll()
call destroys the LLEventPumps LLSingleton instance. These were resurrecting
LLEventPumps -- pointlessly, since a newly-resurrected LLEventPumps instance
can have no knowledge of the LLEventPump instance! Unregistering is
unnecessary!

What we want is a reference we can bind into each LLEventPump instance that
allows us to safely test whether the LLEventPumps instance still exists.
LLHandle is exactly that. Make LLEventPumps an LLHandleProvider and bind its
LLHandle in each LLEventPump's constructor; then the destructor can unregister
only when LLEventPumps still exists.
master
Nat Goodspeed 2017-03-13 14:31:38 -04:00
parent e6fc3528fd
commit c1458713de
2 changed files with 24 additions and 6 deletions

View File

@ -281,7 +281,8 @@ const std::string LLEventPump::ANONYMOUS = std::string();
LLEventPump::LLEventPump(const std::string& name, bool tweak):
// Register every new instance with LLEventPumps
mName(LLEventPumps::instance().registerNew(*this, name, tweak)),
mRegistry(LLEventPumps::instance().getHandle()),
mName(mRegistry.get()->registerNew(*this, name, tweak)),
mSignal(new LLStandardSignal()),
mEnabled(true)
{}
@ -292,8 +293,13 @@ LLEventPump::LLEventPump(const std::string& name, bool tweak):
LLEventPump::~LLEventPump()
{
// Unregister this doomed instance from LLEventPumps
LLEventPumps::instance().unregister(*this);
// Unregister this doomed instance from LLEventPumps -- but only if
// LLEventPumps is still around!
LLEventPumps* registry = mRegistry.get();
if (registry)
{
registry->unregister(*this);
}
}
// static data member

View File

@ -62,6 +62,7 @@
#include "lldependencies.h"
#include "llstl.h"
#include "llexception.h"
#include "llhandle.h"
/*==========================================================================*|
// override this to allow binding free functions with more parameters
@ -227,7 +228,15 @@ class LLEventPump;
* LLEventPumps is a Singleton manager through which one typically accesses
* this subsystem.
*/
class LL_COMMON_API LLEventPumps: public LLSingleton<LLEventPumps>
// LLEventPumps isa LLHandleProvider only for (hopefully rare) long-lived
// class objects that must refer to this class late in their lifespan, say in
// the destructor. Specifically, the case that matters is a possible reference
// after LLEventPumps::deleteSingleton(). (Lingering LLEventPump instances are
// capable of this.) In that case, instead of calling LLEventPumps::instance()
// again -- resurrecting the deleted LLSingleton -- store an
// LLHandle<LLEventPumps> and test it before use.
class LL_COMMON_API LLEventPumps: public LLSingleton<LLEventPumps>,
public LLHandleProvider<LLEventPumps>
{
LLSINGLETON(LLEventPumps);
public:
@ -590,6 +599,9 @@ private:
return this->listen_impl(name, listener, after, before);
}
// must precede mName; see LLEventPump::LLEventPump()
LLHandle<LLEventPumps> mRegistry;
std::string mName;
protected:
@ -817,14 +829,14 @@ public:
mConnection(new LLBoundListener)
{
}
/// Copy constructor. Copy shared_ptrs to original instance data.
LLListenerWrapperBase(const LLListenerWrapperBase& that):
mName(that.mName),
mConnection(that.mConnection)
{
}
virtual ~LLListenerWrapperBase() {}
virtual ~LLListenerWrapperBase() {}
/// Ask LLEventPump::listen() for the listener name
virtual void accept_name(const std::string& name) const