Bug 1290951 - Part 2.3: Update the lifecycle of CompareCache. r=bkelly

--HG--
extra : rebase_source : 9fb447f0301d2e4fbef536f783f39939a0fc59b2
This commit is contained in:
Ho-Pang Hsu 2017-05-09 13:07:09 +08:00
Родитель c1fe89f859
Коммит 1fbf9e14ad
1 изменённых файлов: 53 добавлений и 84 удалений

Просмотреть файл

@ -134,8 +134,7 @@ public:
explicit CompareCache(CompareManager* aManager)
: mManager(aManager)
, mState(WaitingForCache)
, mAborted(false)
, mState(WaitingForInitialization)
{
MOZ_ASSERT(aManager);
AssertIsOnMainThread();
@ -143,7 +142,7 @@ public:
nsresult
Initialize(nsIPrincipal* aPrincipal, const nsAString& aURL,
const nsAString& aCacheName);
Cache* const aCache);
void
Abort();
@ -173,7 +172,7 @@ private:
}
void
ManageCacheResult(JSContext* aCx, JS::Handle<JS::Value> aValue);
Finished(nsresult aStatus, bool aInCache);
void
ManageValueResult(JSContext* aCx, JS::Handle<JS::Value> aValue);
@ -185,11 +184,10 @@ private:
nsString mBuffer;
enum {
WaitingForCache,
WaitingForValue
WaitingForInitialization,
WaitingForValue,
Redundant
} mState;
bool mAborted;
};
NS_IMPL_ISUPPORTS(CompareCache, nsIStreamLoaderObserver)
@ -389,7 +387,7 @@ private:
Cleanup();
void
FetchScript()
FetchScript(Cache* const aCache)
{
mCN = new CompareNetwork(this);
nsresult rv = mCN->Initialize(mPrincipal, mURL, mLoadGroup);
@ -397,9 +395,9 @@ private:
Fail(rv);
}
if (!mOldCacheName.IsEmpty()) {
if (aCache) {
mCC = new CompareCache(this);
rv = mCC->Initialize(mPrincipal, mURL, mOldCacheName);
rv = mCC->Initialize(mPrincipal, mURL, aCache);
if (NS_WARN_IF(NS_FAILED(rv))) {
mCN->Abort();
Fail(rv);
@ -484,7 +482,7 @@ private:
}
mState = WaitingForScriptOrComparisonResult;
FetchScript();
FetchScript(mOldCache);
return;
}
@ -863,36 +861,51 @@ CompareNetwork::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aContext
nsresult
CompareCache::Initialize(nsIPrincipal* aPrincipal, const nsAString& aURL,
const nsAString& aCacheName)
Cache* const aCache)
{
MOZ_ASSERT(aPrincipal);
MOZ_ASSERT(aCache);
MOZ_ASSERT(mState == WaitingForInitialization);
AssertIsOnMainThread();
mURL = aURL;
ErrorResult rv;
RefPtr<Promise> promise = mManager->CacheStorage_()->Open(aCacheName, rv);
if (NS_WARN_IF(rv.Failed())) {
MOZ_ASSERT(!rv.IsErrorWithMessage());
return rv.StealNSResult();
RequestOrUSVString request;
request.SetAsUSVString().Rebind(mURL.Data(), mURL.Length());
ErrorResult error;
CacheQueryOptions params;
RefPtr<Promise> promise = aCache->Match(request, params, error);
if (NS_WARN_IF(error.Failed())) {
Finished(error.StealNSResult(), false);
return error.StealNSResult();
}
mState = WaitingForValue;
promise->AppendNativeHandler(this);
return NS_OK;
}
void
CompareCache::Finished(nsresult aStatus, bool aInCache)
{
if (mState != Redundant) {
mState = Redundant;
mManager->CacheFinished(aStatus, aInCache);
}
}
void
CompareCache::Abort()
{
AssertIsOnMainThread();
MOZ_ASSERT(!mAborted);
mAborted = true;
if (mState != Redundant) {
mState = Redundant;
if (mPump) {
mPump->Cancel(NS_BINDING_ABORTED);
mPump = nullptr;
if (mPump) {
mPump->Cancel(NS_BINDING_ABORTED);
mPump = nullptr;
}
}
}
@ -903,12 +916,12 @@ CompareCache::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aContext,
{
AssertIsOnMainThread();
if (mAborted) {
if (mState == Redundant) {
return aStatus;
}
if (NS_WARN_IF(NS_FAILED(aStatus))) {
mManager->CacheFinished(aStatus, false);
Finished(aStatus, false);
return aStatus;
}
@ -919,30 +932,23 @@ CompareCache::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aContext,
NS_LITERAL_STRING("UTF-8"),
nullptr, buffer, len);
if (NS_WARN_IF(NS_FAILED(rv))) {
mManager->CacheFinished(rv, false);
Finished(rv, false);
return rv;
}
mBuffer.Adopt(buffer, len);
mManager->CacheFinished(NS_OK, true);
Finished(NS_OK, true);
return NS_OK;
}
// This class manages 2 promises: 1 is to retrieve cache object, and 2 is for
// the value from the cache. For this reason we have mState to know what
// reject/resolve callback we are handling.
// This class manages only 1 promise: For the value from the cache.
void
CompareCache::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
{
AssertIsOnMainThread();
if (mAborted) {
return;
}
if (mState == WaitingForCache) {
ManageCacheResult(aCx, aValue);
if (mState == Redundant) {
return;
}
@ -955,48 +961,11 @@ CompareCache::RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
{
AssertIsOnMainThread();
if (mAborted) {
if (mState == Redundant) {
return;
}
mManager->CacheFinished(NS_ERROR_FAILURE, false);
}
void
CompareCache::ManageCacheResult(JSContext* aCx, JS::Handle<JS::Value> aValue)
{
AssertIsOnMainThread();
if (NS_WARN_IF(!aValue.isObject())) {
mManager->CacheFinished(NS_ERROR_FAILURE, false);
return;
}
JS::Rooted<JSObject*> obj(aCx, &aValue.toObject());
if (NS_WARN_IF(!obj)) {
mManager->CacheFinished(NS_ERROR_FAILURE, false);
return;
}
Cache* cache = nullptr;
nsresult rv = UNWRAP_OBJECT(Cache, obj, cache);
if (NS_WARN_IF(NS_FAILED(rv))) {
mManager->CacheFinished(rv, false);
return;
}
RequestOrUSVString request;
request.SetAsUSVString().Rebind(mURL.Data(), mURL.Length());
ErrorResult error;
CacheQueryOptions params;
RefPtr<Promise> promise = cache->Match(request, params, error);
if (NS_WARN_IF(error.Failed())) {
mManager->CacheFinished(error.StealNSResult(), false);
return;
}
promise->AppendNativeHandler(this);
mState = WaitingForValue;
Finished(NS_ERROR_FAILURE, false);
}
void
@ -1006,7 +975,7 @@ CompareCache::ManageValueResult(JSContext* aCx, JS::Handle<JS::Value> aValue)
// The cache returns undefined if the object is not stored.
if (aValue.isUndefined()) {
mManager->CacheFinished(NS_OK, false);
Finished(NS_OK, false);
return;
}
@ -1014,14 +983,14 @@ CompareCache::ManageValueResult(JSContext* aCx, JS::Handle<JS::Value> aValue)
JS::Rooted<JSObject*> obj(aCx, &aValue.toObject());
if (NS_WARN_IF(!obj)) {
mManager->CacheFinished(NS_ERROR_FAILURE, false);
Finished(NS_ERROR_FAILURE, false);
return;
}
Response* response = nullptr;
nsresult rv = UNWRAP_OBJECT(Response, obj, response);
if (NS_WARN_IF(NS_FAILED(rv))) {
mManager->CacheFinished(rv, false);
Finished(rv, false);
return;
}
@ -1034,21 +1003,21 @@ CompareCache::ManageValueResult(JSContext* aCx, JS::Handle<JS::Value> aValue)
MOZ_ASSERT(!mPump);
rv = NS_NewInputStreamPump(getter_AddRefs(mPump), inputStream);
if (NS_WARN_IF(NS_FAILED(rv))) {
mManager->CacheFinished(rv, false);
Finished(rv, false);
return;
}
nsCOMPtr<nsIStreamLoader> loader;
rv = NS_NewStreamLoader(getter_AddRefs(loader), this);
if (NS_WARN_IF(NS_FAILED(rv))) {
mManager->CacheFinished(rv, false);
Finished(rv, false);
return;
}
rv = mPump->AsyncRead(loader, nullptr);
if (NS_WARN_IF(NS_FAILED(rv))) {
mPump = nullptr;
mManager->CacheFinished(rv, false);
Finished(rv, false);
return;
}
@ -1059,7 +1028,7 @@ CompareCache::ManageValueResult(JSContext* aCx, JS::Handle<JS::Value> aValue)
rv = rr->RetargetDeliveryTo(sts);
if (NS_WARN_IF(NS_FAILED(rv))) {
mPump = nullptr;
mManager->CacheFinished(rv, false);
Finished(rv, false);
return;
}
}
@ -1108,7 +1077,7 @@ CompareManager::Initialize(nsIPrincipal* aPrincipal,
// Go fetch the script directly without comparison.
mState = WaitingForScriptOrComparisonResult;
FetchScript();
FetchScript(nullptr);
return NS_OK;
}