diff options
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/CMakeLists.txt | 1 | ||||
-rw-r--r-- | indra/newview/llagent.h | 1 | ||||
-rw-r--r-- | indra/newview/llpanellandmarks.cpp | 3 | ||||
-rw-r--r-- | indra/newview/llpanelpick.cpp | 3 | ||||
-rw-r--r-- | indra/newview/llpanelplaceinfo.cpp | 4 | ||||
-rw-r--r-- | indra/newview/llremoteparcelrequest.cpp | 53 | ||||
-rw-r--r-- | indra/newview/llremoteparcelrequest.h | 2 | ||||
-rw-r--r-- | indra/newview/tests/llremoteparcelrequest_test.cpp | 134 |
8 files changed, 170 insertions, 31 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index fa49c1ac4c..679637caf6 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1877,6 +1877,7 @@ if (LL_TESTS) lldateutil.cpp llmediadataclient.cpp lllogininstance.cpp + llremoteparcelrequest.cpp llviewerhelputil.cpp llversioninfo.cpp ) diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 6c598d5d71..aebebad96a 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -33,6 +33,7 @@ #include "llagentconstants.h" #include "llagentdata.h" // gAgentID, gAgentSessionID #include "llcharacter.h" // LLAnimPauseRequest +#include "llcoordframe.h" // for mFrameAgent #include "llpointer.h" #include "lluicolor.h" #include "llvoavatardefines.h" diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index d25b8e0e02..e8c8273a9d 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -520,9 +520,6 @@ void LLLandmarksPanel::setParcelID(const LLUUID& parcel_id) { if (!parcel_id.isNull()) { - //ext-4655, defensive. remove now incase this gets called twice without a remove - LLRemoteParcelInfoProcessor::getInstance()->removeObserver(parcel_id, this); - LLRemoteParcelInfoProcessor::getInstance()->addObserver(parcel_id, this); LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(parcel_id); } diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp index 271728220c..44cca21a76 100644 --- a/indra/newview/llpanelpick.cpp +++ b/indra/newview/llpanelpick.cpp @@ -204,9 +204,6 @@ void LLPanelPickInfo::sendParcelInfoRequest() { if (mParcelId != mRequestedId) { - //ext-4655, remove now incase this gets called twice without a remove - LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mRequestedId, this); - LLRemoteParcelInfoProcessor::getInstance()->addObserver(mParcelId, this); LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(mParcelId); diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp index 9cbb512e70..4ae0c0eb12 100644 --- a/indra/newview/llpanelplaceinfo.cpp +++ b/indra/newview/llpanelplaceinfo.cpp @@ -128,10 +128,6 @@ void LLPanelPlaceInfo::sendParcelInfoRequest() { if (mParcelID != mRequestedID) { - //ext-4655, defensive. remove now incase this gets called twice without a remove - //as panel never closes its ok atm (but wrong :) - LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mRequestedID, this); - LLRemoteParcelInfoProcessor::getInstance()->addObserver(mParcelID, this); LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(mParcelID); diff --git a/indra/newview/llremoteparcelrequest.cpp b/indra/newview/llremoteparcelrequest.cpp index d63a48647d..10d4452ed2 100644 --- a/indra/newview/llremoteparcelrequest.cpp +++ b/indra/newview/llremoteparcelrequest.cpp @@ -77,23 +77,19 @@ void LLRemoteParcelRequestResponder::error(U32 status, const std::string& reason void LLRemoteParcelInfoProcessor::addObserver(const LLUUID& parcel_id, LLRemoteParcelInfoObserver* observer) { - // Check if the observer is already in observers list for this UUID observer_multimap_t::iterator it; + observer_multimap_t::iterator end = mObservers.upper_bound(parcel_id); - it = mObservers.find(parcel_id); - while (it != mObservers.end()) + // Check if the observer is already in observers list for this UUID + for(it = mObservers.find(parcel_id); it != end; ++it) { - if (it->second == observer) + if (it->second.get() == observer) { return; } - else - { - ++it; - } } - mObservers.insert(std::pair<LLUUID, LLRemoteParcelInfoObserver*>(parcel_id, observer)); + mObservers.insert(std::make_pair(parcel_id, observer->getObserverHandle())); } void LLRemoteParcelInfoProcessor::removeObserver(const LLUUID& parcel_id, LLRemoteParcelInfoObserver* observer) @@ -104,19 +100,15 @@ void LLRemoteParcelInfoProcessor::removeObserver(const LLUUID& parcel_id, LLRemo } observer_multimap_t::iterator it; + observer_multimap_t::iterator end = mObservers.upper_bound(parcel_id); - it = mObservers.find(parcel_id); - while (it != mObservers.end()) + for(it = mObservers.find(parcel_id); it != end; ++it) { - if (it->second == observer) + if (it->second.get() == observer) { mObservers.erase(it); break; } - else - { - ++it; - } } } @@ -141,13 +133,34 @@ void LLRemoteParcelInfoProcessor::processParcelInfoReply(LLMessageSystem* msg, v msg->getS32 ("Data", "SalePrice", parcel_data.sale_price); msg->getS32 ("Data", "AuctionID", parcel_data.auction_id); - LLRemoteParcelInfoProcessor::observer_multimap_t observers = LLRemoteParcelInfoProcessor::getInstance()->mObservers; + LLRemoteParcelInfoProcessor::observer_multimap_t & observers = LLRemoteParcelInfoProcessor::getInstance()->mObservers; + + typedef std::vector<observer_multimap_t::iterator> deadlist_t; + deadlist_t dead_iters; - observer_multimap_t::iterator oi = observers.find(parcel_data.parcel_id); + observer_multimap_t::iterator oi; observer_multimap_t::iterator end = observers.upper_bound(parcel_data.parcel_id); - for (; oi != end; ++oi) + + for (oi = observers.find(parcel_data.parcel_id); oi != end; ++oi) + { + LLRemoteParcelInfoObserver * observer = oi->second.get(); + if(observer) + { + observer->processParcelInfo(parcel_data); + } + else + { + // the handle points to an expired observer, so don't keep it + // around anymore + dead_iters.push_back(oi); + } + } + + deadlist_t::iterator i; + deadlist_t::iterator end_dead = dead_iters.end(); + for(i = dead_iters.begin(); i != end_dead; ++i) { - oi->second->processParcelInfo(parcel_data); + observers.erase(*i); } } diff --git a/indra/newview/llremoteparcelrequest.h b/indra/newview/llremoteparcelrequest.h index a6c62995a9..74cf1616df 100644 --- a/indra/newview/llremoteparcelrequest.h +++ b/indra/newview/llremoteparcelrequest.h @@ -98,7 +98,7 @@ public: static void processParcelInfoReply(LLMessageSystem* msg, void**); private: - typedef std::multimap<LLUUID, LLRemoteParcelInfoObserver*> observer_multimap_t; + typedef std::multimap<LLUUID, LLHandle<LLRemoteParcelInfoObserver> > observer_multimap_t; observer_multimap_t mObservers; }; diff --git a/indra/newview/tests/llremoteparcelrequest_test.cpp b/indra/newview/tests/llremoteparcelrequest_test.cpp new file mode 100644 index 0000000000..a6c1f69c82 --- /dev/null +++ b/indra/newview/tests/llremoteparcelrequest_test.cpp @@ -0,0 +1,134 @@ +/**
+ * @file llremoteparcelrequest_test.cpp
+ * @author Brad Kittenbrink <brad@lindenlab.com>
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "../test/lltut.h"
+
+#include "../llremoteparcelrequest.h"
+
+#include "../llagent.h"
+#include "message.h"
+
+namespace {
+ LLControlGroup s_saved_settings("dummy_settings");
+ const LLUUID TEST_PARCEL_ID("11111111-1111-1111-1111-111111111111");
+}
+
+LLCurl::Responder::Responder() { }
+LLCurl::Responder::~Responder() { }
+void LLCurl::Responder::error(U32,std::string const &) { }
+void LLCurl::Responder::result(LLSD const &) { }
+void LLCurl::Responder::errorWithContent(U32 status,std::string const &,LLSD const &) { }
+void LLCurl::Responder::completedRaw(U32 status, std::string const &, LLChannelDescriptors const &,boost::shared_ptr<LLBufferArray> const &) { }
+void LLCurl::Responder::completed(U32 status, std::string const &, LLSD const &) { }
+void LLCurl::Responder::completedHeader(U32 status, std::string const &, LLSD const &) { }
+void LLMessageSystem::getF32(char const *,char const *,F32 &,S32) { }
+void LLMessageSystem::getU8(char const *,char const *,U8 &,S32) { }
+void LLMessageSystem::getS32(char const *,char const *,S32 &,S32) { }
+void LLMessageSystem::getString(char const *,char const *, std::string &,S32) { }
+void LLMessageSystem::getUUID(char const *,char const *, LLUUID & out_id,S32)
+{
+ out_id = TEST_PARCEL_ID;
+}
+void LLMessageSystem::nextBlock(char const *) { }
+void LLMessageSystem::addUUID(char const *,LLUUID const &) { }
+void LLMessageSystem::addUUIDFast(char const *,LLUUID const &) { }
+void LLMessageSystem::nextBlockFast(char const *) { }
+void LLMessageSystem::newMessage(char const *) { }
+LLMessageSystem * gMessageSystem;
+char * _PREHASH_AgentID;
+char * _PREHASH_AgentData;
+LLAgent gAgent;
+LLAgent::LLAgent() : mAgentAccess(s_saved_settings) { }
+LLAgent::~LLAgent() { }
+void LLAgent::sendReliableMessage(void) { }
+LLUUID gAgentSessionID;
+LLUUID gAgentID;
+LLUIColor::LLUIColor(void) { }
+LLAgentAccess::LLAgentAccess(LLControlGroup & settings) : mSavedSettings(settings) { }
+LLControlGroup::LLControlGroup(std::string const & name) : LLInstanceTracker<LLControlGroup, std::string>(name) { }
+LLControlGroup::~LLControlGroup(void) { }
+
+namespace tut
+{
+ struct TestObserver : public LLRemoteParcelInfoObserver {
+ TestObserver() : mProcessed(false) { }
+
+ virtual void processParcelInfo(const LLParcelData& parcel_data)
+ {
+ mProcessed = true;
+ }
+
+ virtual void setParcelID(const LLUUID& parcel_id) { }
+
+ virtual void setErrorStatus(U32 status, const std::string& reason) { }
+
+ bool mProcessed;
+ };
+
+ struct RemoteParcelRequestData
+ {
+ RemoteParcelRequestData()
+ {
+ }
+ };
+
+ typedef test_group<RemoteParcelRequestData> remoteparcelrequest_t;
+ typedef remoteparcelrequest_t::object remoteparcelrequest_object_t;
+ tut::remoteparcelrequest_t tut_remoteparcelrequest("LLRemoteParcelRequest");
+
+ template<> template<>
+ void remoteparcelrequest_object_t::test<1>()
+ {
+ set_test_name("observer pointer");
+
+ boost::scoped_ptr<TestObserver> observer(new TestObserver());
+
+ LLRemoteParcelInfoProcessor & processor = LLRemoteParcelInfoProcessor::instance();
+ processor.addObserver(LLUUID(TEST_PARCEL_ID), observer.get());
+
+ processor.processParcelInfoReply(gMessageSystem, NULL);
+
+ ensure(observer->mProcessed);
+ }
+
+ template<> template<>
+ void remoteparcelrequest_object_t::test<2>()
+ {
+ set_test_name("CHOP-220: dangling observer pointer");
+
+ LLRemoteParcelInfoObserver * observer = new TestObserver();
+
+ LLRemoteParcelInfoProcessor & processor = LLRemoteParcelInfoProcessor::instance();
+ processor.addObserver(LLUUID(TEST_PARCEL_ID), observer);
+
+ delete observer;
+ observer = NULL;
+
+ processor.processParcelInfoReply(gMessageSystem, NULL);
+ }
+}
|