Example #1
0
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.
}
void
CacheStreamControlChild::DeserializeFds(const CacheReadStream& aReadStream,
                                        nsTArray<FileDescriptor>& aFdsOut)
{
  if (aReadStream.fds().type() !=
      OptionalFileDescriptorSet::TPFileDescriptorSetChild) {
    return;
  }

  auto fdSetActor = static_cast<FileDescriptorSetChild*>(
    aReadStream.fds().get_PFileDescriptorSetChild());
  MOZ_ASSERT(fdSetActor);

  fdSetActor->ForgetFileDescriptors(aFdsOut);
  MOZ_ASSERT(!aFdsOut.IsEmpty());

  unused << fdSetActor->Send__delete__(fdSetActor);
}
Example #3
0
void
TypeUtils::SerializeCacheStream(nsIInputStream* aStream,
                                CacheReadStreamOrVoid* aStreamOut,
                                ErrorResult& aRv)
{
  *aStreamOut = void_t();
  if (!aStream) {
    return;
  }

  // Option 1: Send a cache-specific ReadStream if we can.
  nsRefPtr<ReadStream> controlled = do_QueryObject(aStream);
  if (controlled) {
    controlled->Serialize(aStreamOut);
    return;
  }

  CacheReadStream readStream;
  readStream.controlChild() = nullptr;
  readStream.controlParent() = nullptr;
  readStream.pushStreamChild() = nullptr;
  readStream.pushStreamParent() = nullptr;

  // Option 2: Do normal stream serialization if its supported.
  nsCOMPtr<nsIIPCSerializableInputStream> serial = do_QueryInterface(aStream);
  if (serial) {
    SerializeNormalStream(aStream, readStream);

  // Option 3: As a last resort push data across manually.  Should only be
  //           needed for nsPipe input stream.  Only works for async,
  //           non-blocking streams.
  } else {
    SerializePushStream(aStream, readStream, aRv);
    if (NS_WARN_IF(aRv.Failed())) { return; }
  }

  *aStreamOut = readStream;
}
Example #4
0
// 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();
}