/* -*- 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/. */
if (XRE_IsContentProcess()) {
ContentChild* cc = ContentChild::GetSingleton();
// Increment the field epoch for fields affected by this transaction.
uint64_t epoch = cc->NextBrowsingContextFieldEpoch();
EachIndex([&](auto idx) { if (mModified.contains(idx)) {
FieldEpoch(idx, aOwner) = epoch;
}
});
// Tell our derived class to send the correct "Commit" IPC message.
aOwner->SendCommitTransaction(cc, *this, epoch);
} else {
MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess());
// Tell our derived class to send the correct "Commit" IPC messages.
BrowsingContextGroup* group = aOwner->Group();
group->EachParent([&](ContentParent* aParent) {
aOwner->SendCommitTransaction(aParent, *this,
aParent->GetBrowsingContextFieldEpoch());
});
}
template <typename Context>
mozilla::ipc::IPCResult Transaction<Context>::CommitFromIPC( const MaybeDiscarded<Context>& aOwner, ContentParent* aSource) {
MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess()); if (aOwner.IsNullOrDiscarded()) {
MOZ_LOG(Context::GetSyncLog(), LogLevel::Debug,
("IPC: Trying to send a message to dead or detached context")); return IPC_OK();
}
Context* owner = aOwner.get();
// Validate that the set from content is allowed before continuing.
IndexSet failedFields = Validate(owner, aSource); if (!failedFields.isEmpty()) {
nsCString error = FormatValidationError<Context>(
failedFields, "Invalid Transaction from Child - CanSet failed for field(s): "); // data-review+ at https://bugzilla.mozilla.org/show_bug.cgi?id=1618992#c7 return IPC_FAIL_UNSAFE_PRINTF(aSource, "%s", error.get());
}
// Validate may have dropped some fields from the transaction, check it's not // empty before continuing. if (mModified.isEmpty()) { return IPC_OK();
}
EachIndex([&](auto idx) { if (!mModified.contains(idx)) { return;
}
switch (AsCanSetResult(aOwner->CanSet(idx, mValues.Get(idx), aSource))) { case CanSetResult::Allow: break; case CanSetResult::Deny:
failedFields += idx; break; case CanSetResult::Revert:
revertTxn.mValues.Get(idx) = aOwner->mFields.mValues.Get(idx);
revertTxn.mModified += idx; break;
}
});
// If any changes need to be reverted, log them, remove them from this // transaction, and optionally send a message to the source process. if (!revertTxn.mModified.isEmpty()) { // NOTE: Logging with modified IndexSet from revert transaction, and values // from this transaction, so we log the failed values we're going to revert.
MOZ_LOG(Context::GetSyncLog(), LogLevel::Debug,
("Transaction::PartialRevert(#%" PRIx64 ", childid %d, pid %" PRIPID "): %s",
aOwner->Id(), aSource ? aSource->OtherChildID() : -1,
aSource ? aSource->OtherPid() : base::kInvalidProcessId,
FormatTransaction<Context>(revertTxn.mModified, mValues,
revertTxn.mValues)
.get()));
template <typename Context> void Transaction<Context>::Write(IPC::MessageWriter* aWriter,
mozilla::ipc::IProtocol* aActor) const { // Record which field indices will be included, and then write those fields // out. typename IndexSet::serializedType modified = mModified.serialize();
WriteIPDLParam(aWriter, aActor, modified);
EachIndex([&](auto idx) { if (mModified.contains(idx)) {
WriteIPDLParam(aWriter, aActor, mValues.Get(idx));
}
});
}
template <typename Context> bool Transaction<Context>::Read(IPC::MessageReader* aReader,
mozilla::ipc::IProtocol* aActor) { // Read in which field indices were sent by the remote, followed by the fields // identified by those indices. typename IndexSet::serializedType modified = typename IndexSet::serializedType{}; if (!ReadIPDLParam(aReader, aActor, &modified)) { returnfalse;
}
mModified.deserialize(modified);
bool ok = true;
EachIndex([&](auto idx) { if (ok && mModified.contains(idx)) {
ok = ReadIPDLParam(aReader, aActor, &mValues.Get(idx));
}
}); return ok;
}
template <typename Base, size_t Count> void FieldValues<Base, Count>::Write(IPC::MessageWriter* aWriter,
mozilla::ipc::IProtocol* aActor) const { // XXX The this-> qualification is necessary to work around a bug in older gcc // versions causing an ICE.
EachIndex([&](auto idx) { WriteIPDLParam(aWriter, aActor, this->Get(idx)); });
}
template <typename Base, size_t Count> bool FieldValues<Base, Count>::Read(IPC::MessageReader* aReader,
mozilla::ipc::IProtocol* aActor) { bool ok = true;
EachIndex([&](auto idx) { if (ok) { // XXX The this-> qualification is necessary to work around a bug in older // gcc versions causing an ICE.
ok = ReadIPDLParam(aReader, aActor, &this->Get(idx));
}
}); return ok;
}
} // namespace syncedcontext
} // namespace dom
} // namespace mozilla
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 ist noch experimentell.