diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llprimitive/llmediaentry.cpp | 8 | ||||
| -rw-r--r-- | indra/llprimitive/tests/llmediaentry_test.cpp | 197 | ||||
| -rw-r--r-- | indra/newview/llfloatertools.cpp | 41 | ||||
| -rwxr-xr-x | indra/newview/llmediadataclient.cpp | 21 | ||||
| -rwxr-xr-x | indra/newview/llmediadataclient.h | 8 | ||||
| -rw-r--r-- | indra/newview/llvovolume.cpp | 8 | ||||
| -rw-r--r-- | indra/newview/llvovolume.h | 5 | ||||
| -rw-r--r-- | indra/newview/tests/llmediadataclient_test.cpp | 35 | 
8 files changed, 204 insertions, 119 deletions
| diff --git a/indra/llprimitive/llmediaentry.cpp b/indra/llprimitive/llmediaentry.cpp index 701300163a..2fc1e5e60c 100644 --- a/indra/llprimitive/llmediaentry.cpp +++ b/indra/llprimitive/llmediaentry.cpp @@ -389,8 +389,12 @@ U32 LLMediaEntry::setWhiteList( const std::vector<std::string> &whitelist )  U32 LLMediaEntry::setWhiteList( const LLSD &whitelist )  { -    // If whitelist is undef, this is a no-op. -    if (whitelist.isUndefined()) return LSL_STATUS_OK; +    // If whitelist is undef, the whitelist is cleared +    if (whitelist.isUndefined())  +	{ +		mWhiteList.clear(); +		return LSL_STATUS_OK; +	}      // However, if the whitelist is an empty array, erase it.      if (whitelist.isArray())  diff --git a/indra/llprimitive/tests/llmediaentry_test.cpp b/indra/llprimitive/tests/llmediaentry_test.cpp index cd9608d56b..dfac5f26c7 100644 --- a/indra/llprimitive/tests/llmediaentry_test.cpp +++ b/indra/llprimitive/tests/llmediaentry_test.cpp @@ -190,9 +190,9 @@ namespace tut          entry.setWhiteList(tokens);      } -    void whitelist_test(bool enable, const char *whitelist, const char *candidate_url, bool expected_pass) +    void whitelist_test(int num, bool enable, const char *whitelist, const char *candidate_url, bool expected_pass)      { -        std::string message = "Whitelist test"; +        std::string message = "Whitelist test " + boost::lexical_cast<std::string>(num);          LLMediaEntry entry;          entry.setWhiteListEnable(enable);          set_whitelist(entry, whitelist); @@ -209,13 +209,13 @@ namespace tut          ensure(message, expected_pass == passed_whitelist);      } -    void whitelist_test(const char *whitelist, const char *candidate_url, bool expected_pass) +    void whitelist_test(int num, const char *whitelist, const char *candidate_url, bool expected_pass)      { -        whitelist_test(true, whitelist, candidate_url, expected_pass); +        whitelist_test(num, true, whitelist, candidate_url, expected_pass);      } -    void whitelist_test(const char *whitelist, const char *candidate_url) +    void whitelist_test(int num, const char *whitelist, const char *candidate_url)      { -        whitelist_test(true, whitelist, candidate_url, true); +        whitelist_test(num, true, whitelist, candidate_url, true);      }  	template<> template<> @@ -265,12 +265,30 @@ namespace tut          ensure_llsd_equals(get_test_name() + " failed", defaultMediaEntryLLSD, sd);      } +	 +    template<> template<> +    void object::test<5>() +    { +        set_test_name("Test LLMediaEntry::asLLSD() -> LLMediaEntry::fromLLSD()"); +        LLMediaEntry entry1, entry2; +		// Add a whitelist to entry2 +		std::vector<std::string> whitelist; +		whitelist.push_back("*.example.com"); +        entry2.setWhiteList(whitelist); +		// Render entry1 (which has no whitelist) as an LLSD +        LLSD sd; +		entry1.asLLSD(sd); +		// "read" that LLSD into entry 2 +		entry2.fromLLSD(sd); +        ensure_llsd_equals(get_test_name() + " failed", defaultMediaEntryLLSD, entry2.asLLSD()); +    } +	      // limit tests      const char *URL_OK = "http://www.example.com";      const char *URL_TOO_BIG = "http://www.example.com.qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq";      template<> template<> -    void object::test<5>() +    void object::test<6>()      {          set_test_name("Test Limits on setting current URL");          LLMediaEntry entry; @@ -281,7 +299,7 @@ namespace tut      }          template<> template<> -    void object::test<6>() +    void object::test<7>()      {          set_test_name("Test Limits on setting home URL");          LLMediaEntry entry; @@ -292,7 +310,7 @@ namespace tut      }      template<> template<> -    void object::test<7>() +    void object::test<8>()      {          set_test_name("Test Limits on setting whitelist"); @@ -306,7 +324,7 @@ namespace tut      }      template<> template<> -    void object::test<8>() +    void object::test<9>()      {          set_test_name("Test Limits on setting whitelist too big"); @@ -321,7 +339,7 @@ namespace tut      }      template<> template<> -    void object::test<9>() +    void object::test<10>()      {          set_test_name("Test Limits on setting whitelist too many"); @@ -337,7 +355,7 @@ namespace tut      }      template<> template<> -    void object::test<10>() +    void object::test<11>()      {          set_test_name("Test to make sure both setWhiteList() functions behave the same"); @@ -355,7 +373,7 @@ namespace tut      }      template<> template<> -    void object::test<11>() +    void object::test<12>()      {          set_test_name("Test to make sure both setWhiteList() functions behave the same"); @@ -376,7 +394,7 @@ namespace tut      }      template<> template<> -    void object::test<12>() +    void object::test<13>()      {          set_test_name("Test to make sure both setWhiteList() functions behave the same"); @@ -396,103 +414,70 @@ namespace tut                 empty == entry2.getWhiteList());      } -    // Whitelist check tests -     -    // Check the "empty whitelist" case      template<> template<> -    void object::test<13>() { whitelist_test("", "http://www.example.com", true); } +    void object::test<14>()  +	{ +		// Whitelist check tests +		int n=0; +		 +		// Check the "empty whitelist" case +		whitelist_test(++n, "", "http://www.example.com", true);  -    // Check the "missing scheme" case -    template<> template<> -    void object::test<14>() { whitelist_test("www.example.com", "http://www.example.com", true); } +		// Check the "missing scheme" case +		whitelist_test(++n, "www.example.com", "http://www.example.com", true); -    // Check the "exactly the same" case -    template<> template<> -    void object::test<15>() { whitelist_test("http://example.com", "http://example.com", true); } +		// Check the "exactly the same" case +		whitelist_test(++n, "http://example.com", "http://example.com", true); -    // Check the enable flag -    template<> template<> -    void object::test<16>() { whitelist_test(false, "www.example.com", "http://www.secondlife.com", true); } -    template<> template<> -    void object::test<17>() { whitelist_test(true, "www.example.com", "http://www.secondlife.com", false); } +		// Check the enable flag +		whitelist_test(++n, false, "www.example.com", "http://www.secondlife.com", true); +		whitelist_test(++n, true, "www.example.com", "http://www.secondlife.com", false); -    // Check permutations of trailing slash: -    template<> template<> -    void object::test<18>() { whitelist_test("http://www.example.com", "http://www.example.com/", true); } -    template<> template<> -    void object::test<19>() { whitelist_test("http://www.example.com/", "http://www.example.com/", true); } -    template<> template<> -    void object::test<20>() { whitelist_test("http://www.example.com/", "http://www.example.com", false); } -    template<> template<> -    void object::test<21>() { whitelist_test("http://www.example.com", "http://www.example.com/foobar", true); } -    template<> template<> -    void object::test<22>() { whitelist_test("http://www.example.com/", "http://www.example.com/foobar", false); } +		// Check permutations of trailing slash: +		whitelist_test(++n, "http://www.example.com", "http://www.example.com/", true); +		whitelist_test(++n, "http://www.example.com/", "http://www.example.com/", true); +		whitelist_test(++n, "http://www.example.com/", "http://www.example.com", false); +		whitelist_test(++n, "http://www.example.com", "http://www.example.com/foobar", true); +		whitelist_test(++n, "http://www.example.com/", "http://www.example.com/foobar", false); -    // More cases... -    template<> template<> -    void object::test<23>() { whitelist_test("http://example.com", "http://example.com/wiki", true); } -    template<> template<> -    void object::test<24>() { whitelist_test("www.example.com", "http://www.example.com/help", true); } -    template<> template<> -    void object::test<25>() { whitelist_test("http://www.example.com", "http://wwwexample.com", false); } -    template<> template<> -    void object::test<26>() { whitelist_test("http://www.example.com", "http://www.example.com/wiki", true); } -    template<> template<> -    void object::test<27>() { whitelist_test("example.com", "http://wwwexample.com", false); } -    template<> template<> -    void object::test<28>() { whitelist_test("http://www.example.com/", "http://www.amazon.com/wiki", false); } -    template<> template<> -    void object::test<29>() { whitelist_test("www.example.com", "http://www.amazon.com", false); } - -    // regexp cases -    template<> template<> -    void object::test<30>() { whitelist_test("*.example.com", "http://www.example.com", true); } -    template<> template<> -    void object::test<31>() { whitelist_test("*.example.com", "http://www.amazon.com", false); } -    template<> template<> -    void object::test<32>() { whitelist_test("*.example.com", "http://www.example.com/foo/bar", true); } -    template<> template<> -    void object::test<33>() { whitelist_test("*.example.com", "http:/example.com/foo/bar", false); } -    template<> template<> -    void object::test<34>() { whitelist_test("*example.com", "http://example.com/foo/bar", true); } -    template<> template<> -    void object::test<35>() { whitelist_test("*example.com", "http://my.virus.com/foo/bar?example.com", false); } -    template<> template<> -    void object::test<36>() { whitelist_test("example.com", "http://my.virus.com/foo/bar?example.com", false); } -    template<> template<> -    void object::test<37>() { whitelist_test("*example.com", "http://my.virus.com/foo/bar?*example.com", false); } -    template<> template<> -    void object::test<38>() { whitelist_test("http://*example.com", "http://www.example.com", true); } -    template<> template<> -    void object::test<39>() { whitelist_test("http://*.example.com", "http://www.example.com", true); } -    template<> template<> -    void object::test<40>() { whitelist_test("http://*.e$?^.com", "http://www.e$?^.com", true); } -    template<> template<> -    void object::test<41>() { whitelist_test("*.example.com/foo/bar", "http://www.example.com/", false); } -    template<> template<> -    void object::test<42>() { whitelist_test("*.example.com/foo/bar", "http://example.com/foo/bar", false); } -    template<> template<> -    void object::test<43>() { whitelist_test("http://*.example.com/foo/bar", "http://www.example.com", false); } -    template<> template<> -    void object::test<44>() { whitelist_test("http://*.example.com", "https://www.example.com", false); } -    template<> template<> -    void object::test<45>() { whitelist_test("http*://*.example.com", "rtsp://www.example.com", false); } -    template<> template<> -    void object::test<46>() { whitelist_test("http*://*.example.com", "https://www.example.com", true); } -    template<> template<> -    void object::test<47>() { whitelist_test("example.com", "http://www.example.com", false); } -    template<> template<> -    void object::test<48>() { whitelist_test("www.example.com", "http://www.example.com:80", false); } -    template<> template<> -    void object::test<49>() { whitelist_test("www.example.com", "http://www.example.com", true); } -    template<> template<> -    void object::test<50>() { whitelist_test("www.example.com/", "http://www.example.com", false); } -    template<> template<> -    void object::test<51>() { whitelist_test("www.example.com/foo/bar/*", "http://www.example.com/foo/bar/baz", true); } -    // Path only -    template<> template<> -    void object::test<52>() { whitelist_test("/foo/*/baz", "http://www.example.com/foo/bar/baz", true); } -    template<> template<> -    void object::test<53>() { whitelist_test("/foo/*/baz", "http://www.example.com/foo/bar/", false); } +		// More cases... +		whitelist_test(++n, "http://example.com", "http://example.com/wiki", true); +		whitelist_test(++n, "www.example.com", "http://www.example.com/help", true); +		whitelist_test(++n, "http://www.example.com", "http://wwwexample.com", false); +		whitelist_test(++n, "http://www.example.com", "http://www.example.com/wiki", true); +		whitelist_test(++n, "example.com", "http://wwwexample.com", false); +		whitelist_test(++n, "http://www.example.com/", "http://www.amazon.com/wiki", false); +		whitelist_test(++n, "www.example.com", "http://www.amazon.com", false); + +		// regexp cases +		whitelist_test(++n, "*.example.com", "http://www.example.com", true); +		whitelist_test(++n, "*.example.com", "http://www.amazon.com", false); +		whitelist_test(++n, "*.example.com", "http://www.example.com/foo/bar", true); +		whitelist_test(++n, "*.example.com", "http:/example.com/foo/bar", false); +		whitelist_test(++n, "*example.com", "http://example.com/foo/bar", true); +		whitelist_test(++n, "*example.com", "http://my.virus.com/foo/bar?example.com", false); +		whitelist_test(++n, "example.com", "http://my.virus.com/foo/bar?example.com", false); +		whitelist_test(++n, "*example.com", "http://my.virus.com/foo/bar?*example.com", false); +		whitelist_test(++n, "http://*example.com", "http://www.example.com", true); +		whitelist_test(++n, "http://*.example.com", "http://www.example.com", true); +		whitelist_test(++n, "http://*.e$?^.com", "http://www.e$?^.com", true); +		whitelist_test(++n, "*.example.com/foo/bar", "http://www.example.com/", false); +		whitelist_test(++n, "*.example.com/foo/bar", "http://example.com/foo/bar", false); +		whitelist_test(++n, "http://*.example.com/foo/bar", "http://www.example.com", false); +		whitelist_test(++n, "http://*.example.com", "https://www.example.com", false); +		whitelist_test(++n, "http*://*.example.com", "rtsp://www.example.com", false); +		whitelist_test(++n, "http*://*.example.com", "https://www.example.com", true); +		whitelist_test(++n, "example.com", "http://www.example.com", false); +		whitelist_test(++n, "www.example.com", "http://www.example.com:80", false); +		whitelist_test(++n, "www.example.com", "http://www.example.com", true); +		whitelist_test(++n, "www.example.com/", "http://www.example.com", false); +		whitelist_test(++n, "www.example.com/foo/bar/*", "http://www.example.com/foo/bar/baz", true); + +        // Path only +		whitelist_test(++n, "/foo/*/baz", "http://www.example.com/foo/bar/baz", true); +		whitelist_test(++n, "/foo/*/baz", "http://www.example.com/foo/bar/", false); +	} +	  } + diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 3aef15a35c..3c3dfb760e 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -86,6 +86,7 @@  #include "llviewermenu.h"  #include "llviewerparcelmgr.h"  #include "llviewerwindow.h" +#include "llvovolume.h"  #include "lluictrlfactory.h"  // Globals @@ -1079,21 +1080,45 @@ void LLFloaterTools::getMediaState()  	}  	bool editable = (first_object->permModify() || selectedMediaEditable()); -	 + +	// Check modify permissions and whether any selected objects are in +	// the process of being fetched.  If they are, then we're not editable +	if (editable) +	{ +		LLObjectSelection::iterator iter = selected_objects->begin();  +		LLObjectSelection::iterator end = selected_objects->end(); +		for ( ; iter != end; ++iter) +		{ +			LLSelectNode* node = *iter; +			LLVOVolume* object = dynamic_cast<LLVOVolume*>(node->getObject()); +			if (NULL != object) +			{ +				if (!object->permModify() || object->isMediaDataBeingFetched()) +				{ +					editable = false; +					break; +				} +			} +		} +	} +  	// Media settings -	U8 has_media = (U8)0; -	struct media_functor : public LLSelectedTEGetFunctor<U8> +	bool bool_has_media = false; +	struct media_functor : public LLSelectedTEGetFunctor<bool>  	{ -		U8 get(LLViewerObject* object, S32 face) +		bool get(LLViewerObject* object, S32 face)  		{ -			return (object->getTE(face)->getMediaTexGen()); +			LLTextureEntry *te = object->getTE(face); +			if (te) +			{ +				return te->hasMedia(); +			} +			return false;  		}  	} func;  	// check if all faces have media(or, all dont have media) -	LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue( &func, has_media ); -	bool bool_has_media = (has_media & LLTextureEntry::MF_HAS_MEDIA); - +	LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue( &func, bool_has_media );  	const LLMediaEntry default_media_data; diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp index 512104a2f4..986c14acff 100755 --- a/indra/newview/llmediadataclient.cpp +++ b/indra/newview/llmediadataclient.cpp @@ -324,6 +324,22 @@ std::ostream& operator<<(std::ostream &s, const LLMediaDataClient::PriorityQueue  	return s;  } +// find the given object in the queue. +bool LLMediaDataClient::PriorityQueue::find(const LLMediaDataClientObject::ptr_t &obj) const +{ +	std::vector<LLMediaDataClient::request_ptr_t>::const_iterator iter = c.begin(); +	std::vector<LLMediaDataClient::request_ptr_t>::const_iterator end = c.end(); +	while (iter < end) +	{ +		if (obj->getID() == (*iter)->getObject()->getID()) +		{ +			return true; +		} +		iter++; +	} +	return false; +} +  //////////////////////////////////////////////////////////////////////////////////////  //  // LLMediaDataClient::QueueTimer @@ -491,6 +507,11 @@ bool LLMediaDataClient::isEmpty() const  	return (NULL == pRequestQueue) ? true : pRequestQueue->empty();  } +bool LLMediaDataClient::isInQueue(const LLMediaDataClientObject::ptr_t &object) const +{ +	return (NULL == pRequestQueue) ? false : pRequestQueue->find(object); +} +  //////////////////////////////////////////////////////////////////////////////////////  //  // LLObjectMediaDataClient diff --git a/indra/newview/llmediadataclient.h b/indra/newview/llmediadataclient.h index 9d0aa0981e..0d1450ffbe 100755 --- a/indra/newview/llmediadataclient.h +++ b/indra/newview/llmediadataclient.h @@ -89,7 +89,10 @@ public:  	F32 getRetryTimerDelay() const { return mRetryTimerDelay; }  	// Returns true iff the queue is empty -	bool isEmpty() const;  +	bool isEmpty() const; +	 +	// Returns true iff the given object is in the queue +	bool isInQueue(const LLMediaDataClientObject::ptr_t &object) const;  protected:  	// Destructor @@ -206,6 +209,9 @@ private:  		Comparator >  	{  	public: +		// Return whether the given object is in the queue +		bool find(const LLMediaDataClientObject::ptr_t &obj) const; +		  		friend std::ostream& operator<<(std::ostream &s, const PriorityQueue &q);  	}; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 5ac6dcce5a..2def905bbb 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -109,6 +109,7 @@ public:  				{  					result = te->getMediaData()->asLLSD();  					// XXX HACK: workaround bug in asLLSD() where whitelist is not set properly +					// See DEV-41949  					if (!result.has(LLMediaEntry::WHITELIST_KEY))  					{  						result[LLMediaEntry::WHITELIST_KEY] = LLSD::emptyArray(); @@ -1668,6 +1669,13 @@ void LLVOVolume::requestMediaDataUpdate()      sObjectMediaClient->fetchMedia(new LLMediaDataClientObjectImpl(this));  } +bool LLVOVolume::isMediaDataBeingFetched() const +{ +	// I know what I'm doing by const_casting this away: this is just  +	// a wrapper class that is only going to do a lookup. +	return sObjectMediaClient->isInQueue(new LLMediaDataClientObjectImpl(const_cast<LLVOVolume*>(this))); +} +  void LLVOVolume::cleanUpMediaImpls()  {  	// Iterate through our TEs and remove any Impls that are no longer used diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 784ef16ba3..10fc8865fc 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -265,7 +265,10 @@ public:  	bool hasMedia() const;  	LLVector3 getApproximateFaceNormal(U8 face_id); - +	 +	// Returns 'true' iff the media data for this object is in flight +	bool isMediaDataBeingFetched() const; +	  protected:  	S32	computeLODDetail(F32	distance, F32 radius);  	BOOL calcLOD(); diff --git a/indra/newview/tests/llmediadataclient_test.cpp b/indra/newview/tests/llmediadataclient_test.cpp index 445ec7aa34..3ac631d96e 100644 --- a/indra/newview/tests/llmediadataclient_test.cpp +++ b/indra/newview/tests/llmediadataclient_test.cpp @@ -497,5 +497,38 @@ namespace tut  		ensure("REF COUNT", o->getNumRefs(), 1);      } -	 +	template<> template<> +    void mediadataclient_object_t::test<7>() +    { +		// Test LLMediaDataClient::isInQueue() +		LOG_TEST(7); +		 +		LLMediaDataClientObject::ptr_t o1 = new LLMediaDataClientObjectTest( +			_DATA(VALID_OBJECT_ID_1,"3.0","1.0")); +		LLMediaDataClientObject::ptr_t o2 = new LLMediaDataClientObjectTest( +			_DATA(VALID_OBJECT_ID_2,"1.0","1.0")); +		int num_refs_start = o1->getNumRefs(); +		{ +			LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD); +			 +			ensure("not in queue yet 1", ! mdc->isInQueue(o1)); +			ensure("not in queue yet 2", ! mdc->isInQueue(o2)); +			 +			mdc->fetchMedia(o1); +			 +			ensure("is in queue", mdc->isInQueue(o1)); +			ensure("is not in queue", ! mdc->isInQueue(o2)); +			 +			::pump_timers(); +			 +			ensure("not in queue anymore", ! mdc->isInQueue(o1)); +			ensure("still is not in queue", ! mdc->isInQueue(o2)); +			 +			ensure("queue empty", mdc->isEmpty()); +		} +		 +		// Make sure everyone's destroyed properly +		ensure("REF COUNT", o1->getNumRefs(), num_refs_start); +		 +	}  } | 
