void WorkerNavigator::GetUserAgent(nsString& aUserAgent) const { WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); MOZ_ASSERT(workerPrivate); nsRefPtr<GetUserAgentRunnable> runnable = new GetUserAgentRunnable(workerPrivate, aUserAgent); if (!runnable->Dispatch(workerPrivate->GetJSContext())) { JS_ReportPendingException(workerPrivate->GetJSContext()); } }
// static already_AddRefed<IDBOpenDBRequest> IDBOpenDBRequest::CreateForJS(IDBFactory* aFactory, JS::Handle<JSObject*> aScriptOwner) { MOZ_ASSERT(aFactory); aFactory->AssertIsOnOwningThread(); MOZ_ASSERT(aScriptOwner); nsRefPtr<IDBOpenDBRequest> request = new IDBOpenDBRequest(aFactory, nullptr); CaptureCaller(request->mFilename, &request->mLineNo); request->SetScriptOwner(aScriptOwner); if (!NS_IsMainThread()) { WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); MOZ_ASSERT(workerPrivate); workerPrivate->AssertIsOnWorkerThread(); JSContext* cx = workerPrivate->GetJSContext(); MOZ_ASSERT(cx); nsAutoPtr<WorkerFeature> feature(new WorkerFeature(workerPrivate)); if (NS_WARN_IF(!workerPrivate->AddFeature(cx, feature))) { return nullptr; } request->mWorkerFeature = Move(feature); } return request.forget(); }
already_AddRefed<Promise> PushManager::PermissionState(ErrorResult& aRv) { if (mImpl) { MOZ_ASSERT(NS_IsMainThread()); return mImpl->PermissionState(aRv); } WorkerPrivate* worker = GetCurrentThreadWorkerPrivate(); MOZ_ASSERT(worker); worker->AssertIsOnWorkerThread(); nsCOMPtr<nsIGlobalObject> global = worker->GlobalScope(); RefPtr<Promise> p = Promise::Create(global, aRv); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } RefPtr<PromiseWorkerProxy> proxy = PromiseWorkerProxy::Create(worker, p); if (!proxy) { p->MaybeReject(worker->GetJSContext(), JS::UndefinedHandleValue); return p.forget(); } RefPtr<PermissionStateRunnable> r = new PermissionStateRunnable(proxy); NS_DispatchToMainThread(r); return p.forget(); }
void MessagePort::UpdateMustKeepAlive() { if (mState >= eStateDisentangled && mMessages.IsEmpty() && mIsKeptAlive) { mIsKeptAlive = false; if (mWorkerFeature) { WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); MOZ_ASSERT(workerPrivate); workerPrivate->RemoveFeature(workerPrivate->GetJSContext(), mWorkerFeature); mWorkerFeature = nullptr; } if (NS_IsMainThread()) { nsCOMPtr<nsIObserverService> obs = do_GetService("@mozilla.org/observer-service;1"); if (obs) { obs->RemoveObserver(this, "inner-window-destroyed"); } } Release(); return; } if (mState < eStateDisentangled && !mIsKeptAlive) { mIsKeptAlive = true; AddRef(); } }
void BroadcastChannel::Shutdown() { mState = StateClosed; if (mWorkerFeature) { WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); workerPrivate->RemoveFeature(workerPrivate->GetJSContext(), mWorkerFeature); mWorkerFeature = nullptr; } if (mActor) { mActor->SetParent(nullptr); nsRefPtr<TeardownRunnable> runnable = new TeardownRunnable(mActor); NS_DispatchToCurrentThread(runnable); mActor = nullptr; } // If shutdown() is called we have to release the reference if we still keep // it. if (mIsKeptAlive) { mIsKeptAlive = false; Release(); } }
~WorkerFeature() { mWorkerPrivate->AssertIsOnWorkerThread(); MOZ_COUNT_DTOR(IDBOpenDBRequest::WorkerFeature); mWorkerPrivate->RemoveFeature(mWorkerPrivate->GetJSContext(), this); }
void MessagePort::Initialize(const nsID& aUUID, const nsID& aDestinationUUID, uint32_t aSequenceID, bool mNeutered, State aState, ErrorResult& aRv) { MOZ_ASSERT(mIdentifier); mIdentifier->uuid() = aUUID; mIdentifier->destinationUuid() = aDestinationUUID; mIdentifier->sequenceId() = aSequenceID; mState = aState; mNextStep = eNextStepNone; if (mNeutered) { // If this port is neutered we don't want to keep it alive artificially nor // we want to add listeners or workerFeatures. mState = eStateDisentangled; return; } if (mState == eStateEntangling) { ConnectToPBackground(); } else { MOZ_ASSERT(mState == eStateUnshippedEntangled); } // The port has to keep itself alive until it's entangled. UpdateMustKeepAlive(); if (NS_IsMainThread()) { MOZ_ASSERT(GetOwner()); MOZ_ASSERT(GetOwner()->IsInnerWindow()); mInnerID = GetOwner()->WindowID(); nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); if (obs) { obs->AddObserver(this, "inner-window-destroyed", false); } } else { WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); MOZ_ASSERT(workerPrivate); MOZ_ASSERT(!mWorkerFeature); nsAutoPtr<WorkerFeature> feature(new MessagePortFeature(this)); JSContext* cx = workerPrivate->GetJSContext(); if (NS_WARN_IF(!workerPrivate->AddFeature(cx, feature))) { aRv.Throw(NS_ERROR_FAILURE); return; } mWorkerFeature = Move(feature); } }
/* static */ bool BroadcastChannel::IsEnabled(JSContext* aCx, JSObject* aGlobal) { if (NS_IsMainThread()) { return Preferences::GetBool("dom.broadcastChannel.enabled", false); } WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); MOZ_ASSERT(workerPrivate); workerPrivate->AssertIsOnWorkerThread(); nsRefPtr<PrefEnabledRunnable> runnable = new PrefEnabledRunnable(workerPrivate); runnable->Dispatch(workerPrivate->GetJSContext()); return runnable->IsEnabled(); }
void MessagePort::UpdateMustKeepAlive() { if (mState == eStateDisentangled && mIsKeptAlive) { mIsKeptAlive = false; if (mWorkerFeature) { WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); MOZ_ASSERT(workerPrivate); workerPrivate->RemoveFeature(workerPrivate->GetJSContext(), mWorkerFeature); mWorkerFeature = nullptr; } Release(); return; } if (mState < eStateDisentangled && !mIsKeptAlive) { mIsKeptAlive = true; AddRef(); } }
/* static */ already_AddRefed<BroadcastChannel> BroadcastChannel::Constructor(const GlobalObject& aGlobal, const nsAString& aChannel, ErrorResult& aRv) { nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.GetAsSupports()); // Window is null in workers. nsAutoString origin; PrincipalInfo principalInfo; bool privateBrowsing = false; WorkerPrivate* workerPrivate = nullptr; if (NS_IsMainThread()) { nsCOMPtr<nsIGlobalObject> incumbent = mozilla::dom::GetIncumbentGlobal(); if (!incumbent) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } nsIPrincipal* principal = incumbent->PrincipalOrNull(); if (!principal) { aRv.Throw(NS_ERROR_UNEXPECTED); return nullptr; } bool isNullPrincipal; aRv = principal->GetIsNullPrincipal(&isNullPrincipal); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } if (NS_WARN_IF(isNullPrincipal)) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } GetOrigin(principal, origin, aRv); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } aRv = PrincipalToPrincipalInfo(principal, &principalInfo); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } nsIDocument* doc = window->GetExtantDoc(); if (doc) { privateBrowsing = nsContentUtils::IsInPrivateBrowsing(doc); // No bfcache when BroadcastChannel is used. doc->DisallowBFCaching(); } } else { JSContext* cx = aGlobal.Context(); workerPrivate = GetWorkerPrivateFromContext(cx); MOZ_ASSERT(workerPrivate); nsRefPtr<InitializeRunnable> runnable = new InitializeRunnable(workerPrivate, origin, principalInfo, privateBrowsing, aRv); runnable->Dispatch(cx); } if (aRv.Failed()) { return nullptr; } nsRefPtr<BroadcastChannel> bc = new BroadcastChannel(window, principalInfo, origin, aChannel, privateBrowsing); // Register this component to PBackground. PBackgroundChild* actor = BackgroundChild::GetForCurrentThread(); if (actor) { bc->ActorCreated(actor); } else { BackgroundChild::GetOrCreateForCurrentThread(bc); } if (!workerPrivate) { MOZ_ASSERT(window); MOZ_ASSERT(window->IsInnerWindow()); bc->mInnerID = window->WindowID(); // Register as observer for inner-window-destroyed. nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); if (obs) { obs->AddObserver(bc, "inner-window-destroyed", false); } } else { bc->mWorkerFeature = new BroadcastChannelFeature(bc); JSContext* cx = workerPrivate->GetJSContext(); if (NS_WARN_IF(!workerPrivate->AddFeature(cx, bc->mWorkerFeature))) { NS_WARNING("Failed to register the BroadcastChannel worker feature."); bc->mWorkerFeature = nullptr; aRv.Throw(NS_ERROR_FAILURE); return nullptr; } } return bc.forget(); }