void TypeUtils::SerializePushStream(nsIInputStream* aStream, CacheReadStream& aReadStreamOut, ErrorResult& aRv) { nsCOMPtr<nsIAsyncInputStream> asyncStream = do_QueryInterface(aStream); if (NS_WARN_IF(!asyncStream)) { aRv = NS_ERROR_FAILURE; return; } bool nonBlocking = false; aRv = asyncStream->IsNonBlocking(&nonBlocking); if (NS_WARN_IF(aRv.Failed())) { return; } if (NS_WARN_IF(!nonBlocking)) { aRv = NS_ERROR_FAILURE; return; } aReadStreamOut.pushStreamChild() = CreatePushStream(asyncStream); MOZ_ASSERT(aReadStreamOut.pushStreamChild()); aReadStreamOut.params() = void_t(); aReadStreamOut.fds() = void_t(); // CachePushStreamChild::Start() must be called after sending the stream // across to the parent side. }
// static already_AddRefed<ReadStream> ReadStream::Create(const CacheReadStream& aReadStream) { // The parameter may or may not be for a Cache created stream. The way we // tell is by looking at the stream control actor. If the actor exists, // then we know the Cache created it. if (!aReadStream.controlChild() && !aReadStream.controlParent()) { return nullptr; } MOZ_ASSERT(!aReadStream.pushStreamChild()); MOZ_ASSERT(!aReadStream.pushStreamParent()); // Control is guaranteed to survive this method as ActorDestroy() cannot // run on this thread until we complete. StreamControl* control; if (aReadStream.controlChild()) { auto actor = static_cast<CacheStreamControlChild*>(aReadStream.controlChild()); control = actor; } else { auto actor = static_cast<CacheStreamControlParent*>(aReadStream.controlParent()); control = actor; } MOZ_ASSERT(control); AutoTArray<FileDescriptor, 4> fds; control->DeserializeFds(aReadStream, fds); nsCOMPtr<nsIInputStream> stream = DeserializeInputStream(aReadStream.params(), fds); MOZ_ASSERT(stream); // Currently we expect all cache read streams to be blocking file streams. #ifdef DEBUG nsCOMPtr<nsIAsyncInputStream> asyncStream = do_QueryInterface(stream); MOZ_ASSERT(!asyncStream); #endif RefPtr<Inner> inner = new Inner(control, aReadStream.id(), stream); RefPtr<ReadStream> ref = new ReadStream(inner); return ref.forget(); }