void CacheEntry::InvokeAvailableCallback(Callback const & aCallback) { LOG(("CacheEntry::InvokeAvailableCallback [this=%p, state=%s, cb=%p, r/o=%d, n/w=%d]", this, StateString(mState), aCallback.mCallback.get(), aCallback.mReadOnly, aCallback.mNotWanted)); nsresult rv; uint32_t const state = mState; // When we are here, the entry must be loaded from disk MOZ_ASSERT(state > LOADING || mIsDoomed); bool onAvailThread; rv = aCallback.OnAvailThread(&onAvailThread); if (NS_FAILED(rv)) { LOG((" target thread dead?")); return; } if (!onAvailThread) { // Dispatch to the right thread nsRefPtr<AvailableCallbackRunnable> event = new AvailableCallbackRunnable(this, aCallback); rv = aCallback.mTargetThread->Dispatch(event, nsIEventTarget::DISPATCH_NORMAL); LOG((" redispatched, (rv = 0x%08x)", rv)); return; } if (NS_SUCCEEDED(mFileStatus) && !aCallback.mSecret) { // Let the last-fetched and fetch-count properties be updated. mFile->OnFetched(); } if (mIsDoomed || aCallback.mNotWanted) { LOG((" doomed or not wanted, notifying OCEA with NS_ERROR_CACHE_KEY_NOT_FOUND")); aCallback.mCallback->OnCacheEntryAvailable( nullptr, false, nullptr, NS_ERROR_CACHE_KEY_NOT_FOUND); return; } if (state == READY) { LOG((" ready/has-meta, notifying OCEA with entry and NS_OK")); if (!aCallback.mSecret) { mozilla::MutexAutoLock lock(mLock); BackgroundOp(Ops::FRECENCYUPDATE); } nsRefPtr<CacheEntryHandle> handle = NewHandle(); aCallback.mCallback->OnCacheEntryAvailable( handle, false, nullptr, NS_OK); return; } // R/O callbacks may do revalidation, let them fall through if (aCallback.mReadOnly && !aCallback.mRevalidating) { LOG((" r/o and not ready, notifying OCEA with NS_ERROR_CACHE_KEY_NOT_FOUND")); aCallback.mCallback->OnCacheEntryAvailable( nullptr, false, nullptr, NS_ERROR_CACHE_KEY_NOT_FOUND); return; } // This is a new or potentially non-valid entry and needs to be fetched first. // The CacheEntryHandle blocks other consumers until the channel // either releases the entry or marks metadata as filled or whole entry valid, // i.e. until MetaDataReady() or SetValid() on the entry is called respectively. // Consumer will be responsible to fill or validate the entry metadata and data. nsRefPtr<CacheEntryHandle> handle = NewWriteHandle(); rv = aCallback.mCallback->OnCacheEntryAvailable( handle, state == WRITING, nullptr, NS_OK); if (NS_FAILED(rv)) { LOG((" writing/revalidating failed (0x%08x)", rv)); // Consumer given a new entry failed to take care of the entry. OnHandleClosed(handle); return; } LOG((" writing/revalidating")); }
void CacheEntry::InvokeAvailableCallback(nsICacheEntryOpenCallback* aCallback, bool aReadOnly, bool aNotWanted) { LOG(("CacheEntry::InvokeAvailableCallback [this=%p, state=%s, cb=%p, r/o=%d, n/w=%d]", this, StateString(mState), aCallback, aReadOnly, aNotWanted)); uint32_t const state = mState; // When we are here, the entry must be loaded from disk MOZ_ASSERT(state > LOADING || mIsDoomed); if (!NS_IsMainThread()) { // Must happen on the main thread :( nsRefPtr<AvailableCallbackRunnable> event = new AvailableCallbackRunnable(this, aCallback, aReadOnly, aNotWanted); NS_DispatchToMainThread(event); return; } // This happens only on the main thread / :( / if (mIsDoomed || aNotWanted) { LOG((" doomed or not wanted, notifying OCEA with NS_ERROR_CACHE_KEY_NOT_FOUND")); aCallback->OnCacheEntryAvailable(nullptr, false, nullptr, NS_ERROR_CACHE_KEY_NOT_FOUND); return; } if (state == READY) { LOG((" ready/has-meta, notifying OCEA with entry and NS_OK")); { mozilla::MutexAutoLock lock(mLock); BackgroundOp(Ops::FRECENCYUPDATE); } aCallback->OnCacheEntryAvailable(this, false, nullptr, NS_OK); return; } if (aReadOnly) { LOG((" r/o and not ready, notifying OCEA with NS_ERROR_CACHE_KEY_NOT_FOUND")); aCallback->OnCacheEntryAvailable(nullptr, false, nullptr, NS_ERROR_CACHE_KEY_NOT_FOUND); return; } // This is a new or potentially non-valid entry and needs to be fetched first. // The Handle blocks other consumers until the channel // either releases the entry or marks metadata as filled or whole entry valid, // i.e. until MetaDataReady() or SetValid() on the entry is called respectively. // Consumer will be responsible to fill or validate the entry metadata and data. nsRefPtr<Handle> handle = NewWriteHandle(); nsresult rv = aCallback->OnCacheEntryAvailable(handle, state == WRITING, nullptr, NS_OK); if (NS_FAILED(rv)) { LOG((" writing/revalidating failed (0x%08x)", rv)); // Consumer given a new entry failed to take care of the entry. OnWriterClosed(handle); return; } LOG((" writing/revalidating")); }