void FetchStream::ReleaseObjects(const MutexAutoLock& aProofOfLock) { // This method can be called on 2 possible threads: the owning one and a JS // thread used to release resources. If we are on the JS thread, we need to // dispatch a runnable to go back to the owning thread in order to release // resources correctly. if (mState == eClosed) { // Already gone. Nothing to do. return; } mState = eClosed; if (!NS_IsMainThread() && !IsCurrentThreadRunningWorker()) { // Let's dispatch a WorkerControlRunnable if the owning thread is a worker. if (mWorkerRef) { RefPtr<WorkerShutdown> r = new WorkerShutdown(mWorkerRef->GetUnsafePrivate(), this); Unused << NS_WARN_IF(!r->Dispatch()); return; } // A normal runnable of the owning thread is the main-thread. RefPtr<FetchStream> self = this; RefPtr<Runnable> r = NS_NewRunnableFunction("FetchStream::ReleaseObjects", [self] () { self->ReleaseObjects(); }); mOwningEventTarget->Dispatch(r.forget()); return; } AssertIsOnOwningThread(); if (NS_IsMainThread()) { nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); if (obs) { obs->RemoveObserver(this, DOM_WINDOW_DESTROYED_TOPIC); } } mWorkerRef = nullptr; mGlobal = nullptr; mStreamHolder->NullifyStream(); mStreamHolder = nullptr; }
void FileReader::ReadFileContent(Blob& aBlob, const nsAString &aCharset, eDataFormat aDataFormat, ErrorResult& aRv) { if (IsCurrentThreadRunningWorker() && !mWeakWorkerRef) { // The worker is already shutting down. return; } if (mReadyState == LOADING) { aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); return; } mError = nullptr; SetDOMStringToNull(mResult); mResultArrayBuffer = nullptr; mAsyncStream = nullptr; mTransferred = 0; mTotal = 0; mReadyState = EMPTY; FreeFileData(); mBlob = &aBlob; mDataFormat = aDataFormat; CopyUTF16toUTF8(aCharset, mCharset); { nsCOMPtr<nsIInputStream> stream; mBlob->CreateInputStream(getter_AddRefs(stream), aRv); if (NS_WARN_IF(aRv.Failed())) { return; } aRv = NS_MakeAsyncNonBlockingInputStream(stream.forget(), getter_AddRefs(mAsyncStream)); if (NS_WARN_IF(aRv.Failed())) { return; } } MOZ_ASSERT(mAsyncStream); mTotal = mBlob->GetSize(aRv); if (NS_WARN_IF(aRv.Failed())) { return; } // Binary Format doesn't need a post-processing of the data. Everything is // written directly into mResult. if (mDataFormat != FILE_AS_BINARY) { if (mDataFormat == FILE_AS_ARRAYBUFFER) { mFileData = js_pod_malloc<char>(mTotal); } else { mFileData = (char *) malloc(mTotal); } if (!mFileData) { NS_WARNING("Preallocation failed for ReadFileData"); aRv.Throw(NS_ERROR_OUT_OF_MEMORY); return; } } aRv = DoAsyncWait(); if (NS_WARN_IF(aRv.Failed())) { FreeFileData(); return; } //FileReader should be in loading state here mReadyState = LOADING; DispatchProgressEvent(NS_LITERAL_STRING(LOADSTART_STR)); }