diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 16c2b2d55a9789df17a37143b43c95db9a5ab515..326b5fd629f9304b9f6762f4df02dfd75a40a213 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -332,13 +332,11 @@ const char* const VIEWER_WINDOW_CLASSNAME = "Second Life"; * Tasks added to this list will be executed in the next LLAppViewer::idle() iteration. * All tasks are executed only once. */ -class LLDeferredTaskList: - public LLSingleton<LLDeferredTaskList>, - private LLDestroyClass<LLDeferredTaskList> +class LLDeferredTaskList: public LLSingleton<LLDeferredTaskList> { LOG_CLASS(LLDeferredTaskList); + friend class LLAppViewer; - friend class LLDestroyClass<LLDeferredTaskList>; typedef boost::signals2::signal<void()> signal_t; void addTask(const signal_t::slot_type& cb) @@ -348,15 +346,11 @@ class LLDeferredTaskList: void run() { - if (mSignal.empty()) return; - - mSignal(); - mSignal.disconnect_all_slots(); - } - - static void destroyClass() - { - instance().mSignal.disconnect_all_slots(); + if (!mSignal.empty()) + { + mSignal(); + mSignal.disconnect_all_slots(); + } } signal_t mSignal; @@ -4460,6 +4454,7 @@ void LLAppViewer::idle() } } + // Execute deferred tasks. LLDeferredTaskList::instance().run(); // Handle shutdown process, for example, diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 22966015c827016792e9acfde9c1c2affbfc039f..793abb1c9d405b544347326018d41f9eb4945977 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1060,6 +1060,10 @@ class LLDiscardAgentOffer : public LLInventoryFetchItemsObserver { LL_DEBUGS("Messaging") << "LLDiscardAgentOffer::done()" << LL_ENDL; + // We're invoked from LLInventoryModel::notifyObservers(). + // If we now try to remove the inventory item, it will cause a nested + // notifyObservers() call, which won't work. + // So defer moving the item to trash until viewer gets idle (in a moment). LLAppViewer::instance()->addOnIdleCallback(boost::bind(&LLInventoryModel::removeItem, &gInventory, mObjectID)); gInventory.removeObserver(this); delete this;