diff --git a/indra/llmessage/llexperiencecache.cpp b/indra/llmessage/llexperiencecache.cpp
index 7d96ac4b0256adf9f78614565f9d00c6002faa3c..64c01bd9ebdabb96e94ce3fcbad24c2a87860a18 100644
--- a/indra/llmessage/llexperiencecache.cpp
+++ b/indra/llmessage/llexperiencecache.cpp
@@ -85,15 +85,15 @@ const F64 LLExperienceCache::DEFAULT_EXPIRATION	= 600.0;
 const S32 LLExperienceCache::DEFAULT_QUOTA			= 128; // this is megabytes
 const int LLExperienceCache::SEARCH_PAGE_SIZE     = 30;
 
+bool LLExperienceCache::sShutdown = false;
+
 //=========================================================================
-LLExperienceCache::LLExperienceCache():
-    mShutdown(false)
+LLExperienceCache::LLExperienceCache()
 {
 }
 
 LLExperienceCache::~LLExperienceCache()
 {
-
 }
 
 void LLExperienceCache::initSingleton()
@@ -122,7 +122,7 @@ void LLExperienceCache::cleanup()
     {
         cache_stream << (*this);
     }
-    mShutdown = true;
+    sShutdown = true;
 }
 
 //-------------------------------------------------------------------------
@@ -344,7 +344,7 @@ void LLExperienceCache::requestExperiences()
     ostr << urlBase << "?page_size=" << PAGE_SIZE1;
     RequestQueue_t  requests;
 
-    while (!mRequestQueue.empty())
+    while (!mRequestQueue.empty() && !sShutdown)
     {
         RequestQueue_t::iterator it = mRequestQueue.begin();
         LLUUID key = (*it);
@@ -398,8 +398,6 @@ void LLExperienceCache::idleCoro()
     LL_INFOS("ExperienceCache") << "Launching Experience cache idle coro." << LL_ENDL;
     do 
     {
-        llcoro::suspendUntilTimeout(SECS_BETWEEN_REQUESTS);
-
         if (mEraseExpiredTimer.checkExpirationAndReset(ERASE_EXPIRED_TIMEOUT))
         {
             eraseExpired();
@@ -410,7 +408,9 @@ void LLExperienceCache::idleCoro()
             requestExperiences();
         }
 
-    } while (!mShutdown);
+        llcoro::suspendUntilTimeout(SECS_BETWEEN_REQUESTS);
+
+    } while (!sShutdown);
 
     // The coroutine system will likely be shut down by the time we get to this point
     // (or at least no further cycling will occur on it since the user has decided to quit.)
diff --git a/indra/llmessage/llexperiencecache.h b/indra/llmessage/llexperiencecache.h
index f9ff69c2b6690ebddb9ab59e4555db9bfadbb73e..1c97133723aeca89b512f5a7c2383d110d37a14e 100644
--- a/indra/llmessage/llexperiencecache.h
+++ b/indra/llmessage/llexperiencecache.h
@@ -142,7 +142,7 @@ class LLExperienceCache: public LLSingleton < LLExperienceCache >
     LLFrameTimer    mEraseExpiredTimer;    // Periodically clean out expired entries from the cache
     CapabilityQuery_t mCapability;
     std::string     mCacheFileName;
-    bool            mShutdown;
+    static bool     sShutdown; // control for coroutines, they exist out of LLExperienceCache's scope, so they need a static control
 
     void idleCoro();
 	void eraseExpired();
diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp
index 76e16f5a1fffef3ac7445260f02268a28a2773a9..3aaaaf52f566d1fd85390e2e554c814846dfbe75 100644
--- a/indra/newview/llcompilequeue.cpp
+++ b/indra/newview/llcompilequeue.cpp
@@ -347,6 +347,13 @@ void LLFloaterCompileQueue::processExperienceIdResults(LLSD result, LLUUID paren
 bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloater,
     const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump)
 {
+    if (LLApp::isQuitting())
+    {
+        // Reply from coroutine came on shutdown
+        // We are quiting, don't start any more coroutines!
+        return true;
+    }
+
     LLSD result;
     LLCheckedHandle<LLFloaterCompileQueue> floater(hfloater);
     // Dereferencing floater may fail. If they do they throw LLExeceptionStaleHandle.
@@ -381,6 +388,8 @@ bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloat
         result = llcoro::suspendUntilEventOnWithTimeout(pump, fetch_timeout,
             LLSDMap("timeout", LLSD::Boolean(true)));
 
+        floater.check();
+
         if (result.has("timeout"))
         {   // A timeout filed in the result will always be true if present.
             LLStringUtil::format_map_t args;
@@ -404,6 +413,12 @@ bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloat
 
     }
 
+    if (!gAssetStorage)
+    {
+        // viewer likely is shutting down
+        return true;
+    }
+
     {
         HandleScriptUserData    userData(pump.getName());
 
@@ -468,6 +483,8 @@ bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloat
 
     result = llcoro::suspendUntilEventOnWithTimeout(pump, fetch_timeout, LLSDMap("timeout", LLSD::Boolean(true)));
 
+    floater.check();
+
     if (result.has("timeout"))
     { // A timeout filed in the result will always be true if present.
         LLStringUtil::format_map_t args;
@@ -797,6 +814,7 @@ void LLFloaterScriptQueue::objectScriptProcessingQueueCoro(std::string action, L
                 // but offers no guarantee of doing so.
                 llcoro::suspend();
             }
+            floater.check();
         }
 
         floater->addStringMessage("Done");