From 5805634945d1801abbec47ac525dcde8d72bbfac Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Tue, 17 Nov 2015 23:38:13 +0000 Subject: [PATCH] Bug 1224825 - Race condition in MessagePort::close - patch 2, r=smaug --- dom/messagechannel/MessagePort.cpp | 9 ++++++++- dom/messagechannel/MessagePortService.cpp | 9 +++++---- dom/messagechannel/MessagePortService.h | 2 +- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/dom/messagechannel/MessagePort.cpp b/dom/messagechannel/MessagePort.cpp index 9a61e6082ef1..967b6655440e 100644 --- a/dom/messagechannel/MessagePort.cpp +++ b/dom/messagechannel/MessagePort.cpp @@ -295,7 +295,7 @@ MessagePort::MessagePort(nsPIDOMWindow* aWindow) MessagePort::~MessagePort() { - Close(); + CloseForced(); MOZ_ASSERT(!mWorkerFeature); } @@ -604,6 +604,13 @@ MessagePort::CloseInternal(bool aSoftly) return; } + // Maybe we were already closing the port but softly. In this case we call + // UpdateMustKeepAlive() to consider the empty pending message queue. + if (mState == eStateDisentangledForClose && !aSoftly) { + UpdateMustKeepAlive(); + return; + } + if (mState > eStateEntangled) { return; } diff --git a/dom/messagechannel/MessagePortService.cpp b/dom/messagechannel/MessagePortService.cpp index 302406616175..6f95ec340478 100644 --- a/dom/messagechannel/MessagePortService.cpp +++ b/dom/messagechannel/MessagePortService.cpp @@ -276,7 +276,7 @@ MessagePortService::CloseAllDebugCheck(const nsID& aID, #endif void -MessagePortService::CloseAll(const nsID& aUUID) +MessagePortService::CloseAll(const nsID& aUUID, bool aForced) { MessagePortServiceData* data; if (!mPorts.Get(aUUID, &data)) { @@ -299,7 +299,8 @@ MessagePortService::CloseAll(const nsID& aUUID) // because its entangling request didn't arrive yet), we cannot close this // channel. MessagePortServiceData* destinationData; - if (mPorts.Get(destinationUUID, &destinationData) && + if (!aForced && + mPorts.Get(destinationUUID, &destinationData) && !destinationData->mMessages.IsEmpty() && destinationData->mWaitingForNewParent) { MOZ_ASSERT(!destinationData->mNextStepCloseAll); @@ -309,7 +310,7 @@ MessagePortService::CloseAll(const nsID& aUUID) mPorts.Remove(aUUID); - CloseAll(destinationUUID); + CloseAll(destinationUUID, aForced); // CloseAll calls itself recursively and it can happen that it deletes // itself. Before continuing we must check if we are still alive. @@ -410,7 +411,7 @@ MessagePortService::ForceClose(const nsID& aUUID, return false; } - CloseAll(aUUID); + CloseAll(aUUID, true); return true; } diff --git a/dom/messagechannel/MessagePortService.h b/dom/messagechannel/MessagePortService.h index 7c09dd26264b..c90fb0e899ad 100644 --- a/dom/messagechannel/MessagePortService.h +++ b/dom/messagechannel/MessagePortService.h @@ -46,7 +46,7 @@ public: private: ~MessagePortService() {} - void CloseAll(const nsID& aUUID); + void CloseAll(const nsID& aUUID, bool aForced = false); void MaybeShutdown(); class MessagePortServiceData;