From bbb9d4f21b018bfffc41f790aab7b54975504027 Mon Sep 17 00:00:00 2001
From: Rider Linden <rider@lindenlab.com>
Date: Wed, 14 Oct 2015 17:46:24 -0700
Subject: [PATCH] MAINT-5732: Change to the way event polling handles error
 conditions and cancel calls. Refactor any remaining LLCore::HTTPHandlers to
 use boost::shared_ptr Started minor refactor in the materials manager into
 coroutines (unfinished)

---
 indra/llcorehttp/_httpoperation.cpp           |  29 +-
 indra/llcorehttp/_httpoperation.h             |  10 +-
 indra/llcorehttp/_httpreplyqueue.cpp          |   1 -
 indra/llcorehttp/_httpreplyqueue.h            |  17 +-
 indra/llcorehttp/httphandler.h                |   3 +
 indra/llcorehttp/httprequest.cpp              |  38 +-
 indra/llcorehttp/httprequest.h                |  34 +-
 indra/llcrashlogger/llcrashlogger.cpp         |   2 +-
 indra/llmessage/llcorehttputil.cpp            |  28 +-
 indra/llmessage/llcorehttputil.h              |  18 +-
 indra/llmessage/llhttpsdhandler.cpp           |  30 +-
 indra/llmessage/llhttpsdhandler.h             |  19 +-
 indra/newview/llappcorehttp.cpp               |  11 +-
 indra/newview/llappcorehttp.h                 |   2 +-
 indra/newview/lleventpoll.cpp                 |  12 +-
 indra/newview/llinventorymodel.cpp            |   6 +-
 indra/newview/llinventorymodel.h              |   5 +-
 .../llinventorymodelbackgroundfetch.cpp       |  11 +-
 indra/newview/llinventoryobserver.cpp         |   2 +-
 indra/newview/llmaterialmgr.cpp               | 325 ++++++++++++++----
 indra/newview/llmaterialmgr.h                 |   7 +
 indra/newview/llmediadataclient.cpp           |  16 +-
 indra/newview/llmediadataclient.h             |   8 +-
 indra/newview/llmeshrepository.cpp            |  42 ++-
 indra/newview/llmeshrepository.h              |   4 +-
 indra/newview/lltexturefetch.cpp              |  47 ++-
 indra/newview/llviewerinventory.cpp           |   2 +-
 indra/newview/llxmlrpctransaction.cpp         |   4 +-
 28 files changed, 440 insertions(+), 293 deletions(-)

diff --git a/indra/llcorehttp/_httpoperation.cpp b/indra/llcorehttp/_httpoperation.cpp
index fefe561f80e..dc03b059a4b 100755
--- a/indra/llcorehttp/_httpoperation.cpp
+++ b/indra/llcorehttp/_httpoperation.cpp
@@ -57,8 +57,8 @@ namespace LLCore
 
 HttpOperation::HttpOperation()
 	: LLCoreInt::RefCounted(true),
-	  mReplyQueue(NULL),
-	  mUserHandler(NULL),
+	  mReplyQueue(),
+	  mUserHandler(),
 	  mReqPolicy(HttpRequest::DEFAULT_POLICY_ID),
 	  mReqPriority(0U),
 	  mTracing(HTTP_TRACE_OFF)
@@ -69,30 +69,15 @@ HttpOperation::HttpOperation()
 
 HttpOperation::~HttpOperation()
 {
-	setReplyPath(NULL, NULL);
+    setReplyPath(HttpReplyQueue::ptr_t(), HttpHandler::ptr_t());
 }
 
 
-void HttpOperation::setReplyPath(HttpReplyQueue * reply_queue,
-								 HttpHandler * user_handler)
+void HttpOperation::setReplyPath(HttpReplyQueue::ptr_t reply_queue,
+								 HttpHandler::ptr_t user_handler)
 {
-	if (reply_queue != mReplyQueue)
-	{
-		if (mReplyQueue)
-		{
-			mReplyQueue->release();
-		}
-
-		if (reply_queue)
-		{
-			reply_queue->addRef();
-		}
-
-		mReplyQueue = reply_queue;
-	}
-
-	// Not refcounted
-	mUserHandler = user_handler;
+    mReplyQueue.swap(reply_queue);
+	mUserHandler.swap(user_handler);
 }
 
 
diff --git a/indra/llcorehttp/_httpoperation.h b/indra/llcorehttp/_httpoperation.h
index 937a61187de..f677e7aed80 100755
--- a/indra/llcorehttp/_httpoperation.h
+++ b/indra/llcorehttp/_httpoperation.h
@@ -72,6 +72,8 @@ class HttpService;
 class HttpOperation : public LLCoreInt::RefCounted
 {
 public:
+    typedef boost::shared_ptr<HttpReplyQueue> HttpReplyQueuePtr_t;
+
 	/// Threading:  called by consumer thread.
 	HttpOperation();
 
@@ -110,8 +112,8 @@ class HttpOperation : public LLCoreInt::RefCounted
 	///
 	/// Threading:  called by consumer thread.
 	///
-	void setReplyPath(HttpReplyQueue * reply_queue,
-					  HttpHandler * handler);
+	void setReplyPath(HttpReplyQueuePtr_t reply_queue,
+					  HttpHandler::ptr_t handler);
 
 	/// The three possible staging steps in an operation's lifecycle.
 	/// Asynchronous requests like HTTP operations move from the
@@ -163,8 +165,8 @@ class HttpOperation : public LLCoreInt::RefCounted
 	void addAsReply();
 	
 protected:
-	HttpReplyQueue *			mReplyQueue;			// Have refcount
-	HttpHandler *				mUserHandler;			// Naked pointer
+    HttpReplyQueuePtr_t         mReplyQueue;
+	HttpHandler::ptr_t			mUserHandler;
 
 public:
 	// Request Data
diff --git a/indra/llcorehttp/_httpreplyqueue.cpp b/indra/llcorehttp/_httpreplyqueue.cpp
index 558b7bdee9d..912655d3288 100755
--- a/indra/llcorehttp/_httpreplyqueue.cpp
+++ b/indra/llcorehttp/_httpreplyqueue.cpp
@@ -39,7 +39,6 @@ namespace LLCore
 
 
 HttpReplyQueue::HttpReplyQueue()
-	: RefCounted(true)
 {
 }
 
diff --git a/indra/llcorehttp/_httpreplyqueue.h b/indra/llcorehttp/_httpreplyqueue.h
index 4220a09a3b0..7ad65c581ff 100755
--- a/indra/llcorehttp/_httpreplyqueue.h
+++ b/indra/llcorehttp/_httpreplyqueue.h
@@ -58,21 +58,17 @@ class HttpOperation;
 /// will be coded anyway so it shouldn't be too much of a
 /// burden.
 
-class HttpReplyQueue : public LLCoreInt::RefCounted
+class HttpReplyQueue : private boost::noncopyable
 {
-public:
-	/// Caller acquires a Refcount on construction
-	HttpReplyQueue();
 
-protected:
-	virtual ~HttpReplyQueue();							// Use release()
+public:
+    typedef boost::shared_ptr<HttpReplyQueue>   ptr_t;
 
-private:
-	HttpReplyQueue(const HttpReplyQueue &);				// Not defined
-	void operator=(const HttpReplyQueue &);				// Not defined
+	HttpReplyQueue();
+    virtual ~HttpReplyQueue();		
 
 public:
-	typedef std::vector<HttpOperation *> OpContainer;
+    typedef std::vector<HttpOperation *> OpContainer;
 
 	/// Insert an object at the back of the reply queue.
 	///
@@ -96,6 +92,7 @@ class HttpReplyQueue : public LLCoreInt::RefCounted
 	void fetchAll(OpContainer & ops);
 	
 protected:
+
 	OpContainer							mQueue;
 	LLCoreInt::HttpMutex				mQueueMutex;
 	LLCoreInt::HttpConditionVariable	mQueueCV;
diff --git a/indra/llcorehttp/httphandler.h b/indra/llcorehttp/httphandler.h
index 7bc90967030..65e043f5d35 100755
--- a/indra/llcorehttp/httphandler.h
+++ b/indra/llcorehttp/httphandler.h
@@ -58,6 +58,9 @@ class HttpResponse;
 class HttpHandler 
 {
 public:
+    typedef boost::shared_ptr<HttpHandler>  ptr_t;
+    typedef boost::weak_ptr<HttpHandler>    wptr_t;
+
 	virtual ~HttpHandler()
 	{ }
 
diff --git a/indra/llcorehttp/httprequest.cpp b/indra/llcorehttp/httprequest.cpp
index 63233259fb9..8380e48ddbd 100755
--- a/indra/llcorehttp/httprequest.cpp
+++ b/indra/llcorehttp/httprequest.cpp
@@ -55,13 +55,13 @@ namespace LLCore
 
 
 HttpRequest::HttpRequest()
-	: mReplyQueue(NULL),
+	: mReplyQueue(),
 	  mRequestQueue(NULL)
 {
 	mRequestQueue = HttpRequestQueue::instanceOf();
 	mRequestQueue->addRef();
 
-	mReplyQueue = new HttpReplyQueue();
+	mReplyQueue.reset( new HttpReplyQueue() );
 }
 
 
@@ -73,11 +73,7 @@ HttpRequest::~HttpRequest()
 		mRequestQueue = NULL;
 	}
 
-	if (mReplyQueue)
-	{
-		mReplyQueue->release();
-		mReplyQueue = NULL;
-	}
+    mReplyQueue.reset();
 }
 
 
@@ -128,7 +124,7 @@ HttpStatus HttpRequest::setStaticPolicyOption(EPolicyOption opt, policy_t pclass
 }
 
 HttpHandle HttpRequest::setPolicyOption(EPolicyOption opt, policy_t pclass,
-										long value, HttpHandler * handler)
+										long value, HttpHandler::ptr_t handler)
 {
 	HttpStatus status;
 	HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
@@ -156,7 +152,7 @@ HttpHandle HttpRequest::setPolicyOption(EPolicyOption opt, policy_t pclass,
 
 
 HttpHandle HttpRequest::setPolicyOption(EPolicyOption opt, policy_t pclass,
-										const std::string & value, HttpHandler * handler)
+										const std::string & value, HttpHandler::ptr_t handler)
 {
 	HttpStatus status;
 	HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
@@ -199,7 +195,7 @@ HttpHandle HttpRequest::requestGet(policy_t policy_id,
 								   const std::string & url,
                                    const HttpOptions::ptr_t & options,
 								   const HttpHeaders::ptr_t & headers,
-								   HttpHandler * user_handler)
+								   HttpHandler::ptr_t user_handler)
 {
 	HttpStatus status;
 	HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
@@ -233,7 +229,7 @@ HttpHandle HttpRequest::requestGetByteRange(policy_t policy_id,
 											size_t len,
                                             const HttpOptions::ptr_t & options,
 											const HttpHeaders::ptr_t & headers,
-											HttpHandler * user_handler)
+											HttpHandler::ptr_t user_handler)
 {
 	HttpStatus status;
 	HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
@@ -266,7 +262,7 @@ HttpHandle HttpRequest::requestPost(policy_t policy_id,
 									BufferArray * body,
                                     const HttpOptions::ptr_t & options,
 									const HttpHeaders::ptr_t & headers,
-									HttpHandler * user_handler)
+									HttpHandler::ptr_t user_handler)
 {
 	HttpStatus status;
 	HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
@@ -299,7 +295,7 @@ HttpHandle HttpRequest::requestPut(policy_t policy_id,
 								   BufferArray * body,
                                    const HttpOptions::ptr_t & options,
 								   const HttpHeaders::ptr_t & headers,
-								   HttpHandler * user_handler)
+								   HttpHandler::ptr_t user_handler)
 {
 	HttpStatus status;
 	HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
@@ -330,7 +326,7 @@ HttpHandle HttpRequest::requestDelete(policy_t policy_id,
     const std::string & url,
     const HttpOptions::ptr_t & options,
     const HttpHeaders::ptr_t & headers,
-    HttpHandler * user_handler)
+    HttpHandler::ptr_t user_handler)
 {
     HttpStatus status;
     HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
@@ -362,7 +358,7 @@ HttpHandle HttpRequest::requestPatch(policy_t policy_id,
     BufferArray * body,
     const HttpOptions::ptr_t & options,
     const HttpHeaders::ptr_t & headers,
-    HttpHandler * user_handler)
+    HttpHandler::ptr_t user_handler)
 {
     HttpStatus status;
     HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
@@ -393,7 +389,7 @@ HttpHandle HttpRequest::requestCopy(policy_t policy_id,
     const std::string & url,
     const HttpOptions::ptr_t & options,
     const HttpHeaders::ptr_t & headers,
-    HttpHandler * user_handler)
+    HttpHandler::ptr_t user_handler)
 {
     HttpStatus status;
     HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
@@ -424,7 +420,7 @@ HttpHandle HttpRequest::requestMove(policy_t policy_id,
     const std::string & url,
     const HttpOptions::ptr_t & options,
     const HttpHeaders::ptr_t & headers,
-    HttpHandler * user_handler)
+    HttpHandler::ptr_t user_handler)
 {
     HttpStatus status;
     HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
@@ -451,7 +447,7 @@ HttpHandle HttpRequest::requestMove(policy_t policy_id,
 }
 
 
-HttpHandle HttpRequest::requestNoOp(HttpHandler * user_handler)
+HttpHandle HttpRequest::requestNoOp(HttpHandler::ptr_t user_handler)
 {
 	HttpStatus status;
 	HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
@@ -521,7 +517,7 @@ HttpStatus HttpRequest::update(long usecs)
 // Request Management Methods
 // ====================================
 
-HttpHandle HttpRequest::requestCancel(HttpHandle request, HttpHandler * user_handler)
+HttpHandle HttpRequest::requestCancel(HttpHandle request, HttpHandler::ptr_t user_handler)
 {
 	HttpStatus status;
 	HttpHandle ret_handle(LLCORE_HTTP_HANDLE_INVALID);
@@ -543,7 +539,7 @@ HttpHandle HttpRequest::requestCancel(HttpHandle request, HttpHandler * user_han
 
 
 HttpHandle HttpRequest::requestSetPriority(HttpHandle request, priority_t priority,
-										   HttpHandler * handler)
+										   HttpHandler::ptr_t handler)
 {
 	HttpStatus status;
 	HttpHandle ret_handle(LLCORE_HTTP_HANDLE_INVALID);
@@ -609,7 +605,7 @@ HttpStatus HttpRequest::startThread()
 }
 
 
-HttpHandle HttpRequest::requestStopThread(HttpHandler * user_handler)
+HttpHandle HttpRequest::requestStopThread(HttpHandler::ptr_t user_handler)
 {
 	HttpStatus status;
 	HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
diff --git a/indra/llcorehttp/httprequest.h b/indra/llcorehttp/httprequest.h
index 6c2449266f5..2eb3caa11e2 100755
--- a/indra/llcorehttp/httprequest.h
+++ b/indra/llcorehttp/httprequest.h
@@ -238,7 +238,7 @@ class HttpRequest
 
 	/// Prototype for policy based callbacks.  The callback methods will be executed
 	/// on the worker thread so no modifications should be made to the HttpHandler object.
-    typedef boost::function<HttpStatus(const std::string &, HttpHandler const * const, void *)> policyCallback_t;
+    typedef boost::function<HttpStatus(const std::string &, const HttpHandler::ptr_t &, void *)> policyCallback_t;
 
 	/// Set a policy option for a global or class parameter at
 	/// startup time (prior to thread start).
@@ -270,9 +270,9 @@ class HttpRequest
 	/// @return				Handle of dynamic request.  Use @see getStatus() if
 	///						the returned handle is invalid.
 	HttpHandle setPolicyOption(EPolicyOption opt, policy_t pclass, long value,
-							   HttpHandler * handler);
+							   HttpHandler::ptr_t handler);
 	HttpHandle setPolicyOption(EPolicyOption opt, policy_t pclass, const std::string & value,
-							   HttpHandler * handler);
+							   HttpHandler::ptr_t handler);
 
 	/// @}
 
@@ -350,7 +350,7 @@ class HttpRequest
 						  const std::string & url,
                           const HttpOptions::ptr_t & options,
 						  const HttpHeaders::ptr_t & headers,
-						  HttpHandler * handler);
+						  HttpHandler::ptr_t handler);
 
 
 	/// Queue a full HTTP GET request to be issued with a 'Range' header.
@@ -393,7 +393,7 @@ class HttpRequest
 								   size_t len,
                                    const HttpOptions::ptr_t & options,
 								   const HttpHeaders::ptr_t & headers,
-								   HttpHandler * handler);
+								   HttpHandler::ptr_t handler);
 
 
 	/// Queue a full HTTP POST.  Query arguments and body may
@@ -434,7 +434,7 @@ class HttpRequest
 						   BufferArray * body,
                            const HttpOptions::ptr_t & options,
 						   const HttpHeaders::ptr_t & headers,
-						   HttpHandler * handler);
+						   HttpHandler::ptr_t handler);
 
 
 	/// Queue a full HTTP PUT.  Query arguments and body may
@@ -475,7 +475,7 @@ class HttpRequest
 						  BufferArray * body,
                           const HttpOptions::ptr_t & options,
 						  const HttpHeaders::ptr_t & headers,
-						  HttpHandler * handler);
+						  HttpHandler::ptr_t handler);
 
 
     /// Queue a full HTTP DELETE.  Query arguments and body may
@@ -495,7 +495,7 @@ class HttpRequest
             const std::string & url,
             const HttpOptions::ptr_t & options,
             const HttpHeaders::ptr_t & headers,
-            HttpHandler * user_handler);
+            HttpHandler::ptr_t user_handler);
 
     /// Queue a full HTTP PATCH.  Query arguments and body may
     /// be provided.  Caller is responsible for escaping and
@@ -518,7 +518,7 @@ class HttpRequest
             BufferArray * body,
             const HttpOptions::ptr_t & options,
             const HttpHeaders::ptr_t & headers,
-            HttpHandler * user_handler);
+            HttpHandler::ptr_t user_handler);
 
     /// Queue a full HTTP COPY.  Query arguments and body may
     /// be provided.  Caller is responsible for escaping and
@@ -537,7 +537,7 @@ class HttpRequest
             const std::string & url,
             const HttpOptions::ptr_t & options,
             const HttpHeaders::ptr_t & headers,
-            HttpHandler * user_handler);
+            HttpHandler::ptr_t user_handler);
 
     /// Queue a full HTTP MOVE.  Query arguments and body may
     /// be provided.  Caller is responsible for escaping and
@@ -556,7 +556,7 @@ class HttpRequest
             const std::string & url,
             const HttpOptions::ptr_t & options,
             const HttpHeaders::ptr_t & headers,
-            HttpHandler * user_handler);
+            HttpHandler::ptr_t user_handler);
 
     /// Queue a NoOp request.
 	/// The request is queued and serviced by the working thread which
@@ -566,7 +566,7 @@ class HttpRequest
 	/// @param	handler			@see requestGet()
 	/// @return					"
 	///
-	HttpHandle requestNoOp(HttpHandler * handler);
+	HttpHandle requestNoOp(HttpHandler::ptr_t handler);
 
 	/// While all the heavy work is done by the worker thread, notifications
 	/// must be performed in the context of the application thread.  These
@@ -591,7 +591,7 @@ class HttpRequest
 	///
 	/// @{
 	
-	HttpHandle requestCancel(HttpHandle request, HttpHandler *);
+	HttpHandle requestCancel(HttpHandle request, HttpHandler::ptr_t);
 
 	/// Request that a previously-issued request be reprioritized.
 	/// The status of whether the change itself succeeded arrives
@@ -603,7 +603,7 @@ class HttpRequest
 	/// @param	handler			@see requestGet()
 	/// @return					"
 	///
-	HttpHandle requestSetPriority(HttpHandle request, priority_t priority, HttpHandler * handler);
+	HttpHandle requestSetPriority(HttpHandle request, priority_t priority, HttpHandler::ptr_t handler);
 
 	/// @}
 
@@ -641,7 +641,7 @@ class HttpRequest
 	///							As the request cannot be cancelled, the handle
 	///							is generally not useful.
 	///
-	HttpHandle requestStopThread(HttpHandler * handler);
+	HttpHandle requestStopThread(HttpHandler::ptr_t handler);
 
 	/// Queue a Spin request.
 	/// DEBUG/TESTING ONLY.  This puts the worker into a CPU spin for
@@ -658,11 +658,13 @@ class HttpRequest
 	void generateNotification(HttpOperation * op);
 
 private:
+    typedef boost::shared_ptr<HttpReplyQueue> HttpReplyQueuePtr_t;
+
 	/// @name InstanceData
 	///
 	/// @{
 	HttpStatus			mLastReqStatus;
-	HttpReplyQueue *	mReplyQueue;
+    HttpReplyQueuePtr_t	mReplyQueue;
 	HttpRequestQueue *	mRequestQueue;
 	
 	/// @}
diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp
index 6fd4579876f..f240784dc95 100755
--- a/indra/llcrashlogger/llcrashlogger.cpp
+++ b/indra/llcrashlogger/llcrashlogger.cpp
@@ -410,7 +410,7 @@ bool LLCrashLogger::runCrashLogPost(std::string host, LLSD data, std::string msg
 		updateApplication(llformat("%s, try %d...", msg.c_str(), i+1));
 
         LLCoreHttpUtil::requestPostWithLLSD(httpRequest.get(), LLCore::HttpRequest::DEFAULT_POLICY_ID, 0,
-            host, data, httpOpts, LLCore::HttpHeaders::ptr_t(), new LLCrashLoggerHandler);
+            host, data, httpOpts, LLCore::HttpHeaders::ptr_t(), LLCore::HttpHandler::ptr_t(new LLCrashLoggerHandler));
 
         while(!gBreak)
 		{
diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp
index a93bc03edd6..9d3b8fcc1e3 100644
--- a/indra/llmessage/llcorehttputil.cpp
+++ b/indra/llmessage/llcorehttputil.cpp
@@ -109,7 +109,7 @@ HttpHandle requestPostWithLLSD(HttpRequest * request,
     const LLSD & body,
     const HttpOptions::ptr_t &options,
     const HttpHeaders::ptr_t &headers,
-    HttpHandler * handler)
+    const HttpHandler::ptr_t &handler)
 {
     HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
 
@@ -136,7 +136,7 @@ HttpHandle requestPutWithLLSD(HttpRequest * request,
     const LLSD & body,
     const HttpOptions::ptr_t &options,
     const HttpHeaders::ptr_t &headers,
-    HttpHandler * handler)
+    const HttpHandler::ptr_t &handler)
 {
     HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
 
@@ -162,7 +162,7 @@ HttpHandle requestPatchWithLLSD(HttpRequest * request,
     const LLSD & body,
     const HttpOptions::ptr_t &options,
     const HttpHeaders::ptr_t &headers,
-    HttpHandler * handler)
+    const HttpHandler::ptr_t &handler)
 {
     HttpHandle handle(LLCORE_HTTP_HANDLE_INVALID);
 
@@ -253,7 +253,7 @@ void HttpCoroHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespons
 
         LL_WARNS()
             << "\n--------------------------------------------------------------------------\n"
-            << " Error[" << errType << "] cannot access url '" << response->getRequestURL()
+            << " Error[" << status.toTerseString() << "] cannot access url '" << response->getRequestURL()
             << "' because " << status.toString()
             << "\n--------------------------------------------------------------------------"
             << LL_ENDL;
@@ -678,7 +678,7 @@ LLSD HttpCoroutineAdapter::postAndSuspend_(LLCore::HttpRequest::ptr_t &request,
     // pointer from the smart pointer is safe in this case.
     LLCore::HttpHandle hhandle = requestPostWithLLSD(request,
         mPolicyId, mPriority, url, body, options, headers,
-        handler.get());
+        handler);
 
     if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
     {
@@ -801,7 +801,7 @@ LLSD HttpCoroutineAdapter::postAndSuspend_(LLCore::HttpRequest::ptr_t &request,
     // The HTTPCoroHandler does not self delete, so retrieval of a the contained 
     // pointer from the smart pointer is safe in this case.
     LLCore::HttpHandle hhandle = request->requestPost(mPolicyId, mPriority, url, rawbody.get(),
-        options, headers, handler.get());
+        options, headers, handler);
 
     if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
     {
@@ -859,7 +859,7 @@ LLSD HttpCoroutineAdapter::putAndSuspend_(LLCore::HttpRequest::ptr_t &request,
     // pointer from the smart pointer is safe in this case.
     LLCore::HttpHandle hhandle = requestPutWithLLSD(request,
         mPolicyId, mPriority, url, body, options, headers,
-        handler.get());
+        handler);
 
     if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
     {
@@ -885,7 +885,7 @@ LLSD HttpCoroutineAdapter::putAndSuspend_(LLCore::HttpRequest::ptr_t &request,
     // The HTTPCoroHandler does not self delete, so retrieval of a the contained 
     // pointer from the smart pointer is safe in this case.
     LLCore::HttpHandle hhandle = request->requestPut(mPolicyId, mPriority, 
-        url, rawbody.get(), options, headers, handler.get());
+        url, rawbody.get(), options, headers, handler);
 
     if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
     {
@@ -941,7 +941,7 @@ LLSD HttpCoroutineAdapter::getAndSuspend_(LLCore::HttpRequest::ptr_t &request,
     // The HTTPCoroHandler does not self delete, so retrieval of a the contained 
     // pointer from the smart pointer is safe in this case.
     LLCore::HttpHandle hhandle = request->requestGet(mPolicyId, mPriority,
-        url, options, headers, handler.get());
+        url, options, headers, handler);
 
     if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
     {
@@ -987,7 +987,7 @@ LLSD HttpCoroutineAdapter::deleteAndSuspend_(LLCore::HttpRequest::ptr_t &request
     // The HTTPCoroHandler does not self delete, so retrieval of a the contained 
     // pointer from the smart pointer is safe in this case.
     LLCore::HttpHandle hhandle = request->requestDelete(mPolicyId, mPriority,
-        url, options, headers, handler.get());
+        url, options, headers, handler);
 
     if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
     {
@@ -1025,7 +1025,7 @@ LLSD HttpCoroutineAdapter::patchAndSuspend_(LLCore::HttpRequest::ptr_t &request,
     // pointer from the smart pointer is safe in this case.
     LLCore::HttpHandle hhandle = requestPatchWithLLSD(request,
         mPolicyId, mPriority, url, body, options, headers,
-        handler.get());
+        handler);
 
     if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
     {
@@ -1067,7 +1067,7 @@ LLSD HttpCoroutineAdapter::copyAndSuspend_(LLCore::HttpRequest::ptr_t &request,
     // pointer from the smart pointer is safe in this case.
     // 
     LLCore::HttpHandle hhandle = request->requestCopy(mPolicyId, mPriority, url,
-        options, headers, handler.get());
+        options, headers, handler);
 
     if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
     {
@@ -1109,7 +1109,7 @@ LLSD HttpCoroutineAdapter::moveAndSuspend_(LLCore::HttpRequest::ptr_t &request,
     // pointer from the smart pointer is safe in this case.
     // 
     LLCore::HttpHandle hhandle = request->requestMove(mPolicyId, mPriority, url,
-        options, headers, handler.get());
+        options, headers, handler);
 
     if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
     {
@@ -1152,7 +1152,7 @@ void HttpCoroutineAdapter::cancelSuspendedOperation()
     {
         cleanState();
         LL_INFOS() << "Canceling yielding request!" << LL_ENDL;
-        request->requestCancel(mYieldingHandle, handler.get());
+        request->requestCancel(mYieldingHandle, handler);
     }
 }
 
diff --git a/indra/llmessage/llcorehttputil.h b/indra/llmessage/llcorehttputil.h
index 64601551340..0ec17cda078 100644
--- a/indra/llmessage/llcorehttputil.h
+++ b/indra/llmessage/llcorehttputil.h
@@ -114,7 +114,7 @@ LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest * request,
     const LLSD & body,
     const LLCore::HttpOptions::ptr_t &options,
     const LLCore::HttpHeaders::ptr_t &headers,
-    LLCore::HttpHandler * handler);
+    const LLCore::HttpHandler::ptr_t &handler);
 
 inline LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest::ptr_t & request,
 	LLCore::HttpRequest::policy_t policy_id,
@@ -123,7 +123,7 @@ inline LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest::ptr_t & reque
 	const LLSD & body,
 	const LLCore::HttpOptions::ptr_t & options,
 	const LLCore::HttpHeaders::ptr_t & headers,
-	LLCore::HttpHandler * handler)
+    const LLCore::HttpHandler::ptr_t & handler)
 {
     return requestPostWithLLSD(request.get(), policy_id, priority,
         url, body, options, headers, handler);
@@ -134,7 +134,7 @@ inline LLCore::HttpHandle requestPostWithLLSD(LLCore::HttpRequest::ptr_t & reque
     LLCore::HttpRequest::priority_t priority,
     const std::string & url,
     const LLSD & body,
-    LLCore::HttpHandler * handler)
+    const LLCore::HttpHandler::ptr_t &handler)
 {
     LLCore::HttpOptions::ptr_t options;
     LLCore::HttpHeaders::ptr_t headers;
@@ -167,7 +167,7 @@ LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest * request,
 	const LLSD & body,
 	const LLCore::HttpOptions::ptr_t &options,
 	const LLCore::HttpHeaders::ptr_t &headers,
-	LLCore::HttpHandler * handler);
+    const LLCore::HttpHandler::ptr_t &handler);
 
 inline LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t & request,
 	LLCore::HttpRequest::policy_t policy_id,
@@ -176,7 +176,7 @@ inline LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t & reques
 	const LLSD & body,
 	const LLCore::HttpOptions::ptr_t & options,
 	const LLCore::HttpHeaders::ptr_t & headers,
-	LLCore::HttpHandler * handler)
+    LLCore::HttpHandler::ptr_t handler)
 {
     return requestPutWithLLSD(request.get(), policy_id, priority,
         url, body, options, headers, handler);
@@ -187,7 +187,7 @@ inline LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t & reques
     LLCore::HttpRequest::priority_t priority,
     const std::string & url,
     const LLSD & body,
-    LLCore::HttpHandler * handler)
+    LLCore::HttpHandler::ptr_t handler)
 {
     LLCore::HttpOptions::ptr_t options;
     LLCore::HttpHeaders::ptr_t headers;
@@ -219,7 +219,7 @@ LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest * request,
     const LLSD & body,
     const LLCore::HttpOptions::ptr_t &options,
     const LLCore::HttpHeaders::ptr_t &headers,
-    LLCore::HttpHandler * handler);
+    const LLCore::HttpHandler::ptr_t &handler);
 
 inline LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest::ptr_t & request,
     LLCore::HttpRequest::policy_t policy_id,
@@ -228,7 +228,7 @@ inline LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest::ptr_t & requ
     const LLSD & body,
     const LLCore::HttpOptions::ptr_t & options,
     const LLCore::HttpHeaders::ptr_t & headers,
-    LLCore::HttpHandler * handler)
+    const LLCore::HttpHandler::ptr_t & handler)
 {
     return requestPatchWithLLSD(request.get(), policy_id, priority,
         url, body, options, headers, handler);
@@ -239,7 +239,7 @@ inline LLCore::HttpHandle requestPatchWithLLSD(LLCore::HttpRequest::ptr_t & requ
     LLCore::HttpRequest::priority_t priority,
     const std::string & url,
     const LLSD & body,
-    LLCore::HttpHandler * handler)
+    const LLCore::HttpHandler::ptr_t &handler)
 {
     LLCore::HttpOptions::ptr_t options;
     LLCore::HttpHeaders::ptr_t headers;
diff --git a/indra/llmessage/llhttpsdhandler.cpp b/indra/llmessage/llhttpsdhandler.cpp
index d99bdd3f667..648bc5cfd85 100644
--- a/indra/llmessage/llhttpsdhandler.cpp
+++ b/indra/llmessage/llhttpsdhandler.cpp
@@ -36,8 +36,7 @@
 #include "llcorehttputil.h"
 
 //========================================================================
-LLHttpSDHandler::LLHttpSDHandler(bool selfDelete):
-    mSelfDelete(selfDelete)
+LLHttpSDHandler::LLHttpSDHandler()
 {
 }
 
@@ -75,31 +74,4 @@ void LLHttpSDHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespons
 		this->onSuccess(response, resplsd);
 	}
 
-	// The handler must destroy itself when it is done. 
-	// *TODO: I'm not fond of this pattern. A class shooting itself in the head 
-	// outside of a smart pointer always makes me nervous.
-    if (mSelfDelete)
-    	delete this;
-}
-
-//========================================================================
-LLHttpSDGenericHandler::LLHttpSDGenericHandler(const std::string &name, bool selfDelete):
-	LLHttpSDHandler(selfDelete),
-	mName(name)
-{
-}
-
-void LLHttpSDGenericHandler::onSuccess(LLCore::HttpResponse * response, const LLSD &content)
-{
-	LL_DEBUGS() << mName << " Success." << LL_ENDL;
-}
-
-void LLHttpSDGenericHandler::onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status)
-{
-	LL_WARNS()
-		<< "\n--------------------------------------------------------------------------\n"
-		<< mName << " Error[" << status.toULong() << "] cannot access cap with url '" 
-		<< response->getRequestURL() << "' because " << status.toString()
-		<< "\n--------------------------------------------------------------------------"
-		<< LL_ENDL;
 }
diff --git a/indra/llmessage/llhttpsdhandler.h b/indra/llmessage/llhttpsdhandler.h
index 3b81dc66b96..ce40bdfc08f 100644
--- a/indra/llmessage/llhttpsdhandler.h
+++ b/indra/llmessage/llhttpsdhandler.h
@@ -44,29 +44,12 @@ class LLHttpSDHandler : public LLCore::HttpHandler //,
 	virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response);
 	
 protected:
-    LLHttpSDHandler(bool selfDelete = true);
+    LLHttpSDHandler();
 
 	virtual void onSuccess(LLCore::HttpResponse * response, const LLSD &content) = 0;
 	virtual void onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status) = 0;
 
-private:
-    bool mSelfDelete;
 
 };
 
-/// A trivial implementation of LLHttpSDHandler. This success and failure 
-/// methods log the action taken, the URI accessed and the status code returned 
-/// in the response.
-class LLHttpSDGenericHandler : public LLHttpSDHandler
-{
-public: 
-	LLHttpSDGenericHandler(const std::string &name, bool selfDelete = true);
-
-protected:
-	virtual void onSuccess(LLCore::HttpResponse * response, const LLSD &content);
-	virtual void onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status);
-
-private:
-	std::string mName;
-};
 #endif
diff --git a/indra/newview/llappcorehttp.cpp b/indra/newview/llappcorehttp.cpp
index 91a5148e4ce..ee4b91f8f2d 100755
--- a/indra/newview/llappcorehttp.cpp
+++ b/indra/newview/llappcorehttp.cpp
@@ -278,12 +278,19 @@ void setting_changed()
 	LLAppViewer::instance()->getAppCoreHttp().refreshSettings(false);
 }
 
+namespace
+{
+    void NoOpDeletor(LLCore::HttpHandler *)
+    {
+
+    }
+}
 
 void LLAppCoreHttp::requestStop()
 {
 	llassert_always(mRequest);
 
-	mStopHandle = mRequest->requestStopThread(this);
+	mStopHandle = mRequest->requestStopThread(LLCore::HttpHandler::ptr_t(this, NoOpDeletor));
 	if (LLCORE_HTTP_HANDLE_INVALID != mStopHandle)
 	{
 		mStopRequested = LLTimer::getTotalSeconds();
@@ -486,7 +493,7 @@ void LLAppCoreHttp::refreshSettings(bool initial)
 }
 
 LLCore::HttpStatus LLAppCoreHttp::sslVerify(const std::string &url, 
-	LLCore::HttpHandler const * const handler, void *appdata)
+	const LLCore::HttpHandler::ptr_t &handler, void *appdata)
 {
 	X509_STORE_CTX *ctx = static_cast<X509_STORE_CTX *>(appdata);
 	LLCore::HttpStatus result;
diff --git a/indra/newview/llappcorehttp.h b/indra/newview/llappcorehttp.h
index 410d7c6b079..95c138d5982 100755
--- a/indra/newview/llappcorehttp.h
+++ b/indra/newview/llappcorehttp.h
@@ -257,7 +257,7 @@ class LLAppCoreHttp : public LLCore::HttpHandler
 	bool						mPipelined;				// Global setting
 	boost::signals2::connection	mPipelinedSignal;		// Signal for 'HttpPipelining' setting
 
-	static LLCore::HttpStatus	sslVerify(const std::string &uri, LLCore::HttpHandler const * const handler, void *appdata);
+	static LLCore::HttpStatus	sslVerify(const std::string &uri, const LLCore::HttpHandler::ptr_t &handler, void *appdata);
 };
 
 
diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp
index 021d17251d8..40eaba2bac7 100755
--- a/indra/newview/lleventpoll.cpp
+++ b/indra/newview/lleventpoll.cpp
@@ -120,15 +120,19 @@ namespace Details
 
     void LLEventPollImpl::stop()
     {
-        LL_INFOS() << "requesting stop for event poll coroutine <" << mCounter << ">" << LL_ENDL;
         mDone = true;
 
         LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter = mAdapter.lock();
         if (adapter)
         {
+            LL_INFOS() << "requesting stop for event poll coroutine <" << mCounter << ">" << LL_ENDL;
             // cancel the yielding operation if any.
             adapter->cancelSuspendedOperation();
         }
+        else
+        {
+            LL_INFOS() << "Coroutine for poll <" << mCounter << "> previously stopped.  No action taken." << LL_ENDL;
+        }
     }
 
     void LLEventPollImpl::eventPollCoro(std::string url)
@@ -179,6 +183,12 @@ namespace Details
                     LL_WARNS() << "Canceling coroutine" << LL_ENDL;
                     break;
                 }
+                else if (!status.isHttpStatus())
+                {
+                    /// Some LLCore or LIBCurl error was returned.  This is unlikely to be recoverable
+                    LL_WARNS("LLEventPollImpl") << "Critical error from poll request returned from libraries.  Canceling coroutine." << LL_ENDL;
+                    break;
+                }
                 LL_WARNS("LLEventPollImpl") << "<" << counter << "> Error result from LLCoreHttpUtil::HttpCoroHandler. Code "
                     << status.toTerseString() << ": '" << httpResults["message"] << "'" << LL_ENDL;
 
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 53a58aff4c5..ab0df330515 100755
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -2456,7 +2456,7 @@ void LLInventoryModel::handleResponses(bool foreground)
 LLCore::HttpHandle LLInventoryModel::requestPost(bool foreground,
 												 const std::string & url,
 												 const LLSD & body,
-												 LLCore::HttpHandler * handler,
+												 const LLCore::HttpHandler::ptr_t &handler,
 												 const char * const message)
 {
 	if (! mHttpRequestFG)
@@ -2485,7 +2485,6 @@ LLCore::HttpHandle LLInventoryModel::requestPost(bool foreground,
 						  << ", Status: " << status.toTerseString()
 						  << " Reason: '" << status.toString() << "'"
 						  << LL_ENDL;
-		delete handler;
 	}
 	return handle;
 }
@@ -4051,9 +4050,6 @@ void LLInventoryModel::FetchItemHttpHandler::onCompleted(LLCore::HttpHandle hand
 		processData(body_llsd, response);
 	}
 	while (false);
-
-	// Must delete on completion.
-	delete this;
 }
 
 void LLInventoryModel::FetchItemHttpHandler::processData(LLSD & content, LLCore::HttpResponse * response)
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index a74e3b69f48..e1e6db19eba 100755
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -80,6 +80,9 @@ class LLInventoryModel
 	typedef std::vector<LLPointer<LLViewerInventoryItem> > item_array_t;
 	typedef std::set<LLUUID> changed_items_t;
 
+    // Rider: This is using the old responder patter.  It should be refactored to 
+    // take advantage of coroutines.
+
 	// HTTP handler for individual item requests (inventory or library).
 	// Background item requests are derived from this in the background
 	// inventory system.  All folder requests are also located there
@@ -563,7 +566,7 @@ class LLInventoryModel
 	LLCore::HttpHandle requestPost(bool foreground,
 								   const std::string & url,
 								   const LLSD & body,
-								   LLCore::HttpHandler * handler,
+								   const LLCore::HttpHandler::ptr_t &handler,
 								   const char * const message);
 	
 private:
diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp
index 40edb13a802..4a77edc5650 100755
--- a/indra/newview/llinventorymodelbackgroundfetch.cpp
+++ b/indra/newview/llinventorymodelbackgroundfetch.cpp
@@ -513,7 +513,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
 
 				if (! url.empty())
 				{
-					BGFolderHttpHandler * handler(new BGFolderHttpHandler(folder_request_body, recursive_cats));
+                    LLCore::HttpHandler::ptr_t  handler(new BGFolderHttpHandler(folder_request_body, recursive_cats));
 					gInventory.requestPost(false, url, folder_request_body, handler, "Inventory Folder");
 				}
 			}
@@ -524,7 +524,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
 
 				if (! url.empty())
 				{
-					BGFolderHttpHandler * handler(new BGFolderHttpHandler(folder_request_body_lib, recursive_cats));
+                    LLCore::HttpHandler::ptr_t  handler(new BGFolderHttpHandler(folder_request_body_lib, recursive_cats));
 					gInventory.requestPost(false, url, folder_request_body_lib, handler, "Library Folder");
 				}
 			}
@@ -540,7 +540,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
 				{
 					LLSD body;
 					body["items"] = item_request_body;
-					BGItemHttpHandler * handler(new BGItemHttpHandler(body));
+                    LLCore::HttpHandler::ptr_t  handler(new BGItemHttpHandler(body));
 					gInventory.requestPost(false, url, body, handler, "Inventory Item");
 				}
 			}
@@ -553,7 +553,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
 				{
 					LLSD body;
 					body["items"] = item_request_body_lib;
-					BGItemHttpHandler * handler(new BGItemHttpHandler(body));
+                    LLCore::HttpHandler::ptr_t handler(new BGItemHttpHandler(body));
 					gInventory.requestPost(false, url, body, handler, "Library Item");
 				}
 			}
@@ -647,9 +647,6 @@ void BGFolderHttpHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRes
 		processData(body_llsd, response);
 	}
 	while (false);
-
-	// Must delete on completion.
-	delete this;
 }
 
 
diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp
index d81401b59b4..6c813786229 100755
--- a/indra/newview/llinventoryobserver.cpp
+++ b/indra/newview/llinventoryobserver.cpp
@@ -237,7 +237,7 @@ void fetch_items_from_llsd(const LLSD& items_llsd)
 		if (!url.empty())
 		{
 			body[i]["agent_id"]	= gAgent.getID();
-			LLInventoryModel::FetchItemHttpHandler * handler(new LLInventoryModel::FetchItemHttpHandler(body[i]));
+            LLCore::HttpHandler::ptr_t handler(new LLInventoryModel::FetchItemHttpHandler(body[i]));
 			gInventory.requestPost(true, url, body[i], handler, (i ? "Library Item" : "Inventory Item"));
 			continue;
 		}
diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp
index 1045def72ee..6dc05253655 100755
--- a/indra/newview/llmaterialmgr.cpp
+++ b/indra/newview/llmaterialmgr.cpp
@@ -579,46 +579,56 @@ void LLMaterialMgr::onIdle(void*)
 	instancep->mHttpRequest->update(0L);
 }
 
-void LLMaterialMgr::processGetQueue()
+/*static*/
+void LLMaterialMgr::CapsRecvForRegion(const LLUUID& regionId, LLUUID regionTest, std::string pumpname)
 {
-	get_queue_t::iterator loopRegionQueue = mGetQueue.begin();
-	while (mGetQueue.end() != loopRegionQueue)
-	{
-		get_queue_t::iterator itRegionQueue = loopRegionQueue++;
-
-		const LLUUID& region_id = itRegionQueue->first;
-		if (isGetAllPending(region_id))
-		{
-			continue;
-		}
-
-		LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id);
-		if (!regionp)
-		{
-			LL_WARNS("Materials") << "Unknown region with id " << region_id.asString() << LL_ENDL;
-			mGetQueue.erase(itRegionQueue);
-			continue;
-		}
-		else if (!regionp->capabilitiesReceived() || regionp->materialsCapThrottled())
-		{
-			continue;
-		}
-		else if (mGetAllRequested.end() == mGetAllRequested.find(region_id))
-		{
-			LL_DEBUGS("Materials") << "calling getAll for " << regionp->getName() << LL_ENDL;
-			getAll(region_id);
-			continue;
-		}
-
-		const std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME);
-		if (capURL.empty())
-		{
-			LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME
-				<< "' is not defined on region '" << regionp->getName() << "'" << LL_ENDL;
-			mGetQueue.erase(itRegionQueue);
-			continue;
-		}
+    if (regionId == regionTest)
+    {
+        LLEventPumps::instance().obtain(pumpname).post(LLSD());
+    }
+}
 
+void LLMaterialMgr::processGetQueue()
+{
+    get_queue_t::iterator loopRegionQueue = mGetQueue.begin();
+    while (mGetQueue.end() != loopRegionQueue)
+    {
+#if 1
+        get_queue_t::iterator itRegionQueue = loopRegionQueue++;
+
+        const LLUUID& region_id = itRegionQueue->first;
+        if (isGetAllPending(region_id))
+        {
+            continue;
+        }
+
+        LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id);
+        if (!regionp)
+        {
+            LL_WARNS("Materials") << "Unknown region with id " << region_id.asString() << LL_ENDL;
+            mGetQueue.erase(itRegionQueue);
+            continue;
+        }
+        else if (!regionp->capabilitiesReceived() || regionp->materialsCapThrottled())
+        {
+            continue;
+        }
+        else if (mGetAllRequested.end() == mGetAllRequested.find(region_id))
+        {
+            LL_DEBUGS("Materials") << "calling getAll for " << regionp->getName() << LL_ENDL;
+            getAll(region_id);
+            continue;
+        }
+
+        const std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME);
+        if (capURL.empty())
+        {
+            LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME
+                << "' is not defined on region '" << regionp->getName() << "'" << LL_ENDL;
+            mGetQueue.erase(itRegionQueue);
+            continue;
+        }
+        
 		LLSD materialsData = LLSD::emptyArray();
 
 		material_queue_t& materials = itRegionQueue->second;
@@ -652,10 +662,9 @@ void LLMaterialMgr::processGetQueue()
 		LLSD postData = LLSD::emptyMap();
 		postData[MATERIALS_CAP_ZIP_FIELD] = materialBinary;
 
-		LLMaterialHttpHandler * handler = 
-				new LLMaterialHttpHandler("POST",
+        LLCore::HttpHandler::ptr_t handler(new LLMaterialHttpHandler("POST",
 				boost::bind(&LLMaterialMgr::onGetResponse, this, _1, _2, region_id)
-				);
+				));
 
 		LL_DEBUGS("Materials") << "POSTing to region '" << regionp->getName() << "' at '" << capURL << " for " << materialsData.size() << " materials."
 			<< "\ndata: " << ll_pretty_print_sd(materialsData) << LL_ENDL;
@@ -666,7 +675,6 @@ void LLMaterialMgr::processGetQueue()
 
 		if (handle == LLCORE_HTTP_HANDLE_INVALID)
 		{
-			delete handler;
 			LLCore::HttpStatus status = mHttpRequest->getStatus();
 			LL_ERRS("Meterials") << "Failed to execute material POST. Status = " <<
 				status.toULong() << "\"" << status.toString() << "\"" << LL_ENDL;
@@ -674,6 +682,103 @@ void LLMaterialMgr::processGetQueue()
 
 		regionp->resetMaterialsCapThrottle();
 	}
+#endif
+}
+
+void LLMaterialMgr::processGetQueueCoro()
+{
+#if 0
+    get_queue_t::iterator itRegionQueue = loopRegionQueue++;
+
+    const LLUUID& region_id = itRegionQueue->first;
+    if (isGetAllPending(region_id))
+    {
+        continue;
+    }
+
+    LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id);
+    if (!regionp)
+    {
+        LL_WARNS("Materials") << "Unknown region with id " << region_id.asString() << LL_ENDL;
+        mGetQueue.erase(itRegionQueue);
+        continue;
+    }
+    else if (!regionp->capabilitiesReceived() || regionp->materialsCapThrottled())
+    {
+        continue;
+    }
+    else if (mGetAllRequested.end() == mGetAllRequested.find(region_id))
+    {
+        LL_DEBUGS("Materials") << "calling getAll for " << regionp->getName() << LL_ENDL;
+        getAll(region_id);
+        continue;
+    }
+
+    const std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME);
+    if (capURL.empty())
+    {
+        LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME
+            << "' is not defined on region '" << regionp->getName() << "'" << LL_ENDL;
+        mGetQueue.erase(itRegionQueue);
+        continue;
+    }
+
+    LLSD materialsData = LLSD::emptyArray();
+
+    material_queue_t& materials = itRegionQueue->second;
+    U32 max_entries = regionp->getMaxMaterialsPerTransaction();
+    material_queue_t::iterator loopMaterial = materials.begin();
+    while ((materials.end() != loopMaterial) && (materialsData.size() < max_entries))
+    {
+        material_queue_t::iterator itMaterial = loopMaterial++;
+        materialsData.append((*itMaterial).asLLSD());
+        materials.erase(itMaterial);
+        markGetPending(region_id, *itMaterial);
+    }
+    if (materials.empty())
+    {
+        mGetQueue.erase(itRegionQueue);
+    }
+
+    std::string materialString = zip_llsd(materialsData);
+
+    S32 materialSize = materialString.size();
+    if (materialSize <= 0)
+    {
+        LL_ERRS("Materials") << "cannot zip LLSD binary content" << LL_ENDL;
+        return;
+    }
+
+    LLSD::Binary materialBinary;
+    materialBinary.resize(materialSize);
+    memcpy(materialBinary.data(), materialString.data(), materialSize);
+
+    LLSD postData = LLSD::emptyMap();
+    postData[MATERIALS_CAP_ZIP_FIELD] = materialBinary;
+
+    LLMaterialHttpHandler * handler =
+        new LLMaterialHttpHandler("POST",
+        boost::bind(&LLMaterialMgr::onGetResponse, this, _1, _2, region_id)
+        );
+
+    LL_DEBUGS("Materials") << "POSTing to region '" << regionp->getName() << "' at '" << capURL << " for " << materialsData.size() << " materials."
+        << "\ndata: " << ll_pretty_print_sd(materialsData) << LL_ENDL;
+
+    LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest,
+        mHttpPolicy, mHttpPriority, capURL,
+        postData, mHttpOptions, mHttpHeaders, handler);
+
+    if (handle == LLCORE_HTTP_HANDLE_INVALID)
+    {
+        delete handler;
+        LLCore::HttpStatus status = mHttpRequest->getStatus();
+        LL_ERRS("Meterials") << "Failed to execute material POST. Status = " <<
+            status.toULong() << "\"" << status.toString() << "\"" << LL_ENDL;
+    }
+
+    regionp->resetMaterialsCapThrottle();
+#endif
+
 }
 
 void LLMaterialMgr::processGetAllQueue()
@@ -684,6 +789,10 @@ void LLMaterialMgr::processGetAllQueue()
 		getall_queue_t::iterator itRegion = loopRegion++;
 
 		const LLUUID& region_id = *itRegion;
+#if 1
+        LLCoros::instance().launch("LLMaterialMgr::processGetAllQueueCoro", boost::bind(&LLMaterialMgr::processGetAllQueueCoro,
+            this, region_id));
+#else
 		LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(region_id);
 		if (regionp == NULL)
 		{
@@ -723,11 +832,84 @@ void LLMaterialMgr::processGetAllQueue()
 		}
 
 		regionp->resetMaterialsCapThrottle();
-		mGetAllPending.insert(std::pair<LLUUID, F64>(region_id, LLFrameTimer::getTotalSeconds()));
+#endif
+        mGetAllPending.insert(std::pair<LLUUID, F64>(region_id, LLFrameTimer::getTotalSeconds()));
 		mGetAllQueue.erase(itRegion);	// Invalidates region_id
 	}
 }
 
+void LLMaterialMgr::processGetAllQueueCoro(LLUUID regionId)
+{
+    LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(regionId);
+    if (regionp == NULL)
+    {
+        LL_WARNS("Materials") << "Unknown region with id " << regionId.asString() << LL_ENDL;
+        clearGetQueues(regionId);		// Invalidates region_id
+        return;
+    }
+    else if (!regionp->capabilitiesReceived()) 
+    {
+        LLEventStream capsRecv("waitForCaps", true);
+
+        regionp->setCapabilitiesReceivedCallback(
+            boost::bind(&LLMaterialMgr::CapsRecvForRegion,
+            _1, regionId, capsRecv.getName()));
+        
+        llcoro::suspendUntilEventOn(capsRecv);
+
+        // reget the region from the region ID since it may have gone away while waiting.
+        regionp = LLWorld::instance().getRegionFromID(regionId);
+        if (!regionp)
+        {
+            LL_WARNS("Materials") << "Region with ID " << regionId << " is no longer valid." << LL_ENDL;
+            return;
+        }
+    }
+    else if (regionp->materialsCapThrottled())
+    {
+        // TODO:
+        // Figure out how to handle the throttle.
+    }
+
+    std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME);
+    if (capURL.empty())
+    {
+        LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME
+            << "' is not defined on the current region '" << regionp->getName() << "'" << LL_ENDL;
+        clearGetQueues(regionId);		// Invalidates region_id
+        return;
+    }
+
+    LL_DEBUGS("Materials") << "GET all for region " << regionId << "url " << capURL << LL_ENDL;
+
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(
+            new LLCoreHttpUtil::HttpCoroutineAdapter("processGetAllQueue", LLCore::HttpRequest::DEFAULT_POLICY_ID));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest());
+
+    LLSD result = httpAdapter->getAndSuspend(httpRequest, capURL);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        onGetAllResponse(false, LLSD(), regionId);
+    }
+    else
+    {
+        onGetAllResponse(true, result, regionId);
+    }
+
+    // reget the region from the region ID since it may have gone away while waiting.
+    regionp = LLWorld::instance().getRegionFromID(regionId);
+    if (!regionp)
+    {
+        LL_WARNS("Materials") << "Region with ID " << regionId << " is no longer valid." << LL_ENDL;
+        return;
+    }
+    regionp->resetMaterialsCapThrottle();
+}
+
 void LLMaterialMgr::processPutQueue()
 {
 	typedef std::map<LLViewerRegion*, LLSD> regionput_request_map;
@@ -749,34 +931,34 @@ void LLMaterialMgr::processPutQueue()
 		{
 			LLViewerRegion* regionp = objectp->getRegion();
 			if ( !regionp )
-		{
+		    {
 				LL_WARNS("Materials") << "Object region is NULL" << LL_ENDL;
 				mPutQueue.erase(itQueue);
-		}
+		    }
 			else if ( regionp->capabilitiesReceived() && !regionp->materialsCapThrottled())
 			{
-		LLSD& facesData = requests[regionp];
-
-		facematerial_map_t& face_map = itQueue->second;
-				U32 max_entries = regionp->getMaxMaterialsPerTransaction();
-		facematerial_map_t::iterator itFace = face_map.begin();
-				while ( (face_map.end() != itFace) && (facesData.size() < max_entries) )
-		{
-			LLSD faceData = LLSD::emptyMap();
-			faceData[MATERIALS_CAP_FACE_FIELD] = static_cast<LLSD::Integer>(itFace->first);
-			faceData[MATERIALS_CAP_OBJECT_ID_FIELD] = static_cast<LLSD::Integer>(objectp->getLocalID());
-			if (!itFace->second.isNull())
-			{
-				faceData[MATERIALS_CAP_MATERIAL_FIELD] = itFace->second.asLLSD();
-			}
-			facesData.append(faceData);
-			face_map.erase(itFace++);
-		}
-		if (face_map.empty())
-		{
-			mPutQueue.erase(itQueue);
-		}
-	}
+		        LLSD& facesData = requests[regionp];
+
+		        facematerial_map_t& face_map = itQueue->second;
+				        U32 max_entries = regionp->getMaxMaterialsPerTransaction();
+		        facematerial_map_t::iterator itFace = face_map.begin();
+				        while ( (face_map.end() != itFace) && (facesData.size() < max_entries) )
+		        {
+			        LLSD faceData = LLSD::emptyMap();
+			        faceData[MATERIALS_CAP_FACE_FIELD] = static_cast<LLSD::Integer>(itFace->first);
+			        faceData[MATERIALS_CAP_OBJECT_ID_FIELD] = static_cast<LLSD::Integer>(objectp->getLocalID());
+			        if (!itFace->second.isNull())
+			        {
+				        faceData[MATERIALS_CAP_MATERIAL_FIELD] = itFace->second.asLLSD();
+			        }
+			        facesData.append(faceData);
+			        face_map.erase(itFace++);
+		        }
+		        if (face_map.empty())
+		        {
+			        mPutQueue.erase(itQueue);
+		        }
+	        }
 		}
 	}
 
@@ -809,10 +991,9 @@ void LLMaterialMgr::processPutQueue()
 
 			LL_DEBUGS("Materials") << "put for " << itRequest->second.size() << " faces to region " << itRequest->first->getName() << LL_ENDL;
 
-			LLMaterialHttpHandler * handler =
-					new LLMaterialHttpHandler("PUT",
-					boost::bind(&LLMaterialMgr::onPutResponse, this, _1, _2)
-					);
+			LLCore::HttpHandler::ptr_t handler (new LLMaterialHttpHandler("PUT",
+										boost::bind(&LLMaterialMgr::onPutResponse, this, _1, _2)
+										));
 
 			LLCore::HttpHandle handle = LLCoreHttpUtil::requestPutWithLLSD(
 				mHttpRequest, mHttpPolicy, mHttpPriority, capURL,
@@ -820,7 +1001,6 @@ void LLMaterialMgr::processPutQueue()
 
 			if (handle == LLCORE_HTTP_HANDLE_INVALID)
 			{
-				delete handler;
 				LLCore::HttpStatus status = mHttpRequest->getStatus();
 				LL_ERRS("Meterials") << "Failed to execute material PUT. Status = " << 
 					status.toULong() << "\"" << status.toString() << "\"" << LL_ENDL;
@@ -838,6 +1018,7 @@ void LLMaterialMgr::processPutQueue()
 void LLMaterialMgr::clearGetQueues(const LLUUID& region_id)
 {
 	mGetQueue.erase(region_id);
+
 	for (get_pending_map_t::iterator itPending = mGetPending.begin(); itPending != mGetPending.end();)
 	{
 		if (region_id == itPending->first.first)
diff --git a/indra/newview/llmaterialmgr.h b/indra/newview/llmaterialmgr.h
index ef202d24baf..36dd0904b6d 100644
--- a/indra/newview/llmaterialmgr.h
+++ b/indra/newview/llmaterialmgr.h
@@ -67,9 +67,14 @@ class LLMaterialMgr : public LLSingleton<LLMaterialMgr>
 	const LLMaterialPtr setMaterial(const LLUUID& region_id, const LLMaterialID& material_id, const LLSD& material_data);
 
 	static void onIdle(void*);
+
+    static void CapsRecvForRegion(const LLUUID& regionId, LLUUID regionTest, std::string pumpname);
+
 	void processGetQueue();
+    void processGetQueueCoro();
 	void onGetResponse(bool success, const LLSD& content, const LLUUID& region_id);
 	void processGetAllQueue();
+    void processGetAllQueueCoro(LLUUID regionId);
 	void onGetAllResponse(bool success, const LLSD& content, const LLUUID& region_id);
 	void processPutQueue();
 	void onPutResponse(bool success, const LLSD& content);
@@ -116,7 +121,9 @@ class LLMaterialMgr : public LLSingleton<LLMaterialMgr>
 	typedef std::map<U8, LLMaterial> facematerial_map_t;
 	typedef std::map<LLUUID, facematerial_map_t> put_queue_t;
 
+
 	get_queue_t				mGetQueue;
+    uuid_set_t              mRegionGets;
 	get_pending_map_t		mGetPending;
 	get_callback_map_t		mGetCallbacks;
 
diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp
index bfd0700a2f4..bd8f464acd3 100755
--- a/indra/newview/llmediadataclient.cpp
+++ b/indra/newview/llmediadataclient.cpp
@@ -353,14 +353,12 @@ void LLMediaDataClient::serviceQueue()
 		trackRequest(request);
 		
 		// and make the post
-        LLHttpSDHandler *handler = request->createHandler();
+        LLCore::HttpHandler::ptr_t handler = request->createHandler();
         LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest, mHttpPolicy, 0,
             url, sd_payload, mHttpOpts, mHttpHeaders, handler);
 
         if (handle == LLCORE_HTTP_HANDLE_INVALID)
         {
-            // *TODO: Change this metaphore to use boost::shared_ptr<> for handlers.  Requires change in LLCore::HTTP
-            delete handler;
             LLCore::HttpStatus status = mHttpRequest->getStatus();
             LL_WARNS("LLMediaDataClient") << "'" << url << "' request POST failed. Reason "
                 << status.toTerseString() << " \"" << status.toString() << "\"" << LL_ENDL;
@@ -878,9 +876,9 @@ LLSD LLObjectMediaDataClient::RequestGet::getPayload() const
 	return result;
 }
 
-LLHttpSDHandler *LLObjectMediaDataClient::RequestGet::createHandler()
+LLCore::HttpHandler::ptr_t LLObjectMediaDataClient::RequestGet::createHandler()
 {
-	return new LLObjectMediaDataClient::Handler(shared_from_this());
+    return LLCore::HttpHandler::ptr_t(new LLObjectMediaDataClient::Handler(shared_from_this()));
 }
 
 
@@ -914,10 +912,10 @@ LLSD LLObjectMediaDataClient::RequestUpdate::getPayload() const
 	return result;
 }
 
-LLHttpSDHandler *LLObjectMediaDataClient::RequestUpdate::createHandler()
+LLCore::HttpHandler::ptr_t LLObjectMediaDataClient::RequestUpdate::createHandler()
 {
 	// This just uses the base class's responder.
-	return new LLMediaDataClient::Handler(shared_from_this());
+    return LLCore::HttpHandler::ptr_t(new LLMediaDataClient::Handler(shared_from_this()));
 }
 
 void LLObjectMediaDataClient::Handler::onSuccess(LLCore::HttpResponse * response, const LLSD &content)
@@ -1049,9 +1047,9 @@ LLSD LLObjectMediaNavigateClient::RequestNavigate::getPayload() const
 	return result;
 }
 
-LLHttpSDHandler *LLObjectMediaNavigateClient::RequestNavigate::createHandler()
+LLCore::HttpHandler::ptr_t LLObjectMediaNavigateClient::RequestNavigate::createHandler()
 {
-	return new LLObjectMediaNavigateClient::Handler(shared_from_this());
+    return LLCore::HttpHandler::ptr_t(new LLObjectMediaNavigateClient::Handler(shared_from_this()));
 }
 
 void LLObjectMediaNavigateClient::Handler::onSuccess(LLCore::HttpResponse * response, const LLSD &content)
diff --git a/indra/newview/llmediadataclient.h b/indra/newview/llmediadataclient.h
index 9907897613b..58f8bad3e44 100755
--- a/indra/newview/llmediadataclient.h
+++ b/indra/newview/llmediadataclient.h
@@ -124,7 +124,7 @@ class LLMediaDataClient : public LLRefCount
         // Subclasses must implement this to build a payload for their request type.
         virtual LLSD getPayload() const = 0;
         // and must create the correct type of responder.
-        virtual LLHttpSDHandler *createHandler() = 0;
+        virtual LLCore::HttpHandler::ptr_t createHandler() = 0;
 
         virtual std::string getURL() { return ""; }
 
@@ -324,7 +324,7 @@ class LLObjectMediaDataClient : public LLMediaDataClient
 	public:
 		RequestGet(LLMediaDataClientObject *obj, LLMediaDataClient *mdc);
 		/*virtual*/ LLSD getPayload() const;
-        /*virtual*/ LLHttpSDHandler *createHandler();
+        /*virtual*/ LLCore::HttpHandler::ptr_t createHandler();
 	};
 
 	class RequestUpdate: public Request
@@ -332,7 +332,7 @@ class LLObjectMediaDataClient : public LLMediaDataClient
 	public:
 		RequestUpdate(LLMediaDataClientObject *obj, LLMediaDataClient *mdc);
 		/*virtual*/ LLSD getPayload() const;
-        /*virtual*/ LLHttpSDHandler *createHandler();
+        /*virtual*/ LLCore::HttpHandler::ptr_t createHandler();
 	};
 
 	// Returns true iff the queue is empty
@@ -409,7 +409,7 @@ class LLObjectMediaNavigateClient : public LLMediaDataClient
 	public:
 		RequestNavigate(LLMediaDataClientObject *obj, LLMediaDataClient *mdc, U8 texture_index, const std::string &url);
 		/*virtual*/ LLSD getPayload() const;
-        /*virtual*/ LLHttpSDHandler *createHandler();
+        /*virtual*/ LLCore::HttpHandler::ptr_t createHandler();
 		/*virtual*/ std::string getURL() { return mURL; }
 	private:
 		std::string mURL;
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 457053f7131..ad27f2e564e 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -1,3 +1,4 @@
+ptr_t
 /** 
  * @file llmeshrepository.cpp
  * @brief Mesh repository implementation.
@@ -392,6 +393,12 @@ U32 LLMeshRepository::sMaxLockHoldoffs = 0;
 	
 LLDeadmanTimer LLMeshRepository::sQuiescentTimer(15.0, false);	// true -> gather cpu metrics
 
+namespace {
+    void NoOpDeletor(LLCore::HttpHandler *)
+    {
+
+    }
+}
 
 static S32 dump_num = 0;
 std::string make_dump_name(std::string prefix, S32 num)
@@ -538,9 +545,12 @@ S32 LLMeshRepoThread::sRequestWaterLevel = 0;
 //     LLMeshPhysicsShapeHandler
 //   LLMeshUploadThread
 
-class LLMeshHandlerBase : public LLCore::HttpHandler
+class LLMeshHandlerBase : public LLCore::HttpHandler,
+    public boost::enable_shared_from_this<LLMeshHandlerBase>
 {
 public:
+    typedef boost::shared_ptr<LLMeshHandlerBase> ptr_t;
+
 	LOG_CLASS(LLMeshHandlerBase);
 	LLMeshHandlerBase(U32 offset, U32 requested_bytes)
 		: LLCore::HttpHandler(),
@@ -824,12 +834,6 @@ LLMeshRepoThread::~LLMeshRepoThread()
 					   << ", Max Lock Holdoffs:  " << LLMeshRepository::sMaxLockHoldoffs
 					   << LL_ENDL;
 
-	for (http_request_set::iterator iter(mHttpRequestSet.begin());
-		 iter != mHttpRequestSet.end();
-		 ++iter)
-	{
-		delete *iter;
-	}
 	mHttpRequestSet.clear();
     mHttpHeaders.reset();
 
@@ -1161,7 +1165,7 @@ void LLMeshRepoThread::constructUrl(LLUUID mesh_id, std::string * url, int * ver
 // Thread:  repo
 LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url, int cap_version,
 												  size_t offset, size_t len,
-												  LLCore::HttpHandler * handler)
+												  const LLCore::HttpHandler::ptr_t &handler)
 {
 	// Also used in lltexturefetch.cpp
 	static LLCachedControl<bool> disable_range_req(gSavedSettings, "HttpRangeRequestsDisable", false);
@@ -1275,7 +1279,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
 
 			if (!http_url.empty())
 			{
-				LLMeshSkinInfoHandler * handler = new LLMeshSkinInfoHandler(mesh_id, offset, size);
+                LLMeshHandlerBase::ptr_t handler(new LLMeshSkinInfoHandler(mesh_id, offset, size));
 				LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler);
 				if (LLCORE_HTTP_HANDLE_INVALID == handle)
 				{
@@ -1283,7 +1287,6 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
 									   << ".  Reason:  " << mHttpStatus.toString()
 									   << " (" << mHttpStatus.toTerseString() << ")"
 									   << LL_ENDL;
-					delete handler;
 					ret = false;
 				}
 				else
@@ -1369,7 +1372,7 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
 			
 			if (!http_url.empty())
 			{
-				LLMeshDecompositionHandler * handler = new LLMeshDecompositionHandler(mesh_id, offset, size);
+                LLMeshHandlerBase::ptr_t handler(new LLMeshDecompositionHandler(mesh_id, offset, size));
 				LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler);
 				if (LLCORE_HTTP_HANDLE_INVALID == handle)
 				{
@@ -1377,7 +1380,6 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
 									   << ".  Reason:  " << mHttpStatus.toString()
 									   << " (" << mHttpStatus.toTerseString() << ")"
 									   << LL_ENDL;
-					delete handler;
 					ret = false;
 				}
 				else
@@ -1462,7 +1464,7 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
 			
 			if (!http_url.empty())
 			{
-				LLMeshPhysicsShapeHandler * handler = new LLMeshPhysicsShapeHandler(mesh_id, offset, size);
+                LLMeshHandlerBase::ptr_t handler(new LLMeshPhysicsShapeHandler(mesh_id, offset, size));
 				LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler);
 				if (LLCORE_HTTP_HANDLE_INVALID == handle)
 				{
@@ -1470,7 +1472,6 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
 									   << ".  Reason:  " << mHttpStatus.toString()
 									   << " (" << mHttpStatus.toTerseString() << ")"
 									   << LL_ENDL;
-					delete handler;
 					ret = false;
 				}
 				else
@@ -1561,7 +1562,7 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params)
 		//within the first 4KB
 		//NOTE -- this will break of headers ever exceed 4KB		
 
-		LLMeshHeaderHandler * handler = new LLMeshHeaderHandler(mesh_params, 0, MESH_HEADER_SIZE);
+        LLMeshHandlerBase::ptr_t handler(new LLMeshHeaderHandler(mesh_params, 0, MESH_HEADER_SIZE));
 		LLCore::HttpHandle handle = getByteRange(http_url, cap_version, 0, MESH_HEADER_SIZE, handler);
 		if (LLCORE_HTTP_HANDLE_INVALID == handle)
 		{
@@ -1569,7 +1570,6 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params)
 							   << ".  Reason:  " << mHttpStatus.toString()
 							   << " (" << mHttpStatus.toTerseString() << ")"
 							   << LL_ENDL;
-			delete handler;
 			retval = false;
 		}
 		else
@@ -1645,7 +1645,7 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
 			
 			if (!http_url.empty())
 			{
-				LLMeshLODHandler * handler = new LLMeshLODHandler(mesh_params, lod, offset, size);
+                LLMeshHandlerBase::ptr_t handler(new LLMeshLODHandler(mesh_params, lod, offset, size));
 				LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler);
 				if (LLCORE_HTTP_HANDLE_INVALID == handle)
 				{
@@ -1653,7 +1653,6 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
 									   << ".  Reason:  " << mHttpStatus.toString()
 									   << " (" << mHttpStatus.toTerseString() << ")"
 									   << LL_ENDL;
-					delete handler;
 					retval = false;
 				}
 				else
@@ -2456,7 +2455,7 @@ void LLMeshUploadThread::doWholeModelUpload()
 																		body,
 																		mHttpOptions,
 																		mHttpHeaders,
-																		this);
+                                                                        LLCore::HttpHandler::ptr_t(this, &NoOpDeletor));
 		if (LLCORE_HTTP_HANDLE_INVALID == handle)
 		{
 			mHttpStatus = mHttpRequest->getStatus();
@@ -2507,7 +2506,7 @@ void LLMeshUploadThread::requestWholeModelFee()
 																	mModelData,
 																	mHttpOptions,
 																	mHttpHeaders,
-																	this);
+                                                                    LLCore::HttpHandler::ptr_t(this, &NoOpDeletor));
 	if (LLCORE_HTTP_HANDLE_INVALID == handle)
 	{
 		mHttpStatus = mHttpRequest->getStatus();
@@ -2948,8 +2947,7 @@ void LLMeshHandlerBase::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespo
 
 	// Release handler
 common_exit:
-	gMeshRepo.mThread->mHttpRequestSet.erase(this);
-	delete this;		// Must be last statement
+	gMeshRepo.mThread->mHttpRequestSet.erase(this->shared_from_this());
 }
 
 
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index b33497730eb..d35c44397b0 100755
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -283,7 +283,7 @@ class LLMeshRepoThread : public LLThread
 	LLCore::HttpRequest::policy_t		mHttpLargePolicyClass;
 	LLCore::HttpRequest::priority_t		mHttpPriority;
 
-	typedef std::set<LLCore::HttpHandler *> http_request_set;
+	typedef std::set<LLCore::HttpHandler::ptr_t> http_request_set;
 	http_request_set					mHttpRequestSet;			// Outstanding HTTP requests
 
 	std::string mGetMeshCapability;
@@ -351,7 +351,7 @@ class LLMeshRepoThread : public LLThread
 	// Threads:  Repo thread only
 	LLCore::HttpHandle getByteRange(const std::string & url, int cap_version,
 									size_t offset, size_t len, 
-									LLCore::HttpHandler * handler);
+									const LLCore::HttpHandler::ptr_t &handler);
 };
 
 
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 30d90431eaa..61747b606e4 100755
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -254,6 +254,12 @@ static const S32 HTTP_NONPIPE_REQUESTS_LOW_WATER = 20;
 static const S32 HTTP_REQUESTS_RANGE_END_MAX = 20000000;
 
 //////////////////////////////////////////////////////////////////////////////
+namespace
+{
+    void NoOpDeletor(LLCore::HttpHandler *)
+    {
+    }
+}
 
 static const char* e_state_name[] =
 {
@@ -806,16 +812,10 @@ class TFReqSendMetrics : public LLTextureFetch::TFRequest
 	 *							ownership of the copy and disposes of it
 	 *							when done.
 	 */
-	TFReqSendMetrics(const std::string & caps_url,
-					 const LLUUID & session_id,
-					 const LLUUID & agent_id,
-					 LLViewerAssetStats * main_stats)
-		: LLTextureFetch::TFRequest(),
-		  mCapsURL(caps_url),
-		  mSessionID(session_id),
-		  mAgentID(agent_id),
-		  mMainStats(main_stats)
-		{}
+    TFReqSendMetrics(const std::string & caps_url,
+        const LLUUID & session_id,
+        const LLUUID & agent_id,
+        LLViewerAssetStats * main_stats);
 	TFReqSendMetrics & operator=(const TFReqSendMetrics &);	// Not defined
 
 	virtual ~TFReqSendMetrics();
@@ -827,6 +827,9 @@ class TFReqSendMetrics : public LLTextureFetch::TFRequest
 	const LLUUID mSessionID;
 	const LLUUID mAgentID;
 	LLViewerAssetStats * mMainStats;
+
+private:
+    LLCore::HttpHandler::ptr_t  mHandler;
 };
 
 /*
@@ -1569,7 +1572,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 															 mUrl,
 															 options,
 															 mFetcher->mHttpHeaders,
-															 this);
+                                                             LLCore::HttpHandler::ptr_t(this, &NoOpDeletor));
 		}
 		else
 		{
@@ -1582,7 +1585,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 																	  : mRequestedSize,
 																	  options,
 																	  mFetcher->mHttpHeaders,
-																	  this);
+                                                                      LLCore::HttpHandler::ptr_t(this, &NoOpDeletor));
 		}
 		if (LLCORE_HTTP_HANDLE_INVALID == mHttpHandle)
 		{
@@ -3937,9 +3940,6 @@ class AssetReportHandler : public LLCore::HttpHandler
 	}
 }; // end class AssetReportHandler
 
-AssetReportHandler stats_handler;
-
-
 /**
  * Implements the 'Set Region' command.
  *
@@ -3953,6 +3953,18 @@ TFReqSetRegion::doWork(LLTextureFetch *)
 	return true;
 }
 
+TFReqSendMetrics::TFReqSendMetrics(const std::string & caps_url,
+        const LLUUID & session_id,
+        const LLUUID & agent_id,
+        LLViewerAssetStats * main_stats): 
+    LLTextureFetch::TFRequest(),
+    mCapsURL(caps_url),
+    mSessionID(session_id),
+    mAgentID(agent_id),
+    mMainStats(main_stats),
+    mHandler(new AssetReportHandler)
+{}
+
 
 TFReqSendMetrics::~TFReqSendMetrics()
 {
@@ -3971,7 +3983,6 @@ bool
 TFReqSendMetrics::doWork(LLTextureFetch * fetcher)
 {
 	static const U32 report_priority(1);
-	static LLCore::HttpHandler * const handler(fetcher->isQAMode() || true ? &stats_handler : NULL);
 	
 	//if (! gViewerAssetStatsThread1)
 	//	return true;
@@ -4021,7 +4032,7 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)
 											sd,
 											LLCore::HttpOptions::ptr_t(),
 											fetcher->getMetricsHeaders(),
-											handler);
+											mHandler);
 		LLTextureFetch::svMetricsDataBreak = false;
 	}
 	else
@@ -4598,7 +4609,7 @@ S32 LLTextureFetchDebugger::fillCurlQueue()
 																				   requestedSize,
 																				   LLCore::HttpOptions::ptr_t(),
 																				   mHttpHeaders,
-																				   this);
+                                                                                   LLCore::HttpHandler::ptr_t(this, &NoOpDeletor));
 		if (LLCORE_HTTP_HANDLE_INVALID != handle)
 		{
 			mHandleToFetchIndex[handle] = i;
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 573791aca39..0ee873d7a11 100755
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -427,7 +427,7 @@ void LLViewerInventoryItem::fetchFromServer(void) const
 			body["items"][0]["owner_id"]	= mPermissions.getOwner();
 			body["items"][0]["item_id"]		= mUUID;
 
-			LLInventoryModel::FetchItemHttpHandler * handler(new LLInventoryModel::FetchItemHttpHandler(body));
+            LLCore::HttpHandler::ptr_t handler(new LLInventoryModel::FetchItemHttpHandler(body));
 			gInventory.requestPost(true, url, body, handler, "Inventory Item");
 		}
 		else
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index 442ed73c2dd..f8b38669b61 100755
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -175,7 +175,7 @@ class LLXMLRPCTransaction::Handler : public LLCore::HttpHandler
 
 	virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response);
 
-	typedef boost::unique_ptr<LLXMLRPCTransaction::Handler> ptr_t;
+	typedef boost::shared_ptr<LLXMLRPCTransaction::Handler> ptr_t;
 
 private:
 
@@ -390,7 +390,7 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip)
 	mHandler = LLXMLRPCTransaction::Handler::ptr_t(new Handler( mHttpRequest, this ));
 
 	mPostH = mHttpRequest->requestPost(LLCore::HttpRequest::DEFAULT_POLICY_ID, 0, 
-		mURI, body.get(), httpOpts, httpHeaders, mHandler.get());
+		mURI, body.get(), httpOpts, httpHeaders, mHandler);
 
 }
 
-- 
GitLab