void MessagePort::CloneAndDisentangle(MessagePortIdentifier& aIdentifier) { MOZ_ASSERT(mIdentifier); // We can clone a port that has already been transfered. In this case, on the // otherside will have a neutered port. Here we set neutered to true so that // we are safe in case a early return. aIdentifier.neutered() = true; if (mState > eStateEntangled) { return; } // We already have a 'next step'. We have to consider this port as already // cloned/closed/disentangled. if (mState == eStateEntanglingForDisentangle || mState == eStateEntanglingForClose) { return; } aIdentifier.uuid() = mIdentifier->uuid(); aIdentifier.destinationUuid() = mIdentifier->destinationUuid(); aIdentifier.sequenceId() = mIdentifier->sequenceId() + 1; aIdentifier.neutered() = false; // We have to entangle first. if (mState == eStateUnshippedEntangled) { MOZ_ASSERT(mUnshippedEntangledPort); MOZ_ASSERT(mMessagesForTheOtherPort.IsEmpty()); // Disconnect the entangled port and connect it to PBackground. mUnshippedEntangledPort->ConnectToPBackground(); mUnshippedEntangledPort = nullptr; // In this case, we don't need to be connected to the PBackground service. if (mMessages.IsEmpty()) { aIdentifier.sequenceId() = mIdentifier->sequenceId(); mState = eStateDisentangled; UpdateMustKeepAlive(); return; } // Register this component to PBackground. ConnectToPBackground(); mState = eStateEntanglingForDisentangle; return; } // Not entangled yet, we have to wait. if (mState == eStateEntangling) { mState = eStateEntanglingForDisentangle; return; } MOZ_ASSERT(mState == eStateEntangled); StartDisentangling(); }
/* static */ void MessagePort::ForceClose(const MessagePortIdentifier& aIdentifier) { mozilla::ipc::PBackgroundChild* actorChild = mozilla::ipc::BackgroundChild::GetOrCreateForCurrentThread(); if (NS_WARN_IF(!actorChild)) { MOZ_CRASH("Failed to create a PBackgroundChild actor!"); } Unused << actorChild->SendMessagePortForceClose(aIdentifier.uuid(), aIdentifier.destinationUuid(), aIdentifier.sequenceId()); }