From 086c044dc34dfc0f74fbe41f4ecb402b2cd34884 Mon Sep 17 00:00:00 2001
From: Daniel Baumann <daniel.baumann@progress-linux.org>
Date: Fri, 19 Apr 2024 03:13:33 +0200
Subject: Merging upstream version 125.0.1.

Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
---
 dom/messagechannel/MessagePort.cpp | 36 ++++++++++++++++++++++++++++++++----
 1 file changed, 32 insertions(+), 4 deletions(-)

(limited to 'dom/messagechannel/MessagePort.cpp')

diff --git a/dom/messagechannel/MessagePort.cpp b/dom/messagechannel/MessagePort.cpp
index 23c54cde25..5c07311427 100644
--- a/dom/messagechannel/MessagePort.cpp
+++ b/dom/messagechannel/MessagePort.cpp
@@ -204,7 +204,8 @@ already_AddRefed<MessagePort> MessagePort::Create(nsIGlobalObject* aGlobal,
                                                   ErrorResult& aRv) {
   MOZ_ASSERT(aGlobal);
 
-  RefPtr<MessagePort> mp = new MessagePort(aGlobal, eStateUnshippedEntangled);
+  RefPtr<MessagePort> mp =
+      new MessagePort(aGlobal, eStateInitializingUnshippedEntangled);
   mp->Initialize(aUUID, aDestinationUUID, 1 /* 0 is an invalid sequence ID */,
                  false /* Neutered */, aRv);
   return mp.forget();
@@ -223,11 +224,16 @@ already_AddRefed<MessagePort> MessagePort::Create(
   return mp.forget();
 }
 
-void MessagePort::UnshippedEntangle(MessagePort* aEntangledPort) {
+void MessagePort::UnshippedEntangle(RefPtr<MessagePort>& aEntangledPort) {
   MOZ_DIAGNOSTIC_ASSERT(aEntangledPort);
   MOZ_DIAGNOSTIC_ASSERT(!mUnshippedEntangledPort);
 
-  mUnshippedEntangledPort = aEntangledPort;
+  if (mState == eStateInitializingUnshippedEntangled) {
+    mUnshippedEntangledPort = aEntangledPort;
+    mState = eStateUnshippedEntangled;
+  } else {
+    MOZ_ASSERT_UNREACHABLE("Should not have been called.");
+  }
 }
 
 void MessagePort::Initialize(const nsID& aUUID, const nsID& aDestinationUUID,
@@ -251,7 +257,7 @@ void MessagePort::Initialize(const nsID& aUUID, const nsID& aDestinationUUID,
       return;
     }
   } else {
-    MOZ_ASSERT(mState == eStateUnshippedEntangled);
+    MOZ_ASSERT(mState == eStateInitializingUnshippedEntangled);
   }
 
   // The port has to keep itself alive until it's entangled.
@@ -332,6 +338,12 @@ void MessagePort::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
     return;
   }
 
+  if (mState == eStateInitializingUnshippedEntangled) {
+    MOZ_ASSERT_UNREACHABLE(
+        "Should be eStateUnshippedEntangled or eStateDisentangled by now.");
+    return;
+  }
+
   // If we are unshipped we are connected to the other port on the same thread.
   if (mState == eStateUnshippedEntangled) {
     MOZ_DIAGNOSTIC_ASSERT(mUnshippedEntangledPort);
@@ -390,6 +402,11 @@ void MessagePort::Dispatch() {
   }
 
   switch (mState) {
+    case eStateInitializingUnshippedEntangled:
+      MOZ_ASSERT_UNREACHABLE(
+          "Should be eStateUnshippedEntangled or eStateDisentangled by now.");
+      break;
+
     case eStateUnshippedEntangled:
       // Everything is fine here. We have messages because the other
       // port populates our queue directly.
@@ -459,6 +476,17 @@ void MessagePort::CloseInternal(bool aSoftly) {
   // now invalid.
   mRefMessageBodyService->ForgetPort(mIdentifier->uuid());
 
+  if (mState == eStateInitializingUnshippedEntangled) {
+    // We can end up here if we failed to create our WorkerRef.  Our Create
+    // method will end up returning an error and MessageChannel will not bother
+    // creating our counterpart port or calling UnshippedEntangle (and we
+    // assert on this).
+    mState = eStateDisentangledForClose;
+
+    UpdateMustKeepAlive();
+    return;
+  }
+
   if (mState == eStateUnshippedEntangled) {
     MOZ_DIAGNOSTIC_ASSERT(mUnshippedEntangledPort);
 
-- 
cgit v1.2.3