void WriteNetworkBufferToNewCache() { AssertIsOnMainThread(); MOZ_ASSERT(mCN); MOZ_ASSERT(mCacheStorage); MOZ_ASSERT(mNewCacheName.IsEmpty()); ErrorResult result; result = serviceWorkerScriptCache::GenerateCacheName(mNewCacheName); if (NS_WARN_IF(result.Failed())) { MOZ_ASSERT(!result.IsErrorWithMessage()); Fail(result.StealNSResult()); return; } RefPtr<Promise> cacheOpenPromise = mCacheStorage->Open(mNewCacheName, result); if (NS_WARN_IF(result.Failed())) { MOZ_ASSERT(!result.IsErrorWithMessage()); Fail(result.StealNSResult()); return; } cacheOpenPromise->AppendNativeHandler(this); }
virtual bool MainThreadRun() override { AssertIsOnMainThread(); // Initialise an AutoJSAPI with the target window. AutoJSAPI jsapi; if (NS_WARN_IF(!jsapi.Init(mBackingStore->GetParentObject()))) { mResult = NS_ERROR_UNEXPECTED; return true; } JSContext* cx = jsapi.cx(); ErrorResult rv; JS::Rooted<JS::Value> value(cx); Read(mBackingStore->GetParentObject(), cx, &value, rv); if (NS_WARN_IF(rv.Failed())) { rv.SuppressException(); mResult = NS_ERROR_DOM_DATA_CLONE_ERR; return true; } RefPtr<Promise> promise = mBackingStore->Add(cx, value, mId, mRevisionId, rv); if (NS_WARN_IF(rv.Failed())) { rv.SuppressException(); mResult = NS_ERROR_FAILURE; return true; } promise->AppendNativeHandler(mPromiseWorkerProxy); return true; }
already_AddRefed<Promise> Cache::AddAll(const GlobalObject& aGlobal, nsTArray<RefPtr<Request>>&& aRequestList, CallerType aCallerType, ErrorResult& aRv) { MOZ_DIAGNOSTIC_ASSERT(mActor); // If there is no work to do, then resolve immediately if (aRequestList.IsEmpty()) { RefPtr<Promise> promise = Promise::Create(mGlobal, aRv); if (NS_WARN_IF(!promise)) { return nullptr; } promise->MaybeResolveWithUndefined(); return promise.forget(); } AutoTArray<RefPtr<Promise>, 256> fetchList; fetchList.SetCapacity(aRequestList.Length()); // Begin fetching each request in parallel. For now, if an error occurs just // abandon our previous fetch calls. In theory we could cancel them in the // future once fetch supports it. for (uint32_t i = 0; i < aRequestList.Length(); ++i) { RequestOrUSVString requestOrString; requestOrString.SetAsRequest() = aRequestList[i]; RefPtr<Promise> fetch = FetchRequest(mGlobal, requestOrString, RequestInit(), aCallerType, aRv); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } fetchList.AppendElement(std::move(fetch)); } RefPtr<Promise> promise = Promise::Create(mGlobal, aRv); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } RefPtr<FetchHandler> handler = new FetchHandler(mActor->GetWorkerHolder(), this, std::move(aRequestList), promise); RefPtr<Promise> fetchPromise = Promise::All(aGlobal.Context(), fetchList, aRv); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } fetchPromise->AppendNativeHandler(handler); return promise.forget(); }
virtual bool MainThreadRun() override { AssertIsOnMainThread(); ErrorResult rv; RefPtr<Promise> promise = mBackingStore->GetLength(rv); promise->AppendNativeHandler(mPromiseWorkerProxy); if (NS_WARN_IF(rv.Failed())) { rv.SuppressException(); mFailed = true; } return true; }
void GetEntryHelper::Run() { MOZ_ASSERT(!mParts.IsEmpty()); ErrorResult rv; RefPtr<Promise> promise = mDirectory->Get(mParts[0], rv); if (NS_WARN_IF(rv.Failed())) { rv.SuppressException(); Error(NS_ERROR_DOM_INVALID_STATE_ERR); return; } mParts.RemoveElementAt(0); promise->AppendNativeHandler(this); }
void JSWindowActor::ReceiveMessageOrQuery( JSContext* aCx, const JSWindowActorMessageMeta& aMetadata, JS::Handle<JS::Value> aData, ErrorResult& aRv) { // The argument which we want to pass to IPC. RootedDictionary<ReceiveMessageArgument> argument(aCx); argument.mObjects = JS_NewPlainObject(aCx); argument.mTarget = this; argument.mName = aMetadata.messageName(); argument.mData = aData; argument.mJson = aData; argument.mSync = false; JS::Rooted<JSObject*> self(aCx, GetWrapper()); JS::Rooted<JSObject*> global(aCx, JS::GetNonCCWObjectGlobal(self)); // We only need to create a promise if we're dealing with a query here. It // will be resolved or rejected once the listener has been called. Our // listener on this promise will then send the reply. RefPtr<Promise> promise; if (aMetadata.kind() == JSWindowActorMessageKind::Query) { promise = Promise::Create(xpc::NativeGlobal(global), aRv); if (NS_WARN_IF(aRv.Failed())) { return; } RefPtr<QueryHandler> handler = new QueryHandler(this, aMetadata); promise->AppendNativeHandler(handler); } // Invoke the actual callback. JS::Rooted<JS::Value> retval(aCx); RefPtr<MessageListener> messageListener = new MessageListener(self, global, nullptr, nullptr); messageListener->ReceiveMessage(argument, &retval, aRv, "JSWindowActor receive message"); // If we have a promise, resolve or reject it respectively. if (promise) { if (aRv.Failed()) { promise->MaybeReject(aRv); } else { promise->MaybeResolve(aCx, retval); } } }
void WriteToCache(Cache* aCache) { AssertIsOnMainThread(); MOZ_ASSERT(aCache); MOZ_ASSERT(mState == WaitingForOpen); ErrorResult result; nsCOMPtr<nsIInputStream> body; result = NS_NewCStringInputStream(getter_AddRefs(body), NS_ConvertUTF16toUTF8(mCN->Buffer())); if (NS_WARN_IF(result.Failed())) { MOZ_ASSERT(!result.IsErrorWithMessage()); Fail(result.StealNSResult()); return; } RefPtr<InternalResponse> ir = new InternalResponse(200, NS_LITERAL_CSTRING("OK")); ir->SetBody(body, mCN->Buffer().Length()); ir->InitChannelInfo(mChannelInfo); if (mPrincipalInfo) { ir->SetPrincipalInfo(Move(mPrincipalInfo)); } RefPtr<Response> response = new Response(aCache->GetGlobalObject(), ir); RequestOrUSVString request; request.SetAsUSVString().Rebind(URL().Data(), URL().Length()); // For now we have to wait until the Put Promise is fulfilled before we can // continue since Cache does not yet support starting a read that is being // written to. RefPtr<Promise> cachePromise = aCache->Put(request, *response, result); if (NS_WARN_IF(result.Failed())) { MOZ_ASSERT(!result.IsErrorWithMessage()); Fail(result.StealNSResult()); return; } mState = WaitingForPut; cachePromise->AppendNativeHandler(this); }
nsresult CompareCache::Initialize(nsIPrincipal* aPrincipal, const nsAString& aURL, const nsAString& aCacheName) { MOZ_ASSERT(aPrincipal); 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(); } promise->AppendNativeHandler(this); return NS_OK; }
NS_IMETHODIMP FetchStreamReader::OnOutputStreamReady(nsIAsyncOutputStream* aStream) { NS_ASSERT_OWNINGTHREAD(FetchStreamReader); MOZ_ASSERT(aStream == mPipeOut); MOZ_ASSERT(mReader); if (mStreamClosed) { return NS_OK; } if (mBuffer) { return WriteBuffer(); } // TODO: We need to verify this is the correct global per the spec. // See bug 1385890. AutoEntryScript aes(mGlobal, "ReadableStreamReader.read", !mWorkerHolder); JS::Rooted<JSObject*> reader(aes.cx(), mReader); JS::Rooted<JSObject*> promise(aes.cx(), JS::ReadableStreamDefaultReaderRead(aes.cx(), reader)); if (NS_WARN_IF(!promise)) { // Let's close the stream. CloseAndRelease(aes.cx(), NS_ERROR_DOM_INVALID_STATE_ERR); return NS_ERROR_FAILURE; } RefPtr<Promise> domPromise = Promise::CreateFromExisting(mGlobal, promise); if (NS_WARN_IF(!domPromise)) { // Let's close the stream. CloseAndRelease(aes.cx(), NS_ERROR_DOM_INVALID_STATE_ERR); return NS_ERROR_FAILURE; } // Let's wait. domPromise->AppendNativeHandler(this); return NS_OK; }
NS_IMETHODIMP FetchStreamReader::OnOutputStreamReady(nsIAsyncOutputStream* aStream) { NS_ASSERT_OWNINGTHREAD(FetchStreamReader); MOZ_ASSERT(aStream == mPipeOut); MOZ_ASSERT(mReader); if (mStreamClosed) { return NS_OK; } if (mBuffer) { return WriteBuffer(); } // Here we can retrieve data from the reader using any global we want because // it is not observable. We want to use the reader's global, which is also the // Response's one. AutoEntryScript aes(mGlobal, "ReadableStreamReader.read", !mWorkerRef); JS::Rooted<JSObject*> reader(aes.cx(), mReader); JS::Rooted<JSObject*> promise( aes.cx(), JS::ReadableStreamDefaultReaderRead(aes.cx(), reader)); if (NS_WARN_IF(!promise)) { // Let's close the stream. CloseAndRelease(aes.cx(), NS_ERROR_DOM_INVALID_STATE_ERR); return NS_ERROR_FAILURE; } RefPtr<Promise> domPromise = Promise::CreateFromExisting(mGlobal, promise); if (NS_WARN_IF(!domPromise)) { // Let's close the stream. CloseAndRelease(aes.cx(), NS_ERROR_DOM_INVALID_STATE_ERR); return NS_ERROR_FAILURE; } // Let's wait. domPromise->AppendNativeHandler(this); return NS_OK; }
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; }
virtual bool MainThreadRun() override { AssertIsOnMainThread(); // Walk up to the containing window. WorkerPrivate* wp = mWorkerPrivate; while (wp->GetParent()) { wp = wp->GetParent(); } nsPIDOMWindowInner* window = wp->GetWindow(); // TODO SharedWorker has null window. Don't need to worry about at this // point, though. if (!window) { mRv.Throw(NS_ERROR_FAILURE); return false; } RefPtr<Promise> promise = Navigator::GetDataStores(window, mName, mOwner, mRv); promise->AppendNativeHandler(mPromiseWorkerProxy); return true; }