Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/dom/ipc/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 9 kB image not shown  

Quelle  SharedMessageBody.cpp   Sprache: C

 
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#include "SharedMessageBody.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/MessagePort.h"
#include "mozilla/dom/RefMessageBodyService.h"
#include "mozilla/dom/PMessagePort.h"
#include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/ipc/BackgroundParent.h"
#include "xpcpublic.h"

namespace mozilla {

using namespace ipc;

namespace dom {

SharedMessageBody::SharedMessageBody(
    StructuredCloneHolder::TransferringSupport aSupportsTransferring,
    const Maybe<nsID>& aAgentClusterId)
    : mRefDataId(Nothing()),
      mSupportsTransferring(aSupportsTransferring),
      mAgentClusterId(aAgentClusterId) {}

void SharedMessageBody::Write(JSContext* aCx, JS::Handle<JS::Value> aValue,
                              JS::Handle<JS::Value> aTransfers, nsID& aPortID,
                              RefMessageBodyService* aRefMessageBodyService,
                              ErrorResult& aRv) {
  MOZ_ASSERT(!mCloneData && !mRefData);
  MOZ_ASSERT(aRefMessageBodyService);

  JS::CloneDataPolicy cloneDataPolicy;
  // During a writing, we don't know the destination, so we assume it is part of
  // the same agent cluster.
  cloneDataPolicy.allowIntraClusterClonableSharedObjects();

  nsIGlobalObject* global = xpc::CurrentNativeGlobal(aCx);
  MOZ_ASSERT(global);

  if (global->IsSharedMemoryAllowed()) {
    cloneDataPolicy.allowSharedMemoryObjects();
  }

  mCloneData = MakeUnique<ipc::StructuredCloneData>(
      JS::StructuredCloneScope::UnknownDestination, mSupportsTransferring);
  mCloneData->Write(aCx, aValue, aTransfers, cloneDataPolicy, aRv);
  if (NS_WARN_IF(aRv.Failed())) {
    return;
  }

  if (mCloneData->CloneScope() == JS::StructuredCloneScope::DifferentProcess) {
    return;
  }

  MOZ_ASSERT(mCloneData->CloneScope() == JS::StructuredCloneScope::SameProcess);
  RefPtr<RefMessageBody> refData =
      new RefMessageBody(aPortID, std::move(mCloneData));

  mRefDataId.emplace(aRefMessageBodyService->Register(refData.forget(), aRv));
}

void SharedMessageBody::Read(JSContext* aCx,
                             JS::MutableHandle<JS::Value> aValue,
                             RefMessageBodyService* aRefMessageBodyService,
                             SharedMessageBody::ReadMethod aReadMethod,
                             ErrorResult& aRv) {
  MOZ_ASSERT(aRefMessageBodyService);

  if (mCloneData) {
    // Use a default cloneDataPolicy here, because SharedArrayBuffers and WASM
    // are not supported.
    return mCloneData->Read(aCx, aValue, JS::CloneDataPolicy(), aRv);
  }

  JS::CloneDataPolicy cloneDataPolicy;

  nsIGlobalObject* global = xpc::CurrentNativeGlobal(aCx);
  MOZ_ASSERT(global);

  // Clones within the same agent cluster are allowed to use shared array
  // buffers and WASM modules.
  if (mAgentClusterId.isSome()) {
    Maybe<nsID> agentClusterId = global->GetAgentClusterId();
    if (agentClusterId.isSome() &&
        mAgentClusterId.value().Equals(agentClusterId.value())) {
      cloneDataPolicy.allowIntraClusterClonableSharedObjects();
    }
  }

  if (global->IsSharedMemoryAllowed()) {
    cloneDataPolicy.allowSharedMemoryObjects();
  }

  MOZ_ASSERT(!mRefData);
  MOZ_ASSERT(mRefDataId.isSome());

  if (aReadMethod == SharedMessageBody::StealRefMessageBody) {
    mRefData = aRefMessageBodyService->Steal(mRefDataId.value());
  } else {
    MOZ_ASSERT(aReadMethod == SharedMessageBody::KeepRefMessageBody);
    mRefData = aRefMessageBodyService->GetAndCount(mRefDataId.value());
  }

  if (!mRefData) {
    aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
    return;
  }

  mRefData->Read(aCx, aValue, cloneDataPolicy, aRv);
}

bool SharedMessageBody::TakeTransferredPortsAsSequence(
    Sequence<OwningNonNull<mozilla::dom::MessagePort>>& aPorts) {
  if (mCloneData) {
    return mCloneData->TakeTransferredPortsAsSequence(aPorts);
  }

  MOZ_ASSERT(mRefData);
  return mRefData->TakeTransferredPortsAsSequence(aPorts);
}

/* static */
void SharedMessageBody::FromSharedToMessageChild(
    mozilla::ipc::PBackgroundChild* aManager, SharedMessageBody* aData,
    MessageData& aMessage) {
  MOZ_ASSERT(aManager);
  MOZ_ASSERT(aData);

  aMessage.agentClusterId() = aData->mAgentClusterId;

  if (aData->mCloneData) {
    ClonedMessageData clonedData;
    aData->mCloneData->BuildClonedMessageData(clonedData);
    aMessage.data() = std::move(clonedData);
    return;
  }

  MOZ_ASSERT(aData->mRefDataId.isSome());
  aMessage.data() = RefMessageData(aData->mRefDataId.value());
}

/* static */
void SharedMessageBody::FromSharedToMessagesChild(
    PBackgroundChild* aManager,
    const nsTArray<RefPtr<SharedMessageBody>>& aData,
    nsTArray<MessageData>& aArray) {
  MOZ_ASSERT(aManager);
  MOZ_ASSERT(aArray.IsEmpty());
  aArray.SetCapacity(aData.Length());

  for (auto& data : aData) {
    MessageData* message = aArray.AppendElement();
    FromSharedToMessageChild(aManager, data, *message);
  }
}

/* static */
already_AddRefed<SharedMessageBody> SharedMessageBody::FromMessageToSharedChild(
    MessageData& aMessage,
    StructuredCloneHolder::TransferringSupport aSupportsTransferring) {
  RefPtr<SharedMessageBody> data =
      new SharedMessageBody(aSupportsTransferring, aMessage.agentClusterId());

  if (aMessage.data().type() == MessageDataType::TClonedMessageData) {
    data->mCloneData = MakeUnique<ipc::StructuredCloneData>(
        JS::StructuredCloneScope::UnknownDestination, aSupportsTransferring);
    data->mCloneData->StealFromClonedMessageData(
        aMessage.data().get_ClonedMessageData());
  } else {
    MOZ_ASSERT(aMessage.data().type() == MessageDataType::TRefMessageData);
    data->mRefDataId.emplace(aMessage.data().get_RefMessageData().uuid());
  }

  return data.forget();
}

/* static */
already_AddRefed<SharedMessageBody> SharedMessageBody::FromMessageToSharedChild(
    const MessageData& aMessage,
    StructuredCloneHolder::TransferringSupport aSupportsTransferring) {
  RefPtr<SharedMessageBody> data =
      new SharedMessageBody(aSupportsTransferring, aMessage.agentClusterId());

  if (aMessage.data().type() == MessageDataType::TClonedMessageData) {
    data->mCloneData = MakeUnique<ipc::StructuredCloneData>(
        JS::StructuredCloneScope::UnknownDestination, aSupportsTransferring);
    data->mCloneData->BorrowFromClonedMessageData(
        aMessage.data().get_ClonedMessageData());
  } else {
    MOZ_ASSERT(aMessage.data().type() == MessageDataType::TRefMessageData);
    data->mRefDataId.emplace(aMessage.data().get_RefMessageData().uuid());
  }

  return data.forget();
}

/* static */
bool SharedMessageBody::FromMessagesToSharedChild(
    nsTArray<MessageData>& aArray,
    FallibleTArray<RefPtr<SharedMessageBody>>& aData,
    StructuredCloneHolder::TransferringSupport aSupportsTransferring) {
  MOZ_ASSERT(aData.IsEmpty());

  if (NS_WARN_IF(!aData.SetCapacity(aArray.Length(), mozilla::fallible))) {
    return false;
  }

  for (auto& message : aArray) {
    RefPtr<SharedMessageBody> data =
        FromMessageToSharedChild(message, aSupportsTransferring);
    if (!data || !aData.AppendElement(data, mozilla::fallible)) {
      return false;
    }
  }

  return true;
}

/* static */
bool SharedMessageBody::FromSharedToMessagesParent(
    PBackgroundParent* aManager,
    const nsTArray<RefPtr<SharedMessageBody>>& aData,
    nsTArray<MessageData>& aArray) {
  MOZ_ASSERT(aManager);
  MOZ_ASSERT(aArray.IsEmpty());

  if (NS_WARN_IF(!aArray.SetCapacity(aData.Length(), mozilla::fallible))) {
    return false;
  }

  for (auto& data : aData) {
    MessageData* message = aArray.AppendElement();
    message->agentClusterId() = data->mAgentClusterId;

    if (data->mCloneData) {
      ClonedMessageData clonedData;
      data->mCloneData->BuildClonedMessageData(clonedData);
      message->data() = std::move(clonedData);
      continue;
    }

    MOZ_ASSERT(data->mRefDataId.isSome());
    message->data() = RefMessageData(data->mRefDataId.value());
  }

  return true;
}

/* static */
already_AddRefed<SharedMessageBody>
SharedMessageBody::FromMessageToSharedParent(
    MessageData& aMessage,
    StructuredCloneHolder::TransferringSupport aSupportsTransferring) {
  // TODO: This alloc is not fallible and there is no codepath that returns
  // nullptr. But the caller checks for nullptr and handles array allocations
  // for these items as fallible. See bug 1750497.
  RefPtr<SharedMessageBody> data =
      new SharedMessageBody(aSupportsTransferring, aMessage.agentClusterId());

  if (aMessage.data().type() == MessageDataType::TClonedMessageData) {
    data->mCloneData = MakeUnique<ipc::StructuredCloneData>(
        JS::StructuredCloneScope::UnknownDestination, aSupportsTransferring);
    data->mCloneData->StealFromClonedMessageData(
        aMessage.data().get_ClonedMessageData());
  } else {
    MOZ_ASSERT(aMessage.data().type() == MessageDataType::TRefMessageData);
    data->mRefDataId.emplace(aMessage.data().get_RefMessageData().uuid());
  }

  return data.forget();
}

bool SharedMessageBody::FromMessagesToSharedParent(
    nsTArray<MessageData>& aArray,
    FallibleTArray<RefPtr<SharedMessageBody>>& aData,
    StructuredCloneHolder::TransferringSupport aSupportsTransferring) {
  MOZ_ASSERT(aData.IsEmpty());

  if (NS_WARN_IF(!aData.SetCapacity(aArray.Length(), mozilla::fallible))) {
    return false;
  }

  for (auto& message : aArray) {
    RefPtr<SharedMessageBody> data = FromMessageToSharedParent(message);
    if (!data || !aData.AppendElement(data, mozilla::fallible)) {
      return false;
    }
  }

  return true;
}

}  // namespace dom
}  // namespace mozilla

Messung V0.5
C=92 H=98 G=94

¤ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.