Bug 1597481 - upgrade heap-allocated MessagePortParent*s to CheckedUnsafePtr<MessagePortParent> r=asuth a=RyanVM
Differential Revision:
https://phabricator.services.mozilla.com/D54649
--- a/dom/messagechannel/MessagePortParent.h
+++ b/dom/messagechannel/MessagePortParent.h
@@ -3,23 +3,26 @@
/* 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_MessagePortParent_h
#define mozilla_dom_MessagePortParent_h
#include "mozilla/dom/PMessagePortParent.h"
+#include "mozilla/dom/quota/CheckedUnsafePtr.h"
namespace mozilla {
namespace dom {
class MessagePortService;
-class MessagePortParent final : public PMessagePortParent {
+class MessagePortParent final
+ : public PMessagePortParent,
+ public SupportsCheckedUnsafePtr<CheckIf<DiagnosticAssertEnabled>> {
friend class PMessagePortParent;
public:
explicit MessagePortParent(const nsID& aUUID);
~MessagePortParent();
bool Entangle(const nsID& aDestinationUUID, const uint32_t& aSequenceID);
--- a/dom/messagechannel/MessagePortService.cpp
+++ b/dom/messagechannel/MessagePortService.cpp
@@ -2,16 +2,17 @@
/* 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 "MessagePortService.h"
#include "MessagePortParent.h"
#include "SharedMessagePortMessage.h"
+#include "mozilla/dom/quota/CheckedUnsafePtr.h"
#include "mozilla/ipc/BackgroundParent.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/Unused.h"
#include "nsTArray.h"
using mozilla::ipc::AssertIsOnBackgroundThread;
namespace mozilla {
@@ -22,16 +23,33 @@ namespace {
StaticRefPtr<MessagePortService> gInstance;
void AssertIsInMainProcess() {
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
}
} // namespace
+struct MessagePortService::NextParent {
+ uint32_t mSequenceID;
+ // MessagePortParent keeps the service alive, and we don't want a cycle.
+ CheckedUnsafePtr<MessagePortParent> mParent;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+// Need to call CheckedUnsafePtr's copy constructor and destructor when
+// resizing dynamic arrays containing NextParent (by calling NextParent's
+// implicit copy constructor/destructor rather than memmove-ing NextParents).
+DECLARE_USE_COPY_CONSTRUCTORS(mozilla::dom::MessagePortService::NextParent);
+
+namespace mozilla {
+namespace dom {
+
class MessagePortService::MessagePortServiceData final {
public:
explicit MessagePortServiceData(const nsID& aDestinationUUID)
: mDestinationUUID(aDestinationUUID),
mSequenceID(1),
mParent(nullptr)
// By default we don't know the next parent.
,
@@ -43,23 +61,17 @@ class MessagePortService::MessagePortSer
MessagePortServiceData(const MessagePortServiceData& aOther) = delete;
MessagePortServiceData& operator=(const MessagePortServiceData&) = delete;
~MessagePortServiceData() { MOZ_COUNT_DTOR(MessagePortServiceData); }
nsID mDestinationUUID;
uint32_t mSequenceID;
- MessagePortParent* mParent;
-
- struct NextParent {
- uint32_t mSequenceID;
- // MessagePortParent keeps the service alive, and we don't want a cycle.
- MessagePortParent* mParent;
- };
+ CheckedUnsafePtr<MessagePortParent> mParent;
FallibleTArray<NextParent> mNextParents;
FallibleTArray<RefPtr<SharedMessagePortMessage>> mMessages;
bool mWaitingForNewParent;
bool mNextStepCloseAll;
};
@@ -155,18 +167,17 @@ bool MessagePortService::RequestEntangli
CloseAll(aParent->ID());
}
return true;
}
// This new parent will be the next one when a Disentangle request is
// received from the current parent.
- MessagePortServiceData::NextParent* nextParent =
- data->mNextParents.AppendElement(mozilla::fallible);
+ auto nextParent = data->mNextParents.AppendElement(mozilla::fallible);
if (!nextParent) {
CloseAll(aParent->ID());
return false;
}
nextParent->mSequenceID = aSequenceID;
nextParent->mParent = aParent;
@@ -260,19 +271,20 @@ void MessagePortService::CloseAll(const
MessagePortServiceData* data;
if (!mPorts.Get(aUUID, &data)) {
MaybeShutdown();
return;
}
if (data->mParent) {
data->mParent->Close();
+ data->mParent = nullptr;
}
- for (const MessagePortServiceData::NextParent& parent : data->mNextParents) {
+ for (const auto& parent : data->mNextParents) {
parent.mParent->CloseAndDelete();
}
nsID destinationUUID = data->mDestinationUUID;
// If we have informations about the other port and that port has some
// pending messages to deliver but the parent has not processed them yet,
// because its entangling request didn't arrive yet), we cannot close this
--- a/dom/messagechannel/MessagePortService.h
+++ b/dom/messagechannel/MessagePortService.h
@@ -16,16 +16,19 @@ namespace dom {
class MessagePortParent;
class SharedMessagePortMessage;
class MessagePortService final {
public:
NS_INLINE_DECL_REFCOUNTING(MessagePortService)
+ // Needs to be public for the DECLARE_USE_COPY_CONSTRUCTORS macro.
+ struct NextParent;
+
static MessagePortService* Get();
static MessagePortService* GetOrCreate();
bool RequestEntangling(MessagePortParent* aParent,
const nsID& aDestinationUUID,
const uint32_t& aSequenceID);
bool DisentanglePort(