SL-15093 Crash nanov2_free_to_block

Superficially crash happens in disconnect() inside signal's deconstructor. Manual cleanup should help figuring out if crash happens due to named or anonymous listeners
master
Andrey Kleshchev 2021-05-28 19:52:07 +03:00
parent 74711a2cf2
commit efdbaa50be
2 changed files with 15 additions and 17 deletions

View File

@ -45,7 +45,6 @@
#include <cctype>
// external library headers
#include <boost/range/iterator_range.hpp>
#include <boost/make_shared.hpp>
#if LL_WINDOWS
#pragma warning (push)
#pragma warning (disable : 4701) // compiler thinks might use uninitialized var, but no
@ -285,7 +284,7 @@ LLEventPump::LLEventPump(const std::string& name, bool tweak):
// Register every new instance with LLEventPumps
mRegistry(LLEventPumps::instance().getHandle()),
mName(mRegistry.get()->registerNew(*this, name, tweak)),
mSignal(boost::make_shared<LLStandardSignal>()),
mSignal(std::make_shared<LLStandardSignal>()),
mEnabled(true)
{}
@ -317,14 +316,24 @@ void LLEventPump::clear()
{
// Destroy the original LLStandardSignal instance, replacing it with a
// whole new one.
mSignal = boost::make_shared<LLStandardSignal>();
mSignal = std::make_shared<LLStandardSignal>();
mConnections.clear();
}
void LLEventPump::reset()
{
mSignal.reset();
// Resetting mSignal is supposed to disconnect everything on its own
// But due to crash on 'reset' added explicit cleanup to get more data
ConnectionMap::const_iterator iter = mConnections.begin();
ConnectionMap::const_iterator end = mConnections.end();
while (iter!=end)
{
iter->second.disconnect();
iter++;
}
mConnections.clear();
mSignal.reset();
//mDeps.clear();
}
@ -543,7 +552,7 @@ bool LLEventStream::post(const LLSD& event)
// *stack* instance of the shared_ptr, ensuring that our heap
// LLStandardSignal object will live at least until post() returns, even
// if 'this' gets destroyed during the call.
boost::shared_ptr<LLStandardSignal> signal(mSignal);
std::shared_ptr<LLStandardSignal> signal(mSignal);
// Let caller know if any one listener handled the event. This is mostly
// useful when using LLEventStream as a listener for an upstream
// LLEventPump.

View File

@ -49,7 +49,6 @@
#endif
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/utility.hpp> // noncopyable
#include <boost/optional/optional.hpp>
@ -571,7 +570,7 @@ protected:
const NameList& before);
/// implement the dispatching
boost::shared_ptr<LLStandardSignal> mSignal;
std::shared_ptr<LLStandardSignal> mSignal;
/// valve open?
bool mEnabled;
@ -745,14 +744,4 @@ private:
LL_COMMON_API bool sendReply(const LLSD& reply, const LLSD& request,
const std::string& replyKey="reply");
// Somewhat to my surprise, passing boost::bind(...boost::weak_ptr<T>...) to
// listen() fails in Boost code trying to instantiate LLEventListener (i.e.
// LLStandardSignal::slot_type) because the boost::get_pointer() utility function isn't
// specialized for boost::weak_ptr. This remedies that omission.
namespace boost
{
template <typename T>
T* get_pointer(const weak_ptr<T>& ptr) { return shared_ptr<T>(ptr).get(); }
}
#endif /* ! defined(LL_LLEVENTS_H) */