Bug 1583321 - Allow sending same entry multiple times during one IPC call. r=nika

Differential Revision: https://phabricator.services.mozilla.com/D46935

--HG--
extra : rebase_source : 48fcbe1dc8c83af1d85575c32e33a904636d31de
extra : source : 184c14258def58dd1796cf2259a6fecf1cbc055c
extra : histedit_source : 3423197858c817b2c10140543105550a7b2ca913
This commit is contained in:
Peter Van der Beken 2019-09-30 15:25:53 +02:00
Родитель bc0cfa0be9
Коммит 3d62c6c2fb
14 изменённых файлов: 242 добавлений и 140 удалений

Просмотреть файл

@ -0,0 +1,78 @@
/* -*- 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 "mozilla/dom/MaybeNewPSHEntry.h"
#include "mozilla/dom/PContentParent.h"
#include "mozilla/dom/SHEntryChild.h"
#include "mozilla/dom/SHEntryParent.h"
namespace mozilla {
namespace ipc {
template <>
struct IPDLParamTraits<dom::NewPSHEntry> {
static void Write(IPC::Message* aMsg, IProtocol* aActor,
dom::NewPSHEntry&& aEntry) {
MOZ_RELEASE_ASSERT(aActor->GetSide() == ParentSide, "wrong side!");
WriteIPDLParam(aMsg, aActor, std::move(aEntry.mEndpoint));
WriteIPDLParam(aMsg, aActor, aEntry.mSharedID);
}
static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,
IProtocol* aActor, dom::NewPSHEntry* aEntry) {
MOZ_RELEASE_ASSERT(aActor->GetSide() == ChildSide, "wrong side!");
return ReadIPDLParam(aMsg, aIter, aActor, &aEntry->mEndpoint) &&
ReadIPDLParam(aMsg, aIter, aActor, &aEntry->mSharedID);
}
};
/* static */
void IPDLParamTraits<dom::CrossProcessSHEntry*>::Write(
IPC::Message* aMsg, IProtocol* aActor, dom::CrossProcessSHEntry* aEntry) {
MOZ_RELEASE_ASSERT(aActor->GetSide() == ParentSide, "wrong side!");
MOZ_DIAGNOSTIC_ASSERT(aActor->ToplevelProtocol()->GetProtocolId() ==
PContentMsgStart);
dom::MaybeNewPSHEntryParent entry(static_cast<dom::PSHEntryParent*>(nullptr));
if (aEntry) {
entry = static_cast<dom::LegacySHEntry*>(aEntry)->GetOrCreateActor(
static_cast<dom::PContentParent*>(aActor->ToplevelProtocol()));
}
WriteIPDLParam(aMsg, aActor, std::move(entry));
}
/* static */
bool IPDLParamTraits<dom::CrossProcessSHEntry*>::Read(
const IPC::Message* aMsg, PickleIterator* aIter,
mozilla::ipc::IProtocol* aActor, RefPtr<dom::CrossProcessSHEntry>* aEntry) {
MOZ_RELEASE_ASSERT(aActor->GetSide() == ChildSide, "wrong side!");
dom::MaybeNewPSHEntryChild actor(static_cast<dom::PSHEntryChild*>(nullptr));
if (!ReadIPDLParam(aMsg, aIter, aActor, &actor)) {
aActor->FatalError("Error deserializing MaybeNewPSHEntry");
return false;
}
return actor.match(
[&](dom::PSHEntryChild*& entry) {
*aEntry = static_cast<dom::SHEntryChild*>(entry);
return true;
},
[&](dom::NewPSHEntry& newEntry) {
RefPtr<dom::SHEntryChild> entry =
new dom::SHEntryChild(newEntry.mSharedID);
dom::ContentChild::GetSingleton()->BindPSHEntryEndpoint(
std::move(newEntry.mEndpoint), do_AddRef(entry).take());
*aEntry = entry.forget();
return true;
});
}
} // namespace ipc
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,56 @@
/* -*- 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/. */
#ifndef mozilla_dom_MaybeNewPSHEntry_h
#define mozilla_dom_MaybeNewPSHEntry_h
#include "ipc/IPCMessageUtils.h"
#include "mozilla/AlreadyAddRefed.h"
#include "mozilla/Variant.h"
#include "mozilla/ipc/IPDLParamTraits.h"
#include "mozilla/ipc/ProtocolUtils.h"
namespace mozilla {
namespace dom {
class LegacySHEntry;
class PSHEntryChild;
class PSHEntryParent;
class SHEntryChild;
struct NewPSHEntry final {
mozilla::ipc::ManagedEndpoint<PSHEntryChild> mEndpoint;
uint64_t mSharedID;
};
typedef Variant<PSHEntryParent*, NewPSHEntry> MaybeNewPSHEntryParent;
typedef Variant<PSHEntryChild*, NewPSHEntry> MaybeNewPSHEntryChild;
// Any IPDL protocol trying to pass this (as argument or return value) needs to
// be managed by PContent.
class CrossProcessSHEntry {
NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
SHEntryChild* ToSHEntryChild();
};
} // namespace dom
namespace ipc {
template <>
struct IPDLParamTraits<dom::CrossProcessSHEntry*> {
static void Write(IPC::Message* aMsg, IProtocol* aActor,
dom::CrossProcessSHEntry* aEntry);
static bool Read(const IPC::Message* aMsg, PickleIterator* aIter,
IProtocol* aActor, RefPtr<dom::CrossProcessSHEntry>* aEntry);
};
} // namespace ipc
} // namespace mozilla
#endif /* mozilla_dom_MaybeNewPSHEntry_h */

Просмотреть файл

@ -1,27 +0,0 @@
/* 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 protocol PSHEntry;
namespace mozilla {
namespace dom {
union PSHEntryOrSharedID
{
PSHEntry;
uint64_t;
};
struct NewPSHEntry {
ManagedEndpoint<PSHEntryChild> endpoint;
uint64_t sharedID;
};
union MaybeNewPSHEntry {
nullable PSHEntry;
NewPSHEntry;
};
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -6,8 +6,8 @@ include protocol PContent;
include protocol PSHistory;
include DOMTypes;
include NewPSHEntry;
using refcounted class mozilla::dom::CrossProcessSHEntry from "mozilla/dom/MaybeNewPSHEntry.h";
using refcounted class nsDocShellLoadState from "mozilla/dom/DocShellMessageUtils.h";
using struct nsID from "nsID.h";
using nsIntRect from "nsRect.h";
@ -16,6 +16,8 @@ namespace mozilla {
namespace dom {
sync protocol PSHEntry {
// IPDLParamTraits<dom::CrossProcessSHEntry*>::Write relies on PContent being
// the manager.
manager PContent;
parent:
@ -37,7 +39,7 @@ parent:
async SetSticky(bool sticky);
sync GetPostData() returns (nsIInputStream postData);
async SetPostData(nsIInputStream postData);
sync GetParent() returns (MaybeNewPSHEntry parentEntry);
sync GetParent() returns (CrossProcessSHEntry parentEntry);
async SetParent(nullable PSHEntry parentEntry);
sync GetLoadType() returns (uint32_t loadType);
async SetLoadType(uint32_t loadType);
@ -100,8 +102,8 @@ parent:
async SetLoadTypeAsHistory();
sync AddChild(nullable PSHEntry childEntry, int32_t offset, bool useRemoteSubframes) returns (nsresult result);
sync RemoveChild(PSHEntry childEntry) returns (nsresult result);
sync GetChildAt(int32_t index) returns (MaybeNewPSHEntry childEntry);
sync GetChildSHEntryIfHasNoDynamicallyAddedChild(int32_t childOffset) returns (MaybeNewPSHEntry childEntry);
sync GetChildAt(int32_t index) returns (CrossProcessSHEntry childEntry);
sync GetChildSHEntryIfHasNoDynamicallyAddedChild(int32_t childOffset) returns (CrossProcessSHEntry childEntry);
sync ReplaceChild(PSHEntry newChildEntry) returns (nsresult result);
async ClearEntry(uint64_t aNewSharedID);
sync CreateLoadInfo() returns (nsDocShellLoadState loadState);

Просмотреть файл

@ -6,9 +6,9 @@ include protocol PContent;
include protocol PSHEntry;
include DOMTypes;
include NewPSHEntry;
using refcounted class mozilla::dom::BrowsingContext from "mozilla/dom/BrowsingContext.h";
using refcounted class mozilla::dom::CrossProcessSHEntry from "mozilla/dom/MaybeNewPSHEntry.h";
using refcounted class nsDocShellLoadState from "mozilla/dom/DocShellMessageUtils.h";
using struct nsID from "nsID.h";
@ -19,7 +19,7 @@ namespace dom {
struct LoadSHEntryData
{
MaybeNewPSHEntry shEntry;
CrossProcessSHEntry shEntry;
BrowsingContext browsingContext;
nsDocShellLoadState loadState;
};
@ -30,6 +30,8 @@ union LoadSHEntryResult {
};
sync protocol PSHistory {
// IPDLParamTraits<dom::CrossProcessSHEntry*>::Write relies on PContent being
// the manager.
manager PContent;
parent:
@ -38,7 +40,7 @@ parent:
sync SetIndex(int32_t index) returns (nsresult result);
sync GetRequestedIndex() returns (int32_t index);
async InternalSetRequestedIndex(int32_t index);
sync GetEntryAtIndex(int32_t index) returns (nsresult result, MaybeNewPSHEntry entry);
sync GetEntryAtIndex(int32_t index) returns (nsresult result, CrossProcessSHEntry entry);
sync PurgeHistory(int32_t numEntries) returns (nsresult result);
sync ReloadCurrentEntry() returns (LoadSHEntryResult load);
sync GotoIndex(int32_t index) returns (LoadSHEntryResult load);
@ -53,8 +55,9 @@ parent:
sync RemoveEntries(nsID[] ids, int32_t index) returns (bool didRemove);
async RemoveFrameEntries(PSHEntry entry);
sync Reload(uint32_t reloadFlags) returns (LoadSHEntryResult load);
sync GetAllEntries() returns (MaybeNewPSHEntry[] entries);
sync FindEntryForBFCache(uint64_t sharedID, bool includeCurrentEntry) returns (MaybeNewPSHEntry entries, int32_t startIndex);
sync GetAllEntries() returns (CrossProcessSHEntry[] entries);
sync FindEntryForBFCache(uint64_t sharedID, bool includeCurrentEntry)
returns (CrossProcessSHEntry entries, int32_t startIndex);
async Evict(PSHEntry[] entry);
async EnsureCorrectEntryAtCurrIndex(PSHEntry entry);
async EvictContentViewersOrReplaceEntry(nullable PSHEntry newSHEntry, bool replace);

Просмотреть файл

@ -7,6 +7,8 @@
#include "SHEntryChild.h"
#include "SHistoryChild.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/StaticPrefs_docshell.h"
#include "mozilla/dom/MaybeNewPSHEntry.h"
#include "nsDocShellEditorData.h"
#include "nsDocShellLoadState.h"
#include "nsIContentViewer.h"
@ -593,12 +595,12 @@ SHEntryChild::Clone(nsISHEntry** aResult) {
NS_IMETHODIMP
SHEntryChild::GetParent(nsISHEntry** aResult) {
MaybeNewPSHEntry parent;
RefPtr<CrossProcessSHEntry> parent;
if (!SendGetParent(&parent)) {
return NS_ERROR_FAILURE;
}
*aResult = SHEntryChild::GetOrCreate(parent).take();
*aResult = parent ? do_AddRef(parent->ToSHEntryChild()).take() : nullptr;
return NS_OK;
}
@ -808,21 +810,21 @@ SHEntryChild::RemoveChild(nsISHEntry* aChild) {
NS_IMETHODIMP
SHEntryChild::GetChildAt(int32_t aIndex, nsISHEntry** aResult) {
MaybeNewPSHEntry child;
RefPtr<CrossProcessSHEntry> child;
if (!SendGetChildAt(aIndex, &child)) {
return NS_ERROR_FAILURE;
}
*aResult = SHEntryChild::GetOrCreate(child).take();
*aResult = child ? do_AddRef(child->ToSHEntryChild()).take() : nullptr;
return NS_OK;
}
NS_IMETHODIMP_(void)
SHEntryChild::GetChildSHEntryIfHasNoDynamicallyAddedChild(int32_t aChildOffset,
nsISHEntry** aChild) {
MaybeNewPSHEntry child;
RefPtr<CrossProcessSHEntry> child;
SendGetChildSHEntryIfHasNoDynamicallyAddedChild(aChildOffset, &child);
*aChild = SHEntryChild::GetOrCreate(child).take();
*aChild = child ? do_AddRef(child->ToSHEntryChild()).take() : nullptr;
}
NS_IMETHODIMP
@ -1012,20 +1014,5 @@ void SHEntryChild::EvictContentViewer() {
}
}
/* static */
already_AddRefed<SHEntryChild> SHEntryChild::GetOrCreate(
MaybeNewPSHEntry& aEntry) {
RefPtr<SHEntryChild> entry;
if (aEntry.type() == MaybeNewPSHEntry::TNewPSHEntry) {
NewPSHEntry& newEntry = aEntry.get_NewPSHEntry();
entry = new SHEntryChild(newEntry.sharedID());
ContentChild::GetSingleton()->BindPSHEntryEndpoint(
std::move(newEntry.endpoint()), do_AddRef(entry).take());
} else {
entry = static_cast<SHEntryChild*>(aEntry.get_PSHEntryChild());
}
return entry.forget();
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -8,6 +8,7 @@
#define mozilla_dom_SHEntryChild_h
#include "mozilla/dom/PSHEntryChild.h"
#include "mozilla/dom/MaybeNewPSHEntry.h"
#include "nsContentUtils.h"
#include "nsExpirationTracker.h"
#include "nsIBFCacheEntry.h"
@ -84,8 +85,11 @@ class SHEntryChildShared final : public nsIBFCacheEntry,
/**
* Session history entry actor for the child process.
*/
class SHEntryChild final : public PSHEntryChild, public nsISHEntry {
class SHEntryChild final : public PSHEntryChild,
public nsISHEntry,
public CrossProcessSHEntry {
friend class PSHEntryChild;
using PSHEntryChild::CrossProcessSHEntry;
public:
explicit SHEntryChild(const SHEntryChild* aClone)
@ -99,8 +103,6 @@ class SHEntryChild final : public PSHEntryChild, public nsISHEntry {
void EvictContentViewer();
static already_AddRefed<SHEntryChild> GetOrCreate(MaybeNewPSHEntry& aEntry);
protected:
void ActorDestroy(ActorDestroyReason aWhy) override {
mIPCActorDeleted = true;
@ -113,6 +115,11 @@ class SHEntryChild final : public PSHEntryChild, public nsISHEntry {
bool mIPCActorDeleted;
};
inline SHEntryChild* CrossProcessSHEntry::ToSHEntryChild() {
MOZ_ASSERT(XRE_IsContentProcess(), "Wrong side!");
return static_cast<SHEntryChild*>(this);
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -7,6 +7,7 @@
#include "SHEntryParent.h"
#include "SHistoryParent.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/MaybeNewPSHEntry.h"
#include "nsStructuredCloneContainer.h"
namespace mozilla {
@ -24,21 +25,22 @@ void SHEntrySharedParent::Destroy() {
SHEntrySharedParentState::Destroy();
}
NS_IMPL_ISUPPORTS_INHERITED0(LegacySHEntry, nsSHEntry)
SHEntryParent* LegacySHEntry::CreateActor() {
MOZ_ASSERT(!mActor);
mActor = new SHEntryParent(this);
return mActor;
}
void LegacySHEntry::GetOrCreateActor(PContentParent* aContentParent,
MaybeNewPSHEntry& aEntry) {
if (!mActor) {
mActor = new SHEntryParent(this);
aEntry =
NewPSHEntry(aContentParent->OpenPSHEntryEndpoint(mActor), mShared->mID);
} else {
aEntry = mActor;
MaybeNewPSHEntryParent LegacySHEntry::GetOrCreateActor(
PContentParent* aContentParent) {
if (mActor) {
return AsVariant(static_cast<PSHEntryParent*>(mActor));
}
return AsVariant(NewPSHEntry{
aContentParent->OpenPSHEntryEndpoint(CreateActor()), mShared->mID});
}
void LegacySHEntry::AbandonBFCacheEntry(uint64_t aNewSharedID) {
@ -156,9 +158,9 @@ bool SHEntryParent::RecvSetPostData(nsIInputStream* aPostData) {
return true;
}
bool SHEntryParent::RecvGetParent(MaybeNewPSHEntry* aParentEntry) {
bool SHEntryParent::RecvGetParent(RefPtr<CrossProcessSHEntry>* aParentEntry) {
nsCOMPtr<nsISHEntry> parent = mEntry->GetParent();
GetOrCreate(parent, aParentEntry);
*aParentEntry = parent.forget().downcast<LegacySHEntry>();
return true;
}
@ -507,21 +509,21 @@ bool SHEntryParent::RecvRemoveChild(PSHEntryParent* aChild, nsresult* aResult) {
}
bool SHEntryParent::RecvGetChildAt(const int32_t& aIndex,
MaybeNewPSHEntry* aChild) {
RefPtr<CrossProcessSHEntry>* aChild) {
nsCOMPtr<nsISHEntry> child;
DebugOnly<nsresult> rv = mEntry->GetChildAt(aIndex, getter_AddRefs(child));
MOZ_ASSERT(NS_SUCCEEDED(rv), "Didn't expect this to fail.");
GetOrCreate(child, aChild);
*aChild = child.forget().downcast<LegacySHEntry>();
return true;
}
bool SHEntryParent::RecvGetChildSHEntryIfHasNoDynamicallyAddedChild(
const int32_t& aChildOffset, MaybeNewPSHEntry* aChild) {
const int32_t& aChildOffset, RefPtr<CrossProcessSHEntry>* aChild) {
nsCOMPtr<nsISHEntry> child;
mEntry->GetChildSHEntryIfHasNoDynamicallyAddedChild(aChildOffset,
getter_AddRefs(child));
GetOrCreate(child, aChild);
*aChild = child.forget().downcast<LegacySHEntry>();
return true;
}
@ -532,15 +534,6 @@ bool SHEntryParent::RecvReplaceChild(PSHEntryParent* aNewChild,
return true;
}
void SHEntryParent::GetOrCreate(PContentParent* aManager, nsISHEntry* aSHEntry,
MaybeNewPSHEntry& aResult) {
if (aSHEntry) {
static_cast<LegacySHEntry*>(aSHEntry)->GetOrCreateActor(aManager, aResult);
} else {
aResult = (PSHEntryParent*)nullptr;
}
}
bool SHEntryParent::RecvClearEntry(const uint64_t& aNewSharedID) {
mEntry->ClearEntry();
mEntry->AbandonBFCacheEntry(aNewSharedID);

Просмотреть файл

@ -8,6 +8,7 @@
#define mozilla_dom_SHistoryEntry_h
#include "mozilla/dom/PSHEntryParent.h"
#include "mozilla/dom/MaybeNewPSHEntry.h"
#include "mozilla/WeakPtr.h"
#include "nsSHEntry.h"
#include "nsSHEntryShared.h"
@ -41,7 +42,7 @@ class SHEntrySharedParent : public SHEntrySharedParentState {
* The actor is (re)created as needed, whenever we need to return an entry to
* the child process. The lifetime is determined by the child side.
*/
class LegacySHEntry final : public nsSHEntry {
class LegacySHEntry final : public nsSHEntry, public CrossProcessSHEntry {
public:
LegacySHEntry(PContentParent* aParent, uint64_t aSharedID)
: nsSHEntry(new SHEntrySharedParent(aParent, aSharedID)),
@ -49,8 +50,9 @@ class LegacySHEntry final : public nsSHEntry {
explicit LegacySHEntry(const LegacySHEntry& aEntry)
: nsSHEntry(aEntry), mActor(nullptr) {}
void GetOrCreateActor(PContentParent* aContentParent,
MaybeNewPSHEntry& aEntry);
NS_DECL_ISUPPORTS_INHERITED
MaybeNewPSHEntryParent GetOrCreateActor(PContentParent* aContentParent);
using nsSHEntry::AbandonBFCacheEntry;
void AbandonBFCacheEntry(uint64_t aNewSharedID);
@ -65,6 +67,8 @@ class LegacySHEntry final : public nsSHEntry {
friend class SHEntryParent;
friend class ContentParent;
~LegacySHEntry() {}
SHEntryParent* CreateActor();
SHEntryParent* mActor;
@ -83,9 +87,6 @@ class SHEntryParent final : public PSHEntryParent {
explicit SHEntryParent(LegacySHEntry* aEntry)
: PSHEntryParent(), mEntry(aEntry) {}
static void GetOrCreate(PContentParent* aManager, nsISHEntry* aSHEntry,
MaybeNewPSHEntry& aResult);
LegacySHEntry* GetSHEntry() { return mEntry; }
protected:
@ -110,7 +111,7 @@ class SHEntryParent final : public PSHEntryParent {
bool RecvSetSticky(const bool& aSticky);
bool RecvGetPostData(RefPtr<nsIInputStream>* aPostData);
bool RecvSetPostData(nsIInputStream* aPostData);
bool RecvGetParent(MaybeNewPSHEntry* aParentEntry);
bool RecvGetParent(RefPtr<CrossProcessSHEntry>* aParentEntry);
bool RecvSetParent(PSHEntryParent* aParentEntry);
bool RecvGetLoadType(uint32_t* aLoadType);
bool RecvSetLoadType(const uint32_t& aLoadType);
@ -180,15 +181,13 @@ class SHEntryParent final : public PSHEntryParent {
bool RecvAddChild(PSHEntryParent* aChild, const int32_t& aOffset,
const bool& aUseRemoteSubframes, nsresult* aResult);
bool RecvRemoveChild(PSHEntryParent* aChild, nsresult* aResult);
bool RecvGetChildAt(const int32_t& aIndex, MaybeNewPSHEntry* aChild);
bool RecvGetChildAt(const int32_t& aIndex,
RefPtr<CrossProcessSHEntry>* aChild);
bool RecvGetChildSHEntryIfHasNoDynamicallyAddedChild(
const int32_t& aChildOffset, MaybeNewPSHEntry* aChild);
const int32_t& aChildOffset, RefPtr<CrossProcessSHEntry>* aChild);
bool RecvReplaceChild(PSHEntryParent* aNewChild, nsresult* aResult);
bool RecvClearEntry(const uint64_t& aNewSharedID);
void GetOrCreate(nsISHEntry* aSHEntry, MaybeNewPSHEntry* aResult) {
GetOrCreate(Manager(), aSHEntry, *aResult);
}
bool RecvCreateLoadInfo(RefPtr<nsDocShellLoadState>* aLoadState);
RefPtr<LegacySHEntry> mEntry;

Просмотреть файл

@ -95,16 +95,15 @@ SHistoryChild::InternalSetRequestedIndex(int32_t aRequestedIndex) {
NS_IMETHODIMP
SHistoryChild::GetEntryAtIndex(int32_t aIndex, nsISHEntry** aResult) {
nsresult rv;
MaybeNewPSHEntry entry;
RefPtr<CrossProcessSHEntry> entry;
if (!SendGetEntryAtIndex(aIndex, &rv, &entry)) {
return NS_ERROR_FAILURE;
}
RefPtr<SHEntryChild> child;
if (NS_SUCCEEDED(rv)) {
child = SHEntryChild::GetOrCreate(entry);
}
child.forget(aResult);
return rv;
NS_ENSURE_SUCCESS(rv, rv);
*aResult = entry ? do_AddRef(entry->ToSHEntryChild()).take() : nullptr;
return NS_OK;
}
NS_IMETHODIMP
@ -245,14 +244,14 @@ NS_IMETHODIMP
SHistoryChild::EvictExpiredContentViewerForEntry(nsIBFCacheEntry* aBFEntry) {
SHEntryChildShared* shared = static_cast<SHEntryChildShared*>(aBFEntry);
MaybeNewPSHEntry entry;
RefPtr<CrossProcessSHEntry> entry;
int32_t index;
if (!SendFindEntryForBFCache(shared->GetID(), false, &entry, &index)) {
return NS_ERROR_FAILURE;
}
RefPtr<SHEntryChild> shEntry = SHEntryChild::GetOrCreate(entry);
if (shEntry) {
RefPtr<SHEntryChild> shEntry;
if (entry && (shEntry = entry->ToSHEntryChild())) {
shEntry->EvictContentViewer();
SendEvict(nsTArray<PSHEntryChild*>({shEntry.get()}));
}
@ -262,7 +261,7 @@ SHistoryChild::EvictExpiredContentViewerForEntry(nsIBFCacheEntry* aBFEntry) {
NS_IMETHODIMP
SHistoryChild::EvictAllContentViewers(void) {
nsTArray<MaybeNewPSHEntry> entries;
nsTArray<RefPtr<CrossProcessSHEntry>> entries;
if (!SendGetAllEntries(&entries)) {
return NS_ERROR_FAILURE;
}
@ -270,8 +269,8 @@ SHistoryChild::EvictAllContentViewers(void) {
// Keep a strong reference to all the entries, we're going to send the array
// back to the parent!
nsTArray<RefPtr<SHEntryChild>> shEntries(entries.Length());
for (MaybeNewPSHEntry& entry : entries) {
RefPtr<SHEntryChild> shEntry = SHEntryChild::GetOrCreate(entry);
for (RefPtr<CrossProcessSHEntry>& entry : entries) {
RefPtr<SHEntryChild> shEntry = entry->ToSHEntryChild();
shEntry->EvictContentViewer();
shEntries.AppendElement(shEntry.forget());
}
@ -318,7 +317,7 @@ SHistoryChild::EnsureCorrectEntryAtCurrIndex(nsISHEntry* aEntry) {
NS_IMETHODIMP_(void)
SHistoryChild::RemoveDynEntriesForBFCacheEntry(nsIBFCacheEntry* aBFEntry) {
MaybeNewPSHEntry entry;
RefPtr<CrossProcessSHEntry> entry;
int32_t index;
if (!SendFindEntryForBFCache(
static_cast<SHEntryChildShared*>(aBFEntry)->GetID(), true, &entry,
@ -326,8 +325,8 @@ SHistoryChild::RemoveDynEntriesForBFCacheEntry(nsIBFCacheEntry* aBFEntry) {
return;
}
RefPtr<SHEntryChild> shEntry = SHEntryChild::GetOrCreate(entry);
if (shEntry) {
RefPtr<SHEntryChild> shEntry;
if (entry && (shEntry = entry->ToSHEntryChild())) {
RemoveDynEntries(index, shEntry);
}
}
@ -364,7 +363,10 @@ nsresult SHistoryChild::LoadURI(LoadSHEntryData& aLoadData) {
nsCOMPtr<nsIDocShell> docShell = aLoadData.browsingContext()->GetDocShell();
NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
RefPtr<SHEntryChild> entry = SHEntryChild::GetOrCreate(aLoadData.shEntry());
RefPtr<SHEntryChild> entry;
if (aLoadData.shEntry()) {
entry = aLoadData.shEntry()->ToSHEntryChild();
}
// FIXME Should this be sent through IPC?
aLoadData.loadState()->SetSHEntry(entry);

Просмотреть файл

@ -27,11 +27,9 @@ static void FillInLoadResult(PContentParent* aManager, nsresult aRv,
const nsSHistory::LoadEntryResult& aLoadResult,
LoadSHEntryResult* aResult) {
if (NS_SUCCEEDED(aRv)) {
MaybeNewPSHEntry entry;
static_cast<LegacySHEntry*>(aLoadResult.mLoadState->SHEntry())
->GetOrCreateActor(aManager, entry);
*aResult = LoadSHEntryData(std::move(entry), aLoadResult.mBrowsingContext,
aLoadResult.mLoadState);
*aResult = LoadSHEntryData(
static_cast<LegacySHEntry*>(aLoadResult.mLoadState->SHEntry()),
aLoadResult.mBrowsingContext, aLoadResult.mLoadState);
} else {
*aResult = aRv;
}
@ -67,10 +65,10 @@ bool SHistoryParent::RecvInternalSetRequestedIndex(int32_t aIndex) {
}
bool SHistoryParent::RecvGetEntryAtIndex(int32_t aIndex, nsresult* aResult,
MaybeNewPSHEntry* aEntry) {
RefPtr<CrossProcessSHEntry>* aEntry) {
nsCOMPtr<nsISHEntry> entry;
*aResult = mHistory->GetEntryAtIndex(aIndex, getter_AddRefs(entry));
SHEntryParent::GetOrCreate(Manager(), entry, *aEntry);
*aEntry = entry.forget().downcast<LegacySHEntry>();
return true;
}
@ -83,11 +81,9 @@ bool SHistoryParent::RecvReloadCurrentEntry(LoadSHEntryResult* aLoadResult) {
nsSHistory::LoadEntryResult loadResult;
nsresult rv = mHistory->ReloadCurrentEntry(loadResult);
if (NS_SUCCEEDED(rv)) {
MaybeNewPSHEntry entry;
SHEntryParent::GetOrCreate(Manager(), loadResult.mLoadState->SHEntry(),
entry);
*aLoadResult = LoadSHEntryData(
std::move(entry), loadResult.mBrowsingContext, loadResult.mLoadState);
static_cast<LegacySHEntry*>(loadResult.mLoadState->SHEntry()),
loadResult.mBrowsingContext, loadResult.mLoadState);
} else {
*aLoadResult = rv;
}
@ -185,21 +181,20 @@ bool SHistoryParent::RecvReload(const uint32_t& aReloadFlags,
return true;
}
bool SHistoryParent::RecvGetAllEntries(nsTArray<MaybeNewPSHEntry>* aEntries) {
bool SHistoryParent::RecvGetAllEntries(
nsTArray<RefPtr<CrossProcessSHEntry>>* aEntries) {
nsTArray<nsCOMPtr<nsISHEntry>>& entries = mHistory->Entries();
uint32_t length = entries.Length();
aEntries->AppendElements(length);
for (uint32_t i = 0; i < length; ++i) {
SHEntryParent::GetOrCreate(Manager(), entries[i].get(),
aEntries->ElementAt(i));
aEntries->ElementAt(i) = static_cast<LegacySHEntry*>(entries[i].get());
}
return true;
}
bool SHistoryParent::RecvFindEntryForBFCache(const uint64_t& aSharedID,
const bool& aIncludeCurrentEntry,
MaybeNewPSHEntry* aEntry,
int32_t* aIndex) {
bool SHistoryParent::RecvFindEntryForBFCache(
const uint64_t& aSharedID, const bool& aIncludeCurrentEntry,
RefPtr<CrossProcessSHEntry>* aEntry, int32_t* aIndex) {
int32_t currentIndex;
mHistory->GetIndex(&currentIndex);
int32_t startSafeIndex, endSafeIndex;
@ -209,20 +204,20 @@ bool SHistoryParent::RecvFindEntryForBFCache(const uint64_t& aSharedID,
nsresult rv = mHistory->GetEntryAtIndex(i, getter_AddRefs(entry));
NS_ENSURE_SUCCESS(rv, false);
if (static_cast<LegacySHEntry*>(entry.get())->GetSharedStateID() ==
aSharedID) {
RefPtr<LegacySHEntry> shEntry = entry.forget().downcast<LegacySHEntry>();
if (shEntry->GetSharedStateID() == aSharedID) {
if (!aIncludeCurrentEntry && i == currentIndex) {
*aEntry = (PSHEntryParent*)nullptr;
*aEntry = nullptr;
*aIndex = -1;
} else {
SHEntryParent::GetOrCreate(Manager(), entry, *aEntry);
*aEntry = shEntry.forget();
*aIndex = i;
}
return true;
}
}
*aEntry = (PSHEntryParent*)nullptr;
*aEntry = nullptr;
*aIndex = -1;
return true;
}

Просмотреть файл

@ -55,7 +55,7 @@ class SHistoryParent final : public PSHistoryParent {
bool RecvGetRequestedIndex(int32_t* aIndex);
bool RecvInternalSetRequestedIndex(int32_t aIndex);
bool RecvGetEntryAtIndex(int32_t aIndex, nsresult* aResult,
MaybeNewPSHEntry* aEntry);
RefPtr<CrossProcessSHEntry>* aEntry);
bool RecvPurgeHistory(int32_t aNumEntries, nsresult* aResult);
bool RecvReloadCurrentEntry(LoadSHEntryResult* aLoadResult);
bool RecvGotoIndex(int32_t aIndex, LoadSHEntryResult* aLoadResult);
@ -73,10 +73,11 @@ class SHistoryParent final : public PSHistoryParent {
bool* aDidRemove);
bool RecvRemoveFrameEntries(PSHEntryParent* aEntry);
bool RecvReload(const uint32_t& aReloadFlags, LoadSHEntryResult* aLoadResult);
bool RecvGetAllEntries(nsTArray<MaybeNewPSHEntry>* aEntries);
bool RecvGetAllEntries(nsTArray<RefPtr<CrossProcessSHEntry>>* aEntries);
bool RecvFindEntryForBFCache(const uint64_t& aSharedID,
const bool& aIncludeCurrentEntry,
MaybeNewPSHEntry* aEntry, int32_t* aIndex);
RefPtr<CrossProcessSHEntry>* aEntry,
int32_t* aIndex);
bool RecvEvict(nsTArray<PSHEntryParent*>&& aEntries);
bool RecvEnsureCorrectEntryAtCurrIndex(PSHEntryParent* aEntry);
bool RecvEvictContentViewersOrReplaceEntry(PSHEntryParent* aNewSHEntry,

Просмотреть файл

@ -14,7 +14,6 @@ XPIDL_SOURCES += [
XPIDL_MODULE = 'shistory'
IPDL_SOURCES += [
'NewPSHEntry.ipdlh',
'PSHEntry.ipdl',
'PSHistory.ipdl',
]
@ -27,6 +26,7 @@ EXPORTS += [
EXPORTS.mozilla.dom += [
'ChildSHistory.h',
'MaybeNewPSHEntry.h',
'ParentSHistory.h',
'SHEntryChild.h',
'SHEntryParent.h',
@ -36,6 +36,7 @@ EXPORTS.mozilla.dom += [
UNIFIED_SOURCES += [
'ChildSHistory.cpp',
'MaybeNewPSHEntry.cpp',
'nsSHEntry.cpp',
'nsSHEntryShared.cpp',
'nsSHistory.cpp',

Просмотреть файл

@ -66,7 +66,6 @@ include ClientIPCTypes;
include HangTypes;
include PrefsTypes;
include NeckoChannelParams;
include NewPSHEntry;
#if defined(MOZ_SANDBOX) && defined(MOZ_DEBUG) && defined(ENABLE_TESTS)
include protocol PSandboxTesting;
@ -332,6 +331,12 @@ struct PostMessageData
bool isFromPrivateWindow;
};
union PSHEntryOrSharedID
{
PSHEntry;
uint64_t;
};
/**
* The PContent protocol is a top-level protocol between the UI process
* and a content process. There is exactly one PContentParent/PContentChild pair