diff options
Diffstat (limited to 'indra/newview/llviewerassetstorage.cpp')
| -rw-r--r-- | indra/newview/llviewerassetstorage.cpp | 90 | 
1 files changed, 72 insertions, 18 deletions
diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp index e0b64403ef..7842d24279 100644 --- a/indra/newview/llviewerassetstorage.cpp +++ b/indra/newview/llviewerassetstorage.cpp @@ -49,6 +49,9 @@  /// LLViewerAssetRequest  ///---------------------------------------------------------------------------- + // There is also PoolSizeAssetStorage value in setting that should mirror this name +static const std::string VIEWER_ASSET_STORAGE_CORO_POOL = "AssetStorage"; +  /**   * @brief Local class to encapsulate asset fetch requests with a timestamp.   * @@ -127,6 +130,23 @@ LLViewerAssetStorage::LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *  {  } +LLViewerAssetStorage::~LLViewerAssetStorage() +{ +    if (!LLCoprocedureManager::wasDeleted()) +    { +        // This class has dedicated coroutine pool, clean it up, otherwise coroutines will crash later.  +        LLCoprocedureManager::instance().close(VIEWER_ASSET_STORAGE_CORO_POOL); +    } + +    while (mCoroWaitList.size() > 0) +    { +        CoroWaitList &request = mCoroWaitList.front(); +        // Clean up pending downloads, delete request and trigger callbacks +        removeAndCallbackPendingDownloads(request.mId, request.mType, request.mId, request.mType, LL_ERR_NOERR, LLExtStat::NONE); +        mCoroWaitList.pop_front(); +    } +} +  // virtual   void LLViewerAssetStorage::storeAssetData(      const LLTransactionID& tid, @@ -168,7 +188,7 @@ void LLViewerAssetStorage::storeAssetData(                  delete req;                  if (callback)                  { -                    callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_FAILED, LL_EXSTAT_VFS_CORRUPT); +                    callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_FAILED, LLExtStat::VFS_CORRUPT);                  }                  return;              } @@ -209,7 +229,7 @@ void LLViewerAssetStorage::storeAssetData(                      if (callback)                      { -                        callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_VFS_CORRUPT); +                        callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LLExtStat::VFS_CORRUPT);                      }                      return;                  } @@ -236,7 +256,7 @@ void LLViewerAssetStorage::storeAssetData(              reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file didn't exist or was zero length (VFS - can't tell which)" );              if (callback)              { -                callback(asset_id, user_data,  LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_NONEXISTENT_FILE); +                callback(asset_id, user_data,  LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LLExtStat::NONEXISTENT_FILE);              }          }      } @@ -247,7 +267,7 @@ void LLViewerAssetStorage::storeAssetData(          reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_NO_UPSTREAM, __FILE__, __LINE__, "No upstream provider" );          if (callback)          { -            callback(asset_id, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM); +            callback(asset_id, user_data, LL_ERR_CIRCUIT_GONE, LLExtStat::NO_UPSTREAM);          }      }  } @@ -333,11 +353,32 @@ void LLViewerAssetStorage::storeAssetData(          }          if (callback)          { -            callback(asset_id, user_data, LL_ERR_CANNOT_OPEN_FILE, LL_EXSTAT_BLOCKED_FILE); +            callback(asset_id, user_data, LL_ERR_CANNOT_OPEN_FILE, LLExtStat::BLOCKED_FILE);          }      }  } +void LLViewerAssetStorage::checkForTimeouts() +{ +    LLAssetStorage::checkForTimeouts(); + +    // Restore requests +    LLCoprocedureManager* manager = LLCoprocedureManager::getInstance(); +    while (mCoroWaitList.size() > 0 +           && manager->count(VIEWER_ASSET_STORAGE_CORO_POOL) < LLCoprocedureManager::DEFAULT_QUEUE_SIZE) +    { +        CoroWaitList &request = mCoroWaitList.front(); +         +        bool with_http = true; +        bool is_temp = false; +        LLViewerAssetStatsFF::record_enqueue(request.mType, with_http, is_temp); + +        manager->enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL, "LLViewerAssetStorage::assetRequestCoro", +            boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, request.mRequest, request.mId, request.mType, request.mCallback, request.mUserData)); + +        mCoroWaitList.pop_front(); +    } +}  /**   * @brief Allocate and queue an asset fetch request for the viewer @@ -395,12 +436,20 @@ void LLViewerAssetStorage::queueRequestHttp(      // This is the same as the current UDP logic - don't re-request a duplicate.      if (!duplicate)      { -        bool with_http = true; -        bool is_temp = false; -        LLViewerAssetStatsFF::record_enqueue(atype, with_http, is_temp); +        // Coroutine buffer has fixed size (synchronization buffer, so we have no alternatives), so buffer any request above limit +        if (LLCoprocedureManager::instance().count(VIEWER_ASSET_STORAGE_CORO_POOL) < LLCoprocedureManager::DEFAULT_QUEUE_SIZE) +        { +            bool with_http = true; +            bool is_temp = false; +            LLViewerAssetStatsFF::record_enqueue(atype, with_http, is_temp); -        LLCoprocedureManager::instance().enqueueCoprocedure("AssetStorage","LLViewerAssetStorage::assetRequestCoro", -            boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, req, uuid, atype, callback, user_data)); +            LLCoprocedureManager::instance().enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL, "LLViewerAssetStorage::assetRequestCoro", +                boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, req, uuid, atype, callback, user_data)); +        } +        else +        { +            mCoroWaitList.emplace_back(req, uuid, atype, callback, user_data); +        }      }  } @@ -444,13 +493,18 @@ void LLViewerAssetStorage::assetRequestCoro(      mCountStarted++;      S32 result_code = LL_ERR_NOERR; -    LLExtStat ext_status = LL_EXSTAT_NONE; +    LLExtStat ext_status = LLExtStat::NONE; +    if (!gAssetStorage) +    { +        LL_WARNS_ONCE("ViewerAsset") << "Asset request fails: asset storage no longer exists" << LL_ENDL; +        return; +    }      if (!gAgent.getRegion())      {          LL_WARNS_ONCE("ViewerAsset") << "Asset request fails: no region set" << LL_ENDL;          result_code = LL_ERR_ASSET_REQUEST_FAILED; -        ext_status = LL_EXSTAT_NONE; +        ext_status = LLExtStat::NONE;          removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status);  		return;      } @@ -475,7 +529,7 @@ void LLViewerAssetStorage::assetRequestCoro(      {          LL_WARNS_ONCE("ViewerAsset") << "asset request fails: caps received but no viewer asset cap found" << LL_ENDL;          result_code = LL_ERR_ASSET_REQUEST_FAILED; -        ext_status = LL_EXSTAT_NONE; +        ext_status = LLExtStat::NONE;          removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status);  		return;      } @@ -490,7 +544,7 @@ void LLViewerAssetStorage::assetRequestCoro(      LLSD result = httpAdapter->getRawAndSuspend(httpRequest, url, httpOpts); -    if (LLApp::isQuitting()) +    if (LLApp::isQuitting() || !gAssetStorage)      {          // Bail out if result arrives after shutdown has been started.          return; @@ -504,7 +558,7 @@ void LLViewerAssetStorage::assetRequestCoro(      {          LL_DEBUGS("ViewerAsset") << "request failed, status " << status.toTerseString() << LL_ENDL;          result_code = LL_ERR_ASSET_REQUEST_FAILED; -        ext_status = LL_EXSTAT_NONE; +        ext_status = LLExtStat::NONE;      }      else      { @@ -530,13 +584,13 @@ void LLViewerAssetStorage::assetRequestCoro(                  // TODO asset-http: handle error                  LL_WARNS("ViewerAsset") << "Failure in vf.write()" << LL_ENDL;                  result_code = LL_ERR_ASSET_REQUEST_FAILED; -                ext_status = LL_EXSTAT_VFS_CORRUPT; +                ext_status = LLExtStat::VFS_CORRUPT;              }              else if (!vf.rename(uuid, atype))              {                  LL_WARNS("ViewerAsset") << "rename failed" << LL_ENDL;                  result_code = LL_ERR_ASSET_REQUEST_FAILED; -                ext_status = LL_EXSTAT_VFS_CORRUPT; +                ext_status = LLExtStat::VFS_CORRUPT;              }              else              { @@ -548,7 +602,7 @@ void LLViewerAssetStorage::assetRequestCoro(              // TODO asset-http: handle invalid size case  			LL_WARNS("ViewerAsset") << "bad size" << LL_ENDL;              result_code = LL_ERR_ASSET_REQUEST_FAILED; -            ext_status = LL_EXSTAT_NONE; +            ext_status = LLExtStat::NONE;          }      }  | 
