TextureClientPool* ClientLayerManager::GetTexturePool(SurfaceFormat aFormat, TextureFlags aFlags) { MOZ_DIAGNOSTIC_ASSERT(!mDestroyed); for (size_t i = 0; i < mTexturePools.Length(); i++) { if (mTexturePools[i]->GetFormat() == aFormat && mTexturePools[i]->GetFlags() == aFlags) { return mTexturePools[i]; } } mTexturePools.AppendElement( new TextureClientPool(aFormat, aFlags, IntSize(gfxPlatform::GetPlatform()->GetTileWidth(), gfxPlatform::GetPlatform()->GetTileHeight()), gfxPrefs::LayersTileMaxPoolSize(), gfxPrefs::LayersTileShrinkPoolTimeout(), mForwarder)); return mTexturePools.LastElement(); }
void ProxyAccessible::Shutdown() { MOZ_DIAGNOSTIC_ASSERT(!IsDoc()); NS_ASSERTION(!mOuterDoc, "Why do we still have a child doc?"); // XXX Ideally this wouldn't be necessary, but it seems OuterDoc accessibles // can be destroyed before the doc they own. if (!mOuterDoc) { uint32_t childCount = mChildren.Length(); for (uint32_t idx = 0; idx < childCount; idx++) mChildren[idx]->Shutdown(); } else { if (mChildren.Length() != 1) MOZ_CRASH("outer doc doesn't own adoc!"); mChildren[0]->AsDoc()->Unbind(); } mChildren.Clear(); ProxyDestroyed(this); mDoc->RemoveAccessible(this); }
/* static */ void FetchStream::WriteIntoReadRequestCallback(JSContext* aCx, JS::HandleObject aStream, void* aUnderlyingSource, uint8_t aFlags, void* aBuffer, size_t aLength, size_t* aByteWritten) { MOZ_DIAGNOSTIC_ASSERT(aUnderlyingSource); MOZ_DIAGNOSTIC_ASSERT(aFlags == FETCH_STREAM_FLAG); MOZ_DIAGNOSTIC_ASSERT(aBuffer); MOZ_DIAGNOSTIC_ASSERT(aByteWritten); RefPtr<FetchStream> stream = static_cast<FetchStream*>(aUnderlyingSource); stream->AssertIsOnOwningThread(); MutexAutoLock lock(stream->mMutex); MOZ_DIAGNOSTIC_ASSERT(stream->mInputStream); MOZ_DIAGNOSTIC_ASSERT(stream->mState == eWriting); stream->mState = eChecking; uint32_t written; nsresult rv = stream->mInputStream->Read(static_cast<char*>(aBuffer), aLength, &written); if (NS_WARN_IF(NS_FAILED(rv))) { stream->ErrorPropagation(aCx, lock, aStream, rv); return; } *aByteWritten = written; if (written == 0) { stream->CloseAndReleaseObjects(aCx, lock, aStream); return; } rv = stream->mInputStream->AsyncWait(stream, 0, 0, stream->mOwningEventTarget); if (NS_WARN_IF(NS_FAILED(rv))) { stream->ErrorPropagation(aCx, lock, aStream, rv); return; } // All good. }
void ChannelMediaDecoder::DownloadProgressed() { MOZ_ASSERT(NS_IsMainThread()); MOZ_DIAGNOSTIC_ASSERT(!IsShutdown()); GetOwner()->DownloadProgressed(); using StatsPromise = MozPromise<MediaStatistics, bool, true>; InvokeAsync(GetStateMachine()->OwnerThread(), __func__, [ playbackStats = mPlaybackStatistics, res = RefPtr<BaseMediaResource>(mResource), duration = mDuration, pos = mPlaybackPosition ]() { auto rate = ComputePlaybackRate(playbackStats, res, duration); UpdatePlaybackRate(rate, res); MediaStatistics stats = GetStatistics(rate, res, pos); return StatsPromise::CreateAndResolve(stats, __func__); }) ->Then( mAbstractMainThread, __func__, [ =, self = RefPtr<ChannelMediaDecoder>(this) ](MediaStatistics aStats) { if (IsShutdown()) { return; } mCanPlayThrough = aStats.CanPlayThrough(); GetStateMachine()->DispatchCanPlayThrough(mCanPlayThrough); mResource->ThrottleReadahead(ShouldThrottleDownload(aStats)); // Update readyState since mCanPlayThrough might have changed. GetOwner()->UpdateReadyState(); }, []() { MOZ_ASSERT_UNREACHABLE("Promise not resolved"); }); }
NS_IMETHOD Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData) override { MOZ_ASSERT(NS_IsMainThread()); MOZ_DIAGNOSTIC_ASSERT(strcmp(aTopic, DOM_WINDOW_DESTROYED_TOPIC) == 0); if (!mStream) { return NS_OK; } nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(mGlobal); if (!SameCOMIdentity(aSubject, window)) { return NS_OK; } // mStream->Close() will call JSStreamConsumer::OnInputStreamReady which may // then destory itself, dropping the last reference to 'this'. RefPtr<WindowStreamOwner> keepAlive(this); mStream->Close(); mStream = nullptr; mGlobal = nullptr; return NS_OK; }
/* static */ already_AddRefed<Promise> FileCreatorHelper::CreateFile( nsIGlobalObject* aGlobalObject, nsIFile* aFile, const ChromeFilePropertyBag& aBag, bool aIsFromNsIFile, ErrorResult& aRv) { MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread()); RefPtr<Promise> promise = Promise::Create(aGlobalObject, aRv); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } nsAutoString path; aRv = aFile->GetPath(path); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } // Register this component to PBackground. mozilla::ipc::PBackgroundChild* actorChild = mozilla::ipc::BackgroundChild::GetOrCreateForCurrentThread(); if (NS_WARN_IF(!actorChild)) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } Maybe<int64_t> lastModified; if (aBag.mLastModified.WasPassed()) { lastModified.emplace(aBag.mLastModified.Value()); } PFileCreatorChild* actor = actorChild->SendPFileCreatorConstructor( path, aBag.mType, aBag.mName, lastModified, aBag.mExistenceCheck, aIsFromNsIFile); static_cast<FileCreatorChild*>(actor)->SetPromise(promise); return promise.forget(); }
nsresult FetchDriver::FinishOnStopRequest(AlternativeDataStreamListener* aAltDataListener) { AssertIsOnMainThread(); // OnStopRequest is not called from channel, that means the main data loading // does not finish yet. Reaching here since alternative data loading finishes. if (!mOnStopRequestCalled) { return NS_OK; } MOZ_DIAGNOSTIC_ASSERT(!mAltDataListener); // Wait for alternative data loading finish if we needed it. if (aAltDataListener && aAltDataListener->Status() == AlternativeDataStreamListener::LOADING) { // For LOADING case, channel holds the reference of altDataListener, no need // to restore it to mAltDataListener. return NS_OK; } if (mObserver) { // From "Main Fetch" step 19.1, 19.2: Process response. if (ShouldCheckSRI(mRequest, mResponse)) { MOZ_ASSERT(mResponse); mObserver->OnResponseAvailable(mResponse); #ifdef DEBUG mResponseAvailableCalled = true; #endif } mObserver->OnResponseEnd(FetchDriverObserver::eByNetworking); mObserver = nullptr; } mChannel = nullptr; return NS_OK; }
NS_IMETHODIMP FetchDriver::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext, nsresult aStatusCode) { AssertIsOnMainThread(); MOZ_DIAGNOSTIC_ASSERT(!mOnStopRequestCalled); mOnStopRequestCalled = true; // main data loading is going to finish, breaking the reference cycle. RefPtr<AlternativeDataStreamListener> altDataListener = mAltDataListener.forget(); // We need to check mObserver, which is nulled by FailWithNetworkError(), // because in the case of "error" redirect mode, aStatusCode may be NS_OK but // mResponse will definitely be null so we must not take the else branch. if (NS_FAILED(aStatusCode) || !mObserver) { nsCOMPtr<nsIAsyncOutputStream> outputStream = do_QueryInterface(mPipeOutputStream); if (outputStream) { outputStream->CloseWithStatus(NS_BINDING_FAILED); } if (altDataListener) { altDataListener->Cancel(); } // We proceed as usual here, since we've already created a successful response // from OnStartRequest. } else { MOZ_ASSERT(mResponse); MOZ_ASSERT(!mResponse->IsError()); // From "Main Fetch" step 19: SRI-part3. if (ShouldCheckSRI(mRequest, mResponse)) { MOZ_ASSERT(mSRIDataVerifier); nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest); nsIConsoleReportCollector* reporter = nullptr; if (mObserver) { reporter = mObserver->GetReporter(); } nsAutoCString sourceUri; if (mDocument && mDocument->GetDocumentURI()) { mDocument->GetDocumentURI()->GetAsciiSpec(sourceUri); } else if (!mWorkerScript.IsEmpty()) { sourceUri.Assign(mWorkerScript); } nsresult rv = mSRIDataVerifier->Verify(mSRIMetadata, channel, sourceUri, reporter); if (NS_FAILED(rv)) { if (altDataListener) { altDataListener->Cancel(); } FailWithNetworkError(rv); // Cancel request. return rv; } } if (mPipeOutputStream) { mPipeOutputStream->Close(); } } return FinishOnStopRequest(altDataListener); }
/* static */ already_AddRefed<File> File::CreateFromFile(nsISupports* aParent, nsIFile* aFile) { MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess()); RefPtr<File> file = new File(aParent, new FileBlobImpl(aFile)); return file.forget(); }
MP4Metadata::ResultAndTrackCount MP4Metadata::GetNumberTracks( mozilla::TrackInfo::TrackType aType) const { uint32_t tracks; auto rv = mp4parse_get_track_count(mParser.get(), &tracks); if (rv != MP4PARSE_STATUS_OK) { MOZ_LOG(gMP4MetadataLog, LogLevel::Warning, ("rust parser error %d counting tracks", rv)); return {MediaResult(NS_ERROR_DOM_MEDIA_METADATA_ERR, RESULT_DETAIL("Rust parser error %d", rv)), MP4Metadata::NumberTracksError()}; } uint32_t total = 0; for (uint32_t i = 0; i < tracks; ++i) { Mp4parseTrackInfo track_info; rv = mp4parse_get_track_info(mParser.get(), i, &track_info); if (rv != MP4PARSE_STATUS_OK) { continue; } if (track_info.track_type == MP4PARSE_TRACK_TYPE_AUDIO) { Mp4parseTrackAudioInfo audio; auto rv = mp4parse_get_track_audio_info(mParser.get(), i, &audio); if (rv != MP4PARSE_STATUS_OK) { MOZ_LOG(gMP4MetadataLog, LogLevel::Warning, ("mp4parse_get_track_audio_info returned error %d", rv)); continue; } MOZ_DIAGNOSTIC_ASSERT(audio.sample_info_count > 0, "Must have at least one audio sample info"); if (audio.sample_info_count == 0) { return { MediaResult( NS_ERROR_DOM_MEDIA_METADATA_ERR, RESULT_DETAIL( "Got 0 audio sample info while checking number tracks")), MP4Metadata::NumberTracksError()}; } // We assume the codec of the first sample info is representative of the // whole track and skip it if we don't recognize the codec. if (audio.sample_info[0].codec_type == MP4PARSE_CODEC_UNKNOWN) { continue; } } else if (track_info.track_type == MP4PARSE_TRACK_TYPE_VIDEO) { Mp4parseTrackVideoInfo video; auto rv = mp4parse_get_track_video_info(mParser.get(), i, &video); if (rv != MP4PARSE_STATUS_OK) { MOZ_LOG(gMP4MetadataLog, LogLevel::Warning, ("mp4parse_get_track_video_info returned error %d", rv)); continue; } MOZ_DIAGNOSTIC_ASSERT(video.sample_info_count > 0, "Must have at least one video sample info"); if (video.sample_info_count == 0) { return { MediaResult( NS_ERROR_DOM_MEDIA_METADATA_ERR, RESULT_DETAIL( "Got 0 video sample info while checking number tracks")), MP4Metadata::NumberTracksError()}; } // We assume the codec of the first sample info is representative of the // whole track and skip it if we don't recognize the codec. if (video.sample_info[0].codec_type == MP4PARSE_CODEC_UNKNOWN) { continue; } } else { // Only audio and video are supported continue; } if (TrackTypeEqual(aType, track_info.track_type)) { total += 1; } } MOZ_LOG(gMP4MetadataLog, LogLevel::Info, ("%s tracks found: %u", TrackTypeToString(aType), total)); return {NS_OK, total}; }
ServiceWorkerCloneData::ServiceWorkerCloneData() : mEventTarget(GetCurrentThreadSerialEventTarget()) { MOZ_DIAGNOSTIC_ASSERT(mEventTarget); }
void ResizeObserverNotificationHelper::WillRefresh(TimeStamp aTime) { MOZ_DIAGNOSTIC_ASSERT(mOwner, "Should've de-registered on-time!"); mOwner->Notify(); // Note that mOwner may be null / dead here. }
NS_IMETHODIMP PostMessageEvent::Run() { MOZ_ASSERT(mTargetWindow->IsOuterWindow(), "should have been passed an outer window!"); MOZ_ASSERT(!mSource || mSource->IsOuterWindow(), "should have been passed an outer window!"); // Note: We don't init this AutoJSAPI with targetWindow, because we do not // want exceptions during message deserialization to trigger error events on // targetWindow. AutoJSAPI jsapi; jsapi.Init(); JSContext* cx = jsapi.cx(); // The document is just used for the principal mismatch error message below. // Use a stack variable so mSourceDocument is not held onto after this method // finishes, regardless of the method outcome. nsCOMPtr<nsIDocument> sourceDocument; sourceDocument.swap(mSourceDocument); // If we bailed before this point we're going to leak mMessage, but // that's probably better than crashing. RefPtr<nsGlobalWindow> targetWindow; if (mTargetWindow->IsClosedOrClosing() || !(targetWindow = mTargetWindow->GetCurrentInnerWindowInternal()) || targetWindow->IsClosedOrClosing()) return NS_OK; MOZ_ASSERT(targetWindow->IsInnerWindow(), "we ordered an inner window!"); JSAutoCompartment ac(cx, targetWindow->GetWrapper()); // Ensure that any origin which might have been provided is the origin of this // window's document. Note that we do this *now* instead of when postMessage // is called because the target window might have been navigated to a // different location between then and now. If this check happened when // postMessage was called, it would be fairly easy for a malicious webpage to // intercept messages intended for another site by carefully timing navigation // of the target window so it changed location after postMessage but before // now. if (mProvidedPrincipal) { // Get the target's origin either from its principal or, in the case the // principal doesn't carry a URI (e.g. the system principal), the target's // document. nsIPrincipal* targetPrin = targetWindow->GetPrincipal(); if (NS_WARN_IF(!targetPrin)) return NS_OK; // Note: This is contrary to the spec with respect to file: URLs, which // the spec groups into a single origin, but given we intentionally // don't do that in other places it seems better to hold the line for // now. Long-term, we want HTML5 to address this so that we can // be compliant while being safer. if (!BasePrincipal::Cast(targetPrin)->EqualsIgnoringAddonId(mProvidedPrincipal)) { nsAutoString providedOrigin, targetOrigin; nsresult rv = nsContentUtils::GetUTFOrigin(targetPrin, targetOrigin); NS_ENSURE_SUCCESS(rv, rv); rv = nsContentUtils::GetUTFOrigin(mProvidedPrincipal, providedOrigin); NS_ENSURE_SUCCESS(rv, rv); MOZ_DIAGNOSTIC_ASSERT(providedOrigin != targetOrigin || (BasePrincipal::Cast(mProvidedPrincipal)->OriginAttributesRef() == BasePrincipal::Cast(targetPrin)->OriginAttributesRef()), "Unexpected postMessage call to a window with mismatched " "origin attributes"); const char16_t* params[] = { providedOrigin.get(), targetOrigin.get() }; nsContentUtils::ReportToConsole(nsIScriptError::errorFlag, NS_LITERAL_CSTRING("DOM Window"), sourceDocument, nsContentUtils::eDOM_PROPERTIES, "TargetPrincipalDoesNotMatch", params, ArrayLength(params)); return NS_OK; } } ErrorResult rv; JS::Rooted<JS::Value> messageData(cx); nsCOMPtr<nsPIDOMWindowInner> window = targetWindow->AsInner(); Read(window, cx, &messageData, rv); if (NS_WARN_IF(rv.Failed())) { return rv.StealNSResult(); } // Create the event nsCOMPtr<mozilla::dom::EventTarget> eventTarget = do_QueryObject(targetWindow); RefPtr<MessageEvent> event = new MessageEvent(eventTarget, nullptr, nullptr); Nullable<WindowProxyOrMessagePort> source; source.SetValue().SetAsWindowProxy() = mSource ? mSource->AsOuter() : nullptr; Sequence<OwningNonNull<MessagePort>> ports; if (!TakeTransferredPortsAsSequence(ports)) { return NS_ERROR_OUT_OF_MEMORY; } event->InitMessageEvent(nullptr, NS_LITERAL_STRING("message"), false /*non-bubbling */, false /*cancelable */, messageData, mCallerOrigin, EmptyString(), source, ports); // We can't simply call dispatchEvent on the window because doing so ends // up flipping the trusted bit on the event, and we don't want that to // happen because then untrusted content can call postMessage on a chrome // window if it can get a reference to it. nsIPresShell *shell = targetWindow->GetExtantDoc()->GetShell(); RefPtr<nsPresContext> presContext; if (shell) presContext = shell->GetPresContext(); event->SetTrusted(mTrustedCaller); WidgetEvent* internalEvent = event->WidgetEventPtr(); nsEventStatus status = nsEventStatus_eIgnore; EventDispatcher::Dispatch(window, presContext, internalEvent, static_cast<dom::Event*>(event.get()), &status); return NS_OK; }
size_t AudioConverter::DownmixAudio(void* aOut, const void* aIn, size_t aFrames) const { MOZ_ASSERT(mIn.Format() == AudioConfig::FORMAT_S16 || mIn.Format() == AudioConfig::FORMAT_FLT); MOZ_ASSERT(mIn.Channels() >= mOut.Channels()); MOZ_ASSERT(mIn.Layout() == AudioConfig::ChannelLayout(mIn.Channels()), "Can only downmix input data in SMPTE layout"); MOZ_ASSERT(mOut.Layout() == AudioConfig::ChannelLayout(2) || mOut.Layout() == AudioConfig::ChannelLayout(1)); uint32_t channels = mIn.Channels(); if (channels == 1 && mOut.Channels() == 1) { if (aOut != aIn) { memmove(aOut, aIn, FramesOutToBytes(aFrames)); } return aFrames; } if (channels > 2) { if (mIn.Format() == AudioConfig::FORMAT_FLT) { // Downmix matrix. Per-row normalization 1 for rows 3,4 and 2 for rows 5-8. static const float dmatrix[6][8][2]= { /*3*/{{0.5858f,0},{0,0.5858f},{0.4142f,0.4142f}}, /*4*/{{0.4226f,0},{0,0.4226f},{0.366f, 0.2114f},{0.2114f,0.366f}}, /*5*/{{0.6510f,0},{0,0.6510f},{0.4600f,0.4600f},{0.5636f,0.3254f},{0.3254f,0.5636f}}, /*6*/{{0.5290f,0},{0,0.5290f},{0.3741f,0.3741f},{0.3741f,0.3741f},{0.4582f,0.2645f},{0.2645f,0.4582f}}, /*7*/{{0.4553f,0},{0,0.4553f},{0.3220f,0.3220f},{0.3220f,0.3220f},{0.2788f,0.2788f},{0.3943f,0.2277f},{0.2277f,0.3943f}}, /*8*/{{0.3886f,0},{0,0.3886f},{0.2748f,0.2748f},{0.2748f,0.2748f},{0.3366f,0.1943f},{0.1943f,0.3366f},{0.3366f,0.1943f},{0.1943f,0.3366f}}, }; // Re-write the buffer with downmixed data const float* in = static_cast<const float*>(aIn); float* out = static_cast<float*>(aOut); for (uint32_t i = 0; i < aFrames; i++) { float sampL = 0.0; float sampR = 0.0; for (uint32_t j = 0; j < channels; j++) { sampL += in[i*mIn.Channels()+j]*dmatrix[mIn.Channels()-3][j][0]; sampR += in[i*mIn.Channels()+j]*dmatrix[mIn.Channels()-3][j][1]; } *out++ = sampL; *out++ = sampR; } } else if (mIn.Format() == AudioConfig::FORMAT_S16) { // Downmix matrix. Per-row normalization 1 for rows 3,4 and 2 for rows 5-8. // Coefficients in Q14. static const int16_t dmatrix[6][8][2]= { /*3*/{{9598, 0},{0, 9598},{6786,6786}}, /*4*/{{6925, 0},{0, 6925},{5997,3462},{3462,5997}}, /*5*/{{10663,0},{0, 10663},{7540,7540},{9234,5331},{5331,9234}}, /*6*/{{8668, 0},{0, 8668},{6129,6129},{6129,6129},{7507,4335},{4335,7507}}, /*7*/{{7459, 0},{0, 7459},{5275,5275},{5275,5275},{4568,4568},{6460,3731},{3731,6460}}, /*8*/{{6368, 0},{0, 6368},{4502,4502},{4502,4502},{5514,3184},{3184,5514},{5514,3184},{3184,5514}} }; // Re-write the buffer with downmixed data const int16_t* in = static_cast<const int16_t*>(aIn); int16_t* out = static_cast<int16_t*>(aOut); for (uint32_t i = 0; i < aFrames; i++) { int32_t sampL = 0; int32_t sampR = 0; for (uint32_t j = 0; j < channels; j++) { sampL+=in[i*channels+j]*dmatrix[channels-3][j][0]; sampR+=in[i*channels+j]*dmatrix[channels-3][j][1]; } *out++ = clipTo15((sampL + 8192)>>14); *out++ = clipTo15((sampR + 8192)>>14); } } else { MOZ_DIAGNOSTIC_ASSERT(false, "Unsupported data type"); } // If we are to continue downmixing to mono, start working on the output // buffer. aIn = aOut; channels = 2; }
bool DocAccessibleParent::RecvShowEvent(const ShowEventData& aData, const bool& aFromUser) { if (mShutdown) return true; MOZ_DIAGNOSTIC_ASSERT(CheckDocTree()); if (aData.NewTree().IsEmpty()) { NS_ERROR("no children being added"); return false; } ProxyAccessible* parent = GetAccessible(aData.ID()); // XXX This should really never happen, but sometimes we fail to fire the // required show events. if (!parent) { NS_ERROR("adding child to unknown accessible"); return true; } uint32_t newChildIdx = aData.Idx(); if (newChildIdx > parent->ChildrenCount()) { NS_ERROR("invalid index to add child at"); return true; } uint32_t consumed = AddSubtree(parent, aData.NewTree(), 0, newChildIdx); MOZ_ASSERT(consumed == aData.NewTree().Length()); // XXX This shouldn't happen, but if we failed to add children then the below // is pointless and can crash. if (!consumed) { return true; } #ifdef DEBUG for (uint32_t i = 0; i < consumed; i++) { uint64_t id = aData.NewTree()[i].ID(); MOZ_ASSERT(mAccessibles.GetEntry(id)); } #endif MOZ_DIAGNOSTIC_ASSERT(CheckDocTree()); ProxyAccessible* target = parent->ChildAt(newChildIdx); ProxyShowHideEvent(target, parent, true, aFromUser); if (!nsCoreUtils::AccEventObserversExist()) { return true; } uint32_t type = nsIAccessibleEvent::EVENT_SHOW; xpcAccessibleGeneric* xpcAcc = GetXPCAccessible(target); xpcAccessibleDocument* doc = GetAccService()->GetXPCDocument(this); nsIDOMNode* node = nullptr; RefPtr<xpcAccEvent> event = new xpcAccEvent(type, xpcAcc, doc, node, aFromUser); nsCoreUtils::DispatchAccEvent(Move(event)); return true; }
ProxyStream::ProxyStream(REFIID aIID, IUnknown* aObject, Environment* aEnv, ProxyStreamFlags aFlags) : mGlobalLockedBuf(nullptr) , mHGlobal(nullptr) , mBufSize(0) , mPreserveStream(aFlags & ProxyStreamFlags::ePreservable) { if (!aObject) { return; } RefPtr<IStream> stream; HGLOBAL hglobal = NULL; int streamSize = 0; DWORD mshlFlags = mPreserveStream ? MSHLFLAGS_TABLESTRONG : MSHLFLAGS_NORMAL; HRESULT createStreamResult = S_OK; HRESULT marshalResult = S_OK; HRESULT statResult = S_OK; HRESULT getHGlobalResult = S_OK; nsAutoString manifestPath; auto marshalFn = [this, &aIID, aObject, mshlFlags, &stream, &streamSize, &hglobal, &createStreamResult, &marshalResult, &statResult, &getHGlobalResult, aEnv, &manifestPath]() -> void { if (aEnv) { bool pushOk = aEnv->Push(); MOZ_DIAGNOSTIC_ASSERT(pushOk); if (!pushOk) { return; } } auto popEnv = MakeScopeExit([aEnv]() -> void { if (!aEnv) { return; } bool popOk = aEnv->Pop(); MOZ_DIAGNOSTIC_ASSERT(popOk); }); createStreamResult = ::CreateStreamOnHGlobal(nullptr, TRUE, getter_AddRefs(stream)); if (FAILED(createStreamResult)) { return; } #if defined(ACCESSIBILITY) ActivationContext::GetCurrentManifestPath(manifestPath); #endif // defined(ACCESSIBILITY) marshalResult = ::CoMarshalInterface(stream, aIID, aObject, MSHCTX_LOCAL, nullptr, mshlFlags); #if !defined(MOZ_DEV_EDITION) MOZ_DIAGNOSTIC_ASSERT(marshalResult != E_INVALIDARG); #endif // !defined(MOZ_DEV_EDITION) if (FAILED(marshalResult)) { return; } STATSTG statstg; statResult = stream->Stat(&statstg, STATFLAG_NONAME); if (SUCCEEDED(statResult)) { streamSize = static_cast<int>(statstg.cbSize.LowPart); } else { return; } getHGlobalResult = ::GetHGlobalFromStream(stream, &hglobal); MOZ_ASSERT(SUCCEEDED(getHGlobalResult)); }; if (XRE_IsParentProcess()) { // We'll marshal this stuff directly using the current thread, therefore its // stub will reside in the same apartment as the current thread. marshalFn(); } else { // When marshaling in child processes, we want to force the MTA. EnsureMTA mta(marshalFn); } if (FAILED(createStreamResult)) { nsPrintfCString hrAsStr("0x%08X", createStreamResult); CrashReporter::AnnotateCrashReport( NS_LITERAL_CSTRING("CreateStreamOnHGlobalFailure"), hrAsStr); } if (FAILED(marshalResult)) { AnnotateInterfaceRegistration(aIID); nsPrintfCString hrAsStr("0x%08X", marshalResult); CrashReporter::AnnotateCrashReport( NS_LITERAL_CSTRING("CoMarshalInterfaceFailure"), hrAsStr); CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("MarshalActCtxManifestPath"), NS_ConvertUTF16toUTF8(manifestPath)); } if (FAILED(statResult)) { nsPrintfCString hrAsStr("0x%08X", statResult); CrashReporter::AnnotateCrashReport( NS_LITERAL_CSTRING("StatFailure"), hrAsStr); } if (FAILED(getHGlobalResult)) { nsPrintfCString hrAsStr("0x%08X", getHGlobalResult); CrashReporter::AnnotateCrashReport( NS_LITERAL_CSTRING("GetHGlobalFromStreamFailure"), hrAsStr); } mStream = mozilla::Move(stream); if (streamSize) { CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ProxyStreamSizeFrom"), NS_LITERAL_CSTRING("IStream::Stat")); mBufSize = streamSize; } if (!hglobal) { return; } mGlobalLockedBuf = reinterpret_cast<BYTE*>(::GlobalLock(hglobal)); mHGlobal = hglobal; // If we couldn't get the stream size directly from mStream, we may use // the size of the memory block allocated by the HGLOBAL, though it might // be larger than the actual stream size. if (!streamSize) { CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ProxyStreamSizeFrom"), NS_LITERAL_CSTRING("GlobalSize")); mBufSize = static_cast<int>(::GlobalSize(hglobal)); } nsAutoCString strBufSize; strBufSize.AppendInt(mBufSize); CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ProxyStreamSize"), strBufSize); }
void DocAccessibleParent::Destroy() { // If we are already shutdown that is because our containing tab parent is // shutting down in which case we don't need to do anything. if (mShutdown) { return; } mShutdown = true; MOZ_DIAGNOSTIC_ASSERT(LiveDocs().Contains(mActorID)); uint32_t childDocCount = mChildDocs.Length(); for (uint32_t i = 0; i < childDocCount; i++) { for (uint32_t j = i + 1; j < childDocCount; j++) { MOZ_DIAGNOSTIC_ASSERT(mChildDocs[i] != mChildDocs[j]); } } // XXX This indirection through the hash map of live documents shouldn't be // needed, but be paranoid for now. int32_t actorID = mActorID; for (uint32_t i = childDocCount - 1; i < childDocCount; i--) { DocAccessibleParent* thisDoc = LiveDocs().Get(actorID); MOZ_ASSERT(thisDoc); if (!thisDoc) { return; } thisDoc->ChildDocAt(i)->Destroy(); } for (auto iter = mAccessibles.Iter(); !iter.Done(); iter.Next()) { MOZ_ASSERT(iter.Get()->mProxy != this); ProxyDestroyed(iter.Get()->mProxy); iter.Remove(); } DocAccessibleParent* thisDoc = LiveDocs().Get(actorID); MOZ_ASSERT(thisDoc); if (!thisDoc) { return; } // The code above should have already completely cleared these, but to be // extra safe make sure they are cleared here. thisDoc->mAccessibles.Clear(); thisDoc->mChildDocs.Clear(); DocManager::NotifyOfRemoteDocShutdown(thisDoc); thisDoc = LiveDocs().Get(actorID); MOZ_ASSERT(thisDoc); if (!thisDoc) { return; } ProxyDestroyed(thisDoc); thisDoc = LiveDocs().Get(actorID); MOZ_ASSERT(thisDoc); if (!thisDoc) { return; } if (DocAccessibleParent* parentDoc = thisDoc->ParentDoc()) parentDoc->RemoveChildDoc(thisDoc); else if (IsTopLevel()) GetAccService()->RemoteDocShutdown(this); }
const TimeDuration& Timeout::TimeRemaining() const { MOZ_DIAGNOSTIC_ASSERT(mWhen.IsNull()); // Note, mWindow->IsFrozen() can be false here. The Thaw() method calls // TimeRemaining() to calculate the new When() value. return mTimeRemaining; }
void AbortSignal::RemoveFollower(AbortFollower* aFollower) { MOZ_DIAGNOSTIC_ASSERT(aFollower); mFollowers.RemoveElement(aFollower); }
nsresult FileReader::DoReadData(uint64_t aCount) { MOZ_ASSERT(mAsyncStream); uint32_t bytesRead = 0; if (mDataFormat == FILE_AS_BINARY) { //Continuously update our binary string as data comes in CheckedInt<uint64_t> size = mResult.Length(); size += aCount; if (!size.isValid() || size.value() > UINT32_MAX || size.value() > mTotal) { return NS_ERROR_OUT_OF_MEMORY; } uint32_t oldLen = mResult.Length(); MOZ_ASSERT(oldLen == mDataLen, "unexpected mResult length"); char16_t* dest = nullptr; mResult.GetMutableData(&dest, size.value(), fallible); NS_ENSURE_TRUE(dest, NS_ERROR_OUT_OF_MEMORY); dest += oldLen; if (NS_InputStreamIsBuffered(mAsyncStream)) { nsresult rv = mAsyncStream->ReadSegments(ReadFuncBinaryString, dest, aCount, &bytesRead); NS_ENSURE_SUCCESS(rv, rv); } else { while (aCount > 0) { char tmpBuffer[4096]; uint32_t minCount = XPCOM_MIN(aCount, static_cast<uint64_t>(sizeof(tmpBuffer))); uint32_t read; nsresult rv = mAsyncStream->Read(tmpBuffer, minCount, &read); if (rv == NS_BASE_STREAM_CLOSED) { rv = NS_OK; } NS_ENSURE_SUCCESS(rv, rv); if (read == 0) { // The stream finished too early. return NS_ERROR_OUT_OF_MEMORY; } PopulateBufferForBinaryString(dest, tmpBuffer, read); dest += read; aCount -= read; bytesRead += read; } } MOZ_ASSERT(size.value() == oldLen + bytesRead); mResult.Truncate(size.value()); } else { CheckedInt<uint64_t> size = mDataLen; size += aCount; //Update memory buffer to reflect the contents of the file if (!size.isValid() || // PR_Realloc doesn't support over 4GB memory size even if 64-bit OS // XXX: it's likely that this check is unnecessary and the comment is // wrong because we no longer use PR_Realloc outside of NSPR and NSS. size.value() > UINT32_MAX || size.value() > mTotal) { return NS_ERROR_OUT_OF_MEMORY; } MOZ_DIAGNOSTIC_ASSERT(mFileData); MOZ_RELEASE_ASSERT((mDataLen + aCount) <= mTotal); nsresult rv = mAsyncStream->Read(mFileData + mDataLen, aCount, &bytesRead); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } } mDataLen += bytesRead; return NS_OK; }
StreamControl::~StreamControl() { // owning thread only, but can't call virtual AssertOwningThread in destructor MOZ_DIAGNOSTIC_ASSERT(mReadStreamList.IsEmpty()); }
void StreamControl::AddReadStream(ReadStream::Controllable* aReadStream) { AssertOwningThread(); MOZ_DIAGNOSTIC_ASSERT(aReadStream); MOZ_ASSERT(!mReadStreamList.Contains(aReadStream)); mReadStreamList.AppendElement(aReadStream); }
NS_IMETHODIMP FetchDriver::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) { AssertIsOnMainThread(); // Note, this can be called multiple times if we are doing an opaqueredirect. // In that case we will get a simulated OnStartRequest() and then the real // channel will call in with an errored OnStartRequest(). if (!mChannel) { MOZ_ASSERT(!mObserver); return NS_BINDING_ABORTED; } nsresult rv; aRequest->GetStatus(&rv); if (NS_FAILED(rv)) { FailWithNetworkError(rv); return rv; } // We should only get to the following code once. MOZ_ASSERT(!mPipeOutputStream); MOZ_ASSERT(mObserver); mNeedToObserveOnDataAvailable = mObserver->NeedOnDataAvailable(); RefPtr<InternalResponse> response; nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest); nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aRequest); // On a successful redirect we perform the following substeps of HTTP Fetch, // step 5, "redirect status", step 11. bool foundOpaqueRedirect = false; int64_t contentLength = InternalResponse::UNKNOWN_BODY_SIZE; rv = channel->GetContentLength(&contentLength); MOZ_ASSERT_IF(NS_FAILED(rv), contentLength == InternalResponse::UNKNOWN_BODY_SIZE); if (httpChannel) { uint32_t responseStatus; rv = httpChannel->GetResponseStatus(&responseStatus); MOZ_ASSERT(NS_SUCCEEDED(rv)); if (mozilla::net::nsHttpChannel::IsRedirectStatus(responseStatus)) { if (mRequest->GetRedirectMode() == RequestRedirect::Error) { FailWithNetworkError(NS_BINDING_ABORTED); return NS_BINDING_FAILED; } if (mRequest->GetRedirectMode() == RequestRedirect::Manual) { foundOpaqueRedirect = true; } } nsAutoCString statusText; rv = httpChannel->GetResponseStatusText(statusText); MOZ_ASSERT(NS_SUCCEEDED(rv)); response = new InternalResponse(responseStatus, statusText); response->Headers()->FillResponseHeaders(httpChannel); // If Content-Encoding or Transfer-Encoding headers are set, then the actual // Content-Length (which refer to the decoded data) is obscured behind the encodings. ErrorResult result; if (response->Headers()->Has(NS_LITERAL_CSTRING("content-encoding"), result) || response->Headers()->Has(NS_LITERAL_CSTRING("transfer-encoding"), result)) { // We cannot trust the content-length when content-encoding or // transfer-encoding are set. There are many servers which just // get this wrong. contentLength = InternalResponse::UNKNOWN_BODY_SIZE; } MOZ_ASSERT(!result.Failed()); } else { response = new InternalResponse(200, NS_LITERAL_CSTRING("OK")); ErrorResult result; nsAutoCString contentType; rv = channel->GetContentType(contentType); if (NS_SUCCEEDED(rv) && !contentType.IsEmpty()) { nsAutoCString contentCharset; channel->GetContentCharset(contentCharset); if (NS_SUCCEEDED(rv) && !contentCharset.IsEmpty()) { contentType += NS_LITERAL_CSTRING(";charset=") + contentCharset; } response->Headers()->Append(NS_LITERAL_CSTRING("Content-Type"), contentType, result); MOZ_ASSERT(!result.Failed()); } if (contentLength > 0) { nsAutoCString contentLenStr; contentLenStr.AppendInt(contentLength); response->Headers()->Append(NS_LITERAL_CSTRING("Content-Length"), contentLenStr, result); MOZ_ASSERT(!result.Failed()); } } nsCOMPtr<nsICacheInfoChannel> cic = do_QueryInterface(aRequest); if (cic && mAltDataListener) { // Skip the case that mAltDataListener->Status() equals to FALLBACK, that means // the opened channel for alternative data loading is reused for loading the // main data. if (mAltDataListener->Status() != AlternativeDataStreamListener::FALLBACK) { // Verify the cache ID is the same with from alternative data cache. // If the cache ID is different, droping the alternative data loading, // otherwise setup the response's alternative body and cacheInfoChannel. uint64_t cacheEntryId = 0; if (NS_SUCCEEDED(cic->GetCacheEntryId(&cacheEntryId)) && cacheEntryId != mAltDataListener->GetAlternativeDataCacheEntryId()) { mAltDataListener->Cancel(); } else { // AlternativeDataStreamListener::OnStartRequest had already been called, // the alternative data input stream and cacheInfo channel must be created. nsCOMPtr<nsICacheInfoChannel> cacheInfo = mAltDataListener->GetCacheInfoChannel(); nsCOMPtr<nsIInputStream> altInputStream = mAltDataListener->GetAlternativeInputStream(); MOZ_ASSERT(altInputStream && cacheInfo); response->SetAlternativeBody(altInputStream); nsMainThreadPtrHandle<nsICacheInfoChannel> handle( new nsMainThreadPtrHolder<nsICacheInfoChannel>("nsICacheInfoChannel", cacheInfo, false)); response->SetCacheInfoChannel(handle); } } else if (!mAltDataListener->GetAlternativeDataType().IsEmpty()) { // If the status is FALLBACK and the mAltDataListener::mAlternativeDataType // is not empty, that means the data need to be saved into cache, setup the // response's nsICacheInfoChannel for caching the data after loading. nsMainThreadPtrHandle<nsICacheInfoChannel> handle( new nsMainThreadPtrHolder<nsICacheInfoChannel>("nsICacheInfoChannel", cic, false)); response->SetCacheInfoChannel(handle); } } // We open a pipe so that we can immediately set the pipe's read end as the // response's body. Setting the segment size to UINT32_MAX means that the // pipe has infinite space. The nsIChannel will continue to buffer data in // xpcom events even if we block on a fixed size pipe. It might be possible // to suspend the channel and then resume when there is space available, but // for now use an infinite pipe to avoid blocking. nsCOMPtr<nsIInputStream> pipeInputStream; rv = NS_NewPipe(getter_AddRefs(pipeInputStream), getter_AddRefs(mPipeOutputStream), 0, /* default segment size */ UINT32_MAX /* infinite pipe */, true /* non-blocking input, otherwise you deadlock */, false /* blocking output, since the pipe is 'in'finite */ ); if (NS_WARN_IF(NS_FAILED(rv))) { FailWithNetworkError(rv); // Cancel request. return rv; } response->SetBody(pipeInputStream, contentLength); response->InitChannelInfo(channel); nsCOMPtr<nsIURI> channelURI; rv = channel->GetURI(getter_AddRefs(channelURI)); if (NS_WARN_IF(NS_FAILED(rv))) { FailWithNetworkError(rv); // Cancel request. return rv; } nsCOMPtr<nsILoadInfo> loadInfo; rv = channel->GetLoadInfo(getter_AddRefs(loadInfo)); if (NS_WARN_IF(NS_FAILED(rv))) { FailWithNetworkError(rv); return rv; } // Propagate any tainting from the channel back to our response here. This // step is not reflected in the spec because the spec is written such that // FetchEvent.respondWith() just passes the already-tainted Response back to // the outer fetch(). In gecko, however, we serialize the Response through // the channel and must regenerate the tainting from the channel in the // interception case. mRequest->MaybeIncreaseResponseTainting(loadInfo->GetTainting()); // Resolves fetch() promise which may trigger code running in a worker. Make // sure the Response is fully initialized before calling this. mResponse = BeginAndGetFilteredResponse(response, foundOpaqueRedirect); if (NS_WARN_IF(!mResponse)) { // Fail to generate a paddingInfo for opaque response. MOZ_DIAGNOSTIC_ASSERT(mResponse->Type() == ResponseType::Opaque); FailWithNetworkError(NS_ERROR_UNEXPECTED); return rv; } // From "Main Fetch" step 19: SRI-part1. if (ShouldCheckSRI(mRequest, mResponse) && mSRIMetadata.IsEmpty()) { nsIConsoleReportCollector* reporter = nullptr; if (mObserver) { reporter = mObserver->GetReporter(); } nsAutoCString sourceUri; if (mDocument && mDocument->GetDocumentURI()) { mDocument->GetDocumentURI()->GetAsciiSpec(sourceUri); } else if (!mWorkerScript.IsEmpty()) { sourceUri.Assign(mWorkerScript); } SRICheck::IntegrityMetadata(mRequest->GetIntegrity(), sourceUri, reporter, &mSRIMetadata); mSRIDataVerifier = new SRICheckDataVerifier(mSRIMetadata, sourceUri, reporter); // Do not retarget off main thread when using SRI API. return NS_OK; } nsCOMPtr<nsIEventTarget> sts = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &rv); if (NS_WARN_IF(NS_FAILED(rv))) { FailWithNetworkError(rv); // Cancel request. return rv; } // Try to retarget off main thread. if (nsCOMPtr<nsIThreadRetargetableRequest> rr = do_QueryInterface(aRequest)) { Unused << NS_WARN_IF(NS_FAILED(rr->RetargetDeliveryTo(sts))); } return NS_OK; }
ServiceWorkerImpl::ServiceWorkerImpl(ServiceWorkerInfo* aInfo) : mInfo(aInfo) , mOuter(nullptr) { MOZ_DIAGNOSTIC_ASSERT(mInfo); }
already_AddRefed<IDBOpenDBRequest> IDBFactory::OpenInternal(JSContext* aCx, nsIPrincipal* aPrincipal, const nsAString& aName, const Optional<uint64_t>& aVersion, const Optional<StorageType>& aStorageType, bool aDeleting, CallerType aCallerType, ErrorResult& aRv) { MOZ_ASSERT(mWindow || mOwningObject); MOZ_ASSERT_IF(!mWindow, !mPrivateBrowsingMode); CommonFactoryRequestParams commonParams; PrincipalInfo& principalInfo = commonParams.principalInfo(); if (aPrincipal) { if (!NS_IsMainThread()) { MOZ_CRASH("Figure out security checks for workers! What's this " "aPrincipal we have on a worker thread?"); } MOZ_ASSERT(aCallerType == CallerType::System); MOZ_DIAGNOSTIC_ASSERT(mPrivateBrowsingMode == (aPrincipal->GetPrivateBrowsingId() > 0)); if (NS_WARN_IF(NS_FAILED(PrincipalToPrincipalInfo(aPrincipal, &principalInfo)))) { IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } if (principalInfo.type() != PrincipalInfo::TContentPrincipalInfo && principalInfo.type() != PrincipalInfo::TSystemPrincipalInfo) { IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } } else { principalInfo = *mPrincipalInfo; } uint64_t version = 0; if (!aDeleting && aVersion.WasPassed()) { if (aVersion.Value() < 1) { aRv.ThrowTypeError<MSG_INVALID_VERSION>(); return nullptr; } version = aVersion.Value(); } // Nothing can be done here if we have previously failed to create a // background actor. if (mBackgroundActorFailed) { IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } PersistenceType persistenceType; bool isInternal = principalInfo.type() == PrincipalInfo::TSystemPrincipalInfo; if (!isInternal && principalInfo.type() == PrincipalInfo::TContentPrincipalInfo) { nsCString origin = principalInfo.get_ContentPrincipalInfo().originNoSuffix(); isInternal = QuotaManager::IsOriginInternal(origin); } // Allow storage attributes for add-ons independent of the pref. // This works in the main thread only, workers don't have the principal. bool isAddon = false; if (NS_IsMainThread()) { // aPrincipal is passed inconsistently, so even when we are already on // the main thread, we may have been passed a null aPrincipal. nsCOMPtr<nsIPrincipal> principal = PrincipalInfoToPrincipal(principalInfo); if (principal) { nsAutoString addonId; Unused << NS_WARN_IF(NS_FAILED(principal->GetAddonId(addonId))); isAddon = !addonId.IsEmpty(); } } if (isInternal) { // Chrome privilege and internal origins always get persistent storage. persistenceType = PERSISTENCE_TYPE_PERSISTENT; } else if (isAddon || DOMPrefs::IndexedDBStorageOptionsEnabled()) { persistenceType = PersistenceTypeFromStorage(aStorageType); } else { persistenceType = PERSISTENCE_TYPE_DEFAULT; } DatabaseMetadata& metadata = commonParams.metadata(); metadata.name() = aName; metadata.persistenceType() = persistenceType; FactoryRequestParams params; if (aDeleting) { metadata.version() = 0; params = DeleteDatabaseRequestParams(commonParams); } else { metadata.version() = version; params = OpenDatabaseRequestParams(commonParams); } if (!mBackgroundActor) { BackgroundChildImpl::ThreadLocal* threadLocal = BackgroundChildImpl::GetThreadLocalForCurrentThread(); nsAutoPtr<ThreadLocal> newIDBThreadLocal; ThreadLocal* idbThreadLocal; if (threadLocal && threadLocal->mIndexedDBThreadLocal) { idbThreadLocal = threadLocal->mIndexedDBThreadLocal; } else { nsCOMPtr<nsIUUIDGenerator> uuidGen = do_GetService("@mozilla.org/uuid-generator;1"); MOZ_ASSERT(uuidGen); nsID id; MOZ_ALWAYS_SUCCEEDS(uuidGen->GenerateUUIDInPlace(&id)); newIDBThreadLocal = idbThreadLocal = new ThreadLocal(id); } PBackgroundChild* backgroundActor = BackgroundChild::GetOrCreateForCurrentThread(); if (NS_WARN_IF(!backgroundActor)) { IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } { BackgroundFactoryChild* actor = new BackgroundFactoryChild(this); // Set EventTarget for the top-level actor. // All child actors created later inherit the same event target. backgroundActor->SetEventTargetForActor(actor, EventTarget()); MOZ_ASSERT(actor->GetActorEventTarget()); mBackgroundActor = static_cast<BackgroundFactoryChild*>( backgroundActor->SendPBackgroundIDBFactoryConstructor(actor, idbThreadLocal->GetLoggingInfo())); if (NS_WARN_IF(!mBackgroundActor)) { mBackgroundActorFailed = true; IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } } if (newIDBThreadLocal) { if (!threadLocal) { threadLocal = BackgroundChildImpl::GetThreadLocalForCurrentThread(); } MOZ_ASSERT(threadLocal); MOZ_ASSERT(!threadLocal->mIndexedDBThreadLocal); threadLocal->mIndexedDBThreadLocal = newIDBThreadLocal.forget(); } } RefPtr<IDBOpenDBRequest> request; if (mWindow) { JS::Rooted<JSObject*> scriptOwner(aCx, nsGlobalWindowInner::Cast(mWindow.get())->FastGetGlobalJSObject()); MOZ_ASSERT(scriptOwner); request = IDBOpenDBRequest::CreateForWindow(aCx, this, mWindow, scriptOwner); } else { JS::Rooted<JSObject*> scriptOwner(aCx, mOwningObject); request = IDBOpenDBRequest::CreateForJS(aCx, this, scriptOwner); if (!request) { MOZ_ASSERT(!NS_IsMainThread()); aRv.ThrowUncatchableException(); return nullptr; } } MOZ_ASSERT(request); if (aDeleting) { IDB_LOG_MARK("IndexedDB %s: Child Request[%llu]: " "indexedDB.deleteDatabase(\"%s\")", "IndexedDB %s: C R[%llu]: IDBFactory.deleteDatabase()", IDB_LOG_ID_STRING(), request->LoggingSerialNumber(), NS_ConvertUTF16toUTF8(aName).get()); } else { IDB_LOG_MARK("IndexedDB %s: Child Request[%llu]: " "indexedDB.open(\"%s\", %s)", "IndexedDB %s: C R[%llu]: IDBFactory.open()", IDB_LOG_ID_STRING(), request->LoggingSerialNumber(), NS_ConvertUTF16toUTF8(aName).get(), IDB_LOG_STRINGIFY(aVersion)); } nsresult rv = InitiateRequest(request, params); if (NS_WARN_IF(NS_FAILED(rv))) { IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } return request.forget(); }
nsCommandManager::nsCommandManager(mozIDOMWindowProxy* aWindow) : mWindow(aWindow) { MOZ_DIAGNOSTIC_ASSERT(mWindow); }
void FireTailDispatcher() { MOZ_DIAGNOSTIC_ASSERT(mTailDispatcher.isSome()); mTailDispatcher.ref().DrainDirectTasks(); mTailDispatcher.reset(); }
ServiceWorkerImpl::~ServiceWorkerImpl() { MOZ_DIAGNOSTIC_ASSERT(!mOuter); mInfo->RemoveListener(this); }