diff --git a/dom/messagechannel/MessagePortParent.h b/dom/messagechannel/MessagePortParent.h index 597798242eb3..685625b227d1 100644 --- a/dom/messagechannel/MessagePortParent.h +++ b/dom/messagechannel/MessagePortParent.h @@ -8,13 +8,16 @@ #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> { friend class PMessagePortParent; public: diff --git a/dom/messagechannel/MessagePortService.cpp b/dom/messagechannel/MessagePortService.cpp index bf3c20133f87..c94219053649 100644 --- a/dom/messagechannel/MessagePortService.cpp +++ b/dom/messagechannel/MessagePortService.cpp @@ -7,6 +7,7 @@ #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" @@ -27,6 +28,23 @@ void AssertIsInMainProcess() { } // namespace +struct MessagePortService::NextParent { + uint32_t mSequenceID; + // MessagePortParent keeps the service alive, and we don't want a cycle. + CheckedUnsafePtr 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) @@ -48,13 +66,7 @@ class MessagePortService::MessagePortServiceData final { 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 mParent; FallibleTArray mNextParents; FallibleTArray> mMessages; @@ -160,8 +172,7 @@ bool MessagePortService::RequestEntangling(MessagePortParent* aParent, // 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; @@ -265,9 +276,10 @@ void MessagePortService::CloseAll(const nsID& aUUID, bool aForced) { 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(); } diff --git a/dom/messagechannel/MessagePortService.h b/dom/messagechannel/MessagePortService.h index ea96b15de7c0..ee889adb97d8 100644 --- a/dom/messagechannel/MessagePortService.h +++ b/dom/messagechannel/MessagePortService.h @@ -21,6 +21,9 @@ 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();