From b3659f2eba2a0a43f48e2c395f1a327dc1114098 Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Mon, 9 Jul 2012 17:04:07 -0400 Subject: Safe implementation of the HTTP resource waiter release method. Doesn't use sets or maps and so there's no ordering assumption to be violated when priorities are changed. Should also be faster. Still want to get rid of the ancillary list, however... --- indra/newview/lltexturefetch.cpp | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 214a6099d0..9d3e7eb2b6 100755 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -28,6 +28,7 @@ #include #include +#include #include "llstl.h" @@ -3358,32 +3359,35 @@ void LLTextureFetch::releaseHttpWaiters() if (mHttpWaitResource.empty()) return; - - const size_t limit(mHttpWaitResource.size()); - tids.reserve(limit); - for (wait_http_res_queue_t::iterator iter(mHttpWaitResource.begin()); - mHttpWaitResource.end() != iter; - ++iter) - { - tids.push_back(*iter); - } + tids.reserve(mHttpWaitResource.size()); + tids.assign(mHttpWaitResource.begin(), mHttpWaitResource.end()); } // -Mfnq // Now lookup the UUUIDs to find valid requests and sort - // them in priority order, highest to lowest. - typedef std::set worker_set_t; - worker_set_t tids2; - - for (uuid_vec_t::const_iterator iter(tids.begin()); + // them in priority order, highest to lowest. We're going + // to modify priority later as a side-effect of releasing + // these objects. That, in turn, would violate the partial + // ordering assumption of std::set, std::map, etc. so we + // don't use those containers. We use a vector and an explicit + // sort to keep the containers valid later. + typedef std::vector worker_list_t; + worker_list_t tids2; + + tids2.reserve(tids.size()); + for (uuid_vec_t::iterator iter(tids.begin()); tids.end() != iter; ++iter) { LLTextureFetchWorker * worker(getWorker(* iter)); if (worker) { - tids2.insert(worker); + tids2.push_back(worker); } } + + // Sort into priority order + LLTextureFetchWorker::Compare compare; + std::sort(tids2.begin(), tids2.end(), compare); tids.clear(); // Release workers up to the high water mark. Since we aren't @@ -3391,7 +3395,7 @@ void LLTextureFetch::releaseHttpWaiters() // with other callers. Do defensive things like getting // refreshed counts of requests and checking if someone else // has moved any worker state around.... - for (worker_set_t::iterator iter2(tids2.begin()); + for (worker_list_t::iterator iter2(tids2.begin()); tids2.end() != iter2 && mHttpSemaphore > 0; ++iter2) { -- cgit v1.2.3