From 51f49bc2ccd55985b282eaf9fae56098d62d24ec Mon Sep 17 00:00:00 2001 From: Kyle Huey Date: Fri, 5 Oct 2012 12:09:33 -0700 Subject: [PATCH] Bug 797889: Make sure IndexedDB does not send messages to thechild after it has begun shutting down. r=bent --- dom/indexedDB/AsyncConnectionHelper.cpp | 31 +++++++++ dom/indexedDB/AsyncConnectionHelper.h | 36 ++++++++--- dom/indexedDB/IDBCursor.cpp | 10 ++- dom/indexedDB/IDBDatabase.cpp | 44 ++++++++++--- dom/indexedDB/IDBDatabase.h | 10 ++- dom/indexedDB/IDBIndex.cpp | 76 +++++++++------------- dom/indexedDB/IDBObjectStore.cpp | 85 ++++++++++--------------- dom/indexedDB/OpenDatabaseHelper.cpp | 4 +- dom/indexedDB/OpenDatabaseHelper.h | 6 -- dom/indexedDB/ipc/IndexedDBChild.cpp | 18 +++--- dom/indexedDB/ipc/IndexedDBParent.cpp | 32 ++++++++++ dom/indexedDB/ipc/IndexedDBParent.h | 13 ++++ dom/ipc/ContentParent.cpp | 20 ++++-- dom/ipc/TabParent.cpp | 6 ++ 14 files changed, 246 insertions(+), 145 deletions(-) diff --git a/dom/indexedDB/AsyncConnectionHelper.cpp b/dom/indexedDB/AsyncConnectionHelper.cpp index 4fb764b37fe3..5aaf2870f0ce 100644 --- a/dom/indexedDB/AsyncConnectionHelper.cpp +++ b/dom/indexedDB/AsyncConnectionHelper.cpp @@ -513,6 +513,37 @@ AsyncConnectionHelper::ReleaseMainThreadObjects() HelperBase::ReleaseMainThreadObjects(); } +AsyncConnectionHelper::ChildProcessSendResult +AsyncConnectionHelper::MaybeSendResponseToChildProcess(nsresult aResultCode) +{ + NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); + NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!"); + + // If there's no request, there could never have been an actor, and so there + // is nothing to do. + if (!mRequest) { + return Success_NotSent; + } + + IDBTransaction* trans = GetCurrentTransaction(); + // We may not have a transaction, e.g. for deleteDatabase + if (!trans) { + return Success_NotSent; + } + + // Are we shutting down the child? + if (trans->Database()->IsDisconnectedFromActor()) { + return Success_ActorDisconnected; + } + + IndexedDBRequestParentBase* actor = mRequest->GetActorParent(); + if (!actor) { + return Success_NotSent; + } + + return SendResponseToChildProcess(aResultCode); +} + nsresult AsyncConnectionHelper::OnParentProcessRequestComplete( const ResponseValue& aResponseValue) diff --git a/dom/indexedDB/AsyncConnectionHelper.h b/dom/indexedDB/AsyncConnectionHelper.h index 2d66656e77ff..496e9049f733 100644 --- a/dom/indexedDB/AsyncConnectionHelper.h +++ b/dom/indexedDB/AsyncConnectionHelper.h @@ -37,15 +37,6 @@ class HelperBase : public nsIRunnable friend class IDBRequest; public: - enum ChildProcessSendResult - { - Success_Sent = 0, - Success_NotSent, - Error - }; - - virtual ChildProcessSendResult - MaybeSendResponseToChildProcess(nsresult aResultCode) = 0; virtual nsresult GetResultCode() = 0; @@ -131,6 +122,25 @@ public: return mResultCode; } + enum ChildProcessSendResult + { + // The result was successfully sent to the child process + Success_Sent = 0, + + // The result was not sent, because this is not an out-of-process request. + Success_NotSent, + + // The result was not sent, because the actor has been disconnected + // (if the child process has shut down or crashed). + Success_ActorDisconnected, + + // An error occurred. + Error + }; + + ChildProcessSendResult + MaybeSendResponseToChildProcess(nsresult aResultCode); + virtual nsresult OnParentProcessRequestComplete( const ResponseValue& aResponseValue); @@ -207,6 +217,14 @@ protected: */ static void SetCurrentTransaction(IDBTransaction* aTransaction); + /** + * Allows the subclass to send its results to the child process. Will only + * be called if all of the IPC infrastructure is available (there is an + * actor, the child is stil alive and hasn't begun shutting down). + */ + virtual ChildProcessSendResult + SendResponseToChildProcess(nsresult aResultCode) = 0; + protected: nsRefPtr mDatabase; nsRefPtr mTransaction; diff --git a/dom/indexedDB/IDBCursor.cpp b/dom/indexedDB/IDBCursor.cpp index 111bb387093d..406636f8a350 100644 --- a/dom/indexedDB/IDBCursor.cpp +++ b/dom/indexedDB/IDBCursor.cpp @@ -95,7 +95,7 @@ public: PackArgumentsForParentProcess(CursorRequestParams& aParams) MOZ_OVERRIDE; virtual ChildProcessSendResult - MaybeSendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; + SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; virtual nsresult UnpackResponseFromParentProcess(const ResponseValue& aResponseValue) @@ -874,16 +874,14 @@ ContinueHelper::PackArgumentsForParentProcess(CursorRequestParams& aParams) return NS_OK; } -HelperBase::ChildProcessSendResult -ContinueHelper::MaybeSendResponseToChildProcess(nsresult aResultCode) +AsyncConnectionHelper::ChildProcessSendResult +ContinueHelper::SendResponseToChildProcess(nsresult aResultCode) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!"); IndexedDBRequestParentBase* actor = mRequest->GetActorParent(); - if (!actor) { - return Success_NotSent; - } + NS_ASSERTION(actor, "How did we get this far without an actor?"); InfallibleTArray blobsParent; diff --git a/dom/indexedDB/IDBDatabase.cpp b/dom/indexedDB/IDBDatabase.cpp index cadd30e451f8..75fc78e8c27b 100644 --- a/dom/indexedDB/IDBDatabase.cpp +++ b/dom/indexedDB/IDBDatabase.cpp @@ -50,7 +50,7 @@ public: } virtual ChildProcessSendResult - MaybeSendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; + SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; virtual nsresult UnpackResponseFromParentProcess(const ResponseValue& aResponseValue) @@ -117,7 +117,7 @@ public: AsyncConnectionHelper::ReleaseMainThreadObjects(); } - virtual ChildProcessSendResult MaybeSendResponseToChildProcess( + virtual ChildProcessSendResult SendResponseToChildProcess( nsresult aResultCode) MOZ_OVERRIDE { @@ -216,7 +216,8 @@ IDBDatabase::IDBDatabase() mActorChild(nullptr), mActorParent(nullptr), mContentParent(nullptr), - mInvalidated(0), + mInvalidated(false), + mDisconnected(false), mRegistered(false), mClosed(false), mRunningVersionChange(false) @@ -256,6 +257,8 @@ IDBDatabase::Invalidate() return; } + mInvalidated = true; + // Make sure we're closed too. Close(); @@ -266,14 +269,39 @@ IDBDatabase::Invalidate() if (owner) { IndexedDatabaseManager::CancelPromptsForWindow(owner); } - - mInvalidated = true; } bool IDBDatabase::IsInvalidated() { - return !!mInvalidated; + return mInvalidated; +} + +void +IDBDatabase::DisconnectFromActor() +{ + NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); + + if (IsDisconnectedFromActor()) { + return; + } + + mDisconnected = true; + + // Make sure we're closed too. + Close(); + + // Kill any outstanding prompts. + nsPIDOMWindow* owner = GetOwner(); + if (owner) { + IndexedDatabaseManager::CancelPromptsForWindow(owner); + } +} + +bool +IDBDatabase::IsDisconnectedFromActor() +{ + return mDisconnected; } void @@ -797,8 +825,8 @@ IDBDatabase::PostHandleEvent(nsEventChainPostVisitor& aVisitor) return IndexedDatabaseManager::FireWindowOnError(GetOwner(), aVisitor); } -HelperBase::ChildProcessSendResult -NoRequestDatabaseHelper::MaybeSendResponseToChildProcess(nsresult aResultCode) +AsyncConnectionHelper::ChildProcessSendResult +NoRequestDatabaseHelper::SendResponseToChildProcess(nsresult aResultCode) { NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!"); return Success_NotSent; diff --git a/dom/indexedDB/IDBDatabase.h b/dom/indexedDB/IDBDatabase.h index 54fd606f0c18..afc780d41e4f 100644 --- a/dom/indexedDB/IDBDatabase.h +++ b/dom/indexedDB/IDBDatabase.h @@ -106,6 +106,13 @@ public: // transactions for this database will be allowed to run. bool IsInvalidated(); + void DisconnectFromActor(); + + // Whether or not the database has been disconnected from its actor. If true + // it is not safe to send any IPC messages to the actor representing this db + // or any of its subactors. + bool IsDisconnectedFromActor(); + void CloseInternal(bool aIsDead); // Whether or not the database has had Close called on it. @@ -183,7 +190,8 @@ private: mozilla::dom::ContentParent* mContentParent; - int32_t mInvalidated; + bool mInvalidated; + bool mDisconnected; bool mRegistered; bool mClosed; bool mRunningVersionChange; diff --git a/dom/indexedDB/IDBIndex.cpp b/dom/indexedDB/IDBIndex.cpp index 05ad46d115e4..794177639b47 100644 --- a/dom/indexedDB/IDBIndex.cpp +++ b/dom/indexedDB/IDBIndex.cpp @@ -93,7 +93,7 @@ public: PackArgumentsForParentProcess(IndexRequestParams& aParams) MOZ_OVERRIDE; virtual ChildProcessSendResult - MaybeSendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; + SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; virtual nsresult UnpackResponseFromParentProcess(const ResponseValue& aResponseValue) @@ -134,7 +134,7 @@ public: PackArgumentsForParentProcess(IndexRequestParams& aParams) MOZ_OVERRIDE; virtual ChildProcessSendResult - MaybeSendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; + SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; virtual nsresult UnpackResponseFromParentProcess(const ResponseValue& aResponseValue) @@ -165,7 +165,7 @@ public: PackArgumentsForParentProcess(IndexRequestParams& aParams) MOZ_OVERRIDE; virtual ChildProcessSendResult - MaybeSendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; + SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; virtual nsresult UnpackResponseFromParentProcess(const ResponseValue& aResponseValue) @@ -206,7 +206,7 @@ public: PackArgumentsForParentProcess(IndexRequestParams& aParams) MOZ_OVERRIDE; virtual ChildProcessSendResult - MaybeSendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; + SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; virtual nsresult UnpackResponseFromParentProcess(const ResponseValue& aResponseValue) @@ -246,7 +246,7 @@ public: PackArgumentsForParentProcess(IndexRequestParams& aParams) MOZ_OVERRIDE; virtual ChildProcessSendResult - MaybeSendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; + SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; virtual nsresult UnpackResponseFromParentProcess(const ResponseValue& aResponseValue) @@ -295,7 +295,7 @@ public: PackArgumentsForParentProcess(IndexRequestParams& aParams) MOZ_OVERRIDE; virtual ChildProcessSendResult - MaybeSendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; + SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; private: virtual nsresult EnsureCursor(); @@ -328,7 +328,7 @@ public: PackArgumentsForParentProcess(IndexRequestParams& aParams) MOZ_OVERRIDE; virtual ChildProcessSendResult - MaybeSendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; + SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; virtual nsresult UnpackResponseFromParentProcess(const ResponseValue& aResponseValue) @@ -1109,16 +1109,14 @@ GetKeyHelper::PackArgumentsForParentProcess(IndexRequestParams& aParams) return NS_OK; } -HelperBase::ChildProcessSendResult -GetKeyHelper::MaybeSendResponseToChildProcess(nsresult aResultCode) +AsyncConnectionHelper::ChildProcessSendResult +GetKeyHelper::SendResponseToChildProcess(nsresult aResultCode) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!"); IndexedDBRequestParentBase* actor = mRequest->GetActorParent(); - if (!actor) { - return Success_NotSent; - } + NS_ASSERTION(actor, "How did we get this far without an actor?"); ResponseValue response; if (NS_FAILED(aResultCode)) { @@ -1231,16 +1229,14 @@ GetHelper::PackArgumentsForParentProcess(IndexRequestParams& aParams) return NS_OK; } -HelperBase::ChildProcessSendResult -GetHelper::MaybeSendResponseToChildProcess(nsresult aResultCode) +AsyncConnectionHelper::ChildProcessSendResult +GetHelper::SendResponseToChildProcess(nsresult aResultCode) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!"); IndexedDBRequestParentBase* actor = mRequest->GetActorParent(); - if (!actor) { - return Success_NotSent; - } + NS_ASSERTION(actor, "How did we get this far without an actor?"); InfallibleTArray blobsParent; @@ -1433,16 +1429,14 @@ GetAllKeysHelper::PackArgumentsForParentProcess(IndexRequestParams& aParams) return NS_OK; } -HelperBase::ChildProcessSendResult -GetAllKeysHelper::MaybeSendResponseToChildProcess(nsresult aResultCode) +AsyncConnectionHelper::ChildProcessSendResult +GetAllKeysHelper::SendResponseToChildProcess(nsresult aResultCode) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!"); IndexedDBRequestParentBase* actor = mRequest->GetActorParent(); - if (!actor) { - return Success_NotSent; - } + NS_ASSERTION(actor, "How did we get this far without an actor?"); ResponseValue response; if (NS_FAILED(aResultCode)) { @@ -1580,16 +1574,14 @@ GetAllHelper::PackArgumentsForParentProcess(IndexRequestParams& aParams) return NS_OK; } -HelperBase::ChildProcessSendResult -GetAllHelper::MaybeSendResponseToChildProcess(nsresult aResultCode) +AsyncConnectionHelper::ChildProcessSendResult +GetAllHelper::SendResponseToChildProcess(nsresult aResultCode) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!"); IndexedDBRequestParentBase* actor = mRequest->GetActorParent(); - if (!actor) { - return Success_NotSent; - } + NS_ASSERTION(actor, "How did we get this far without an actor?"); GetAllResponse getAllResponse; @@ -1909,18 +1901,15 @@ OpenKeyCursorHelper::PackArgumentsForParentProcess(IndexRequestParams& aParams) return NS_OK; } -HelperBase::ChildProcessSendResult -OpenKeyCursorHelper::MaybeSendResponseToChildProcess(nsresult aResultCode) +AsyncConnectionHelper::ChildProcessSendResult +OpenKeyCursorHelper::SendResponseToChildProcess(nsresult aResultCode) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!"); + NS_ASSERTION(!mCursor, "Shouldn't have this yet!"); IndexedDBRequestParentBase* actor = mRequest->GetActorParent(); - if (!actor) { - return Success_NotSent; - } - - NS_ASSERTION(!mCursor, "Shouldn't have this yet!"); + NS_ASSERTION(actor, "How did we get this far without an actor?"); if (NS_SUCCEEDED(aResultCode)) { nsresult rv = EnsureCursor(); @@ -2245,18 +2234,15 @@ OpenCursorHelper::PackArgumentsForParentProcess(IndexRequestParams& aParams) return NS_OK; } -HelperBase::ChildProcessSendResult -OpenCursorHelper::MaybeSendResponseToChildProcess(nsresult aResultCode) +AsyncConnectionHelper::ChildProcessSendResult +OpenCursorHelper::SendResponseToChildProcess(nsresult aResultCode) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!"); + NS_ASSERTION(!mCursor, "Shouldn't have this yet!"); IndexedDBRequestParentBase* actor = mRequest->GetActorParent(); - if (!actor) { - return Success_NotSent; - } - - NS_ASSERTION(!mCursor, "Shouldn't have this yet!"); + NS_ASSERTION(actor, "How did we get this far without an actor?"); InfallibleTArray blobsParent; @@ -2428,16 +2414,14 @@ CountHelper::PackArgumentsForParentProcess(IndexRequestParams& aParams) return NS_OK; } -HelperBase::ChildProcessSendResult -CountHelper::MaybeSendResponseToChildProcess(nsresult aResultCode) +AsyncConnectionHelper::ChildProcessSendResult +CountHelper::SendResponseToChildProcess(nsresult aResultCode) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!"); IndexedDBRequestParentBase* actor = mRequest->GetActorParent(); - if (!actor) { - return Success_NotSent; - } + NS_ASSERTION(actor, "How did we get this far without an actor?"); ResponseValue response; if (NS_FAILED(aResultCode)) { diff --git a/dom/indexedDB/IDBObjectStore.cpp b/dom/indexedDB/IDBObjectStore.cpp index 147082f90e1f..52ba8277c597 100644 --- a/dom/indexedDB/IDBObjectStore.cpp +++ b/dom/indexedDB/IDBObjectStore.cpp @@ -111,7 +111,7 @@ public: MOZ_OVERRIDE; virtual ChildProcessSendResult - MaybeSendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; + SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; virtual nsresult OnSuccess() MOZ_OVERRIDE; @@ -155,7 +155,7 @@ public: PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE; virtual ChildProcessSendResult - MaybeSendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; + SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; virtual nsresult UnpackResponseFromParentProcess(const ResponseValue& aResponseValue) @@ -199,7 +199,7 @@ public: PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE; virtual ChildProcessSendResult - MaybeSendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; + SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; virtual nsresult UnpackResponseFromParentProcess(const ResponseValue& aResponseValue) @@ -234,7 +234,7 @@ public: PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE; virtual ChildProcessSendResult - MaybeSendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; + SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; virtual nsresult UnpackResponseFromParentProcess(const ResponseValue& aResponseValue) @@ -257,7 +257,7 @@ public: PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE; virtual ChildProcessSendResult - MaybeSendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; + SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; virtual nsresult UnpackResponseFromParentProcess(const ResponseValue& aResponseValue) @@ -293,7 +293,7 @@ public: PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE; virtual ChildProcessSendResult - MaybeSendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; + SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; virtual nsresult UnpackResponseFromParentProcess(const ResponseValue& aResponseValue) @@ -399,7 +399,7 @@ public: PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE; virtual ChildProcessSendResult - MaybeSendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; + SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; virtual nsresult UnpackResponseFromParentProcess(const ResponseValue& aResponseValue) @@ -438,7 +438,7 @@ public: PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE; virtual ChildProcessSendResult - MaybeSendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; + SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; virtual nsresult UnpackResponseFromParentProcess(const ResponseValue& aResponseValue) @@ -2563,9 +2563,8 @@ NoRequestObjectStoreHelper::UnpackResponseFromParentProcess( return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } -HelperBase::ChildProcessSendResult -NoRequestObjectStoreHelper::MaybeSendResponseToChildProcess( - nsresult aResultCode) +AsyncConnectionHelper::ChildProcessSendResult +NoRequestObjectStoreHelper::SendResponseToChildProcess(nsresult aResultCode) { NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!"); return Success_NotSent; @@ -2824,16 +2823,14 @@ AddHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) return NS_OK; } -HelperBase::ChildProcessSendResult -AddHelper::MaybeSendResponseToChildProcess(nsresult aResultCode) +AsyncConnectionHelper::ChildProcessSendResult +AddHelper::SendResponseToChildProcess(nsresult aResultCode) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!"); IndexedDBRequestParentBase* actor = mRequest->GetActorParent(); - if (!actor) { - return Success_NotSent; - } + NS_ASSERTION(actor, "How did we get this far without an actor?"); ResponseValue response; if (NS_FAILED(aResultCode)) { @@ -2943,16 +2940,14 @@ GetHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) return NS_OK; } -HelperBase::ChildProcessSendResult -GetHelper::MaybeSendResponseToChildProcess(nsresult aResultCode) +AsyncConnectionHelper::ChildProcessSendResult +GetHelper::SendResponseToChildProcess(nsresult aResultCode) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!"); IndexedDBRequestParentBase* actor = mRequest->GetActorParent(); - if (!actor) { - return Success_NotSent; - } + NS_ASSERTION(actor, "How did we get this far without an actor?"); InfallibleTArray blobsParent; @@ -2973,7 +2968,7 @@ GetHelper::MaybeSendResponseToChildProcess(nsresult aResultCode) blobsParent); if (NS_FAILED(aResultCode)) { NS_WARNING("ConvertBlobsToActors failed!"); - } + } } ResponseValue response; @@ -3070,16 +3065,14 @@ DeleteHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) return NS_OK; } -HelperBase::ChildProcessSendResult -DeleteHelper::MaybeSendResponseToChildProcess(nsresult aResultCode) +AsyncConnectionHelper::ChildProcessSendResult +DeleteHelper::SendResponseToChildProcess(nsresult aResultCode) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!"); IndexedDBRequestParentBase* actor = mRequest->GetActorParent(); - if (!actor) { - return Success_NotSent; - } + NS_ASSERTION(actor, "How did we get this far without an actor?"); ResponseValue response; if (NS_FAILED(aResultCode)) { @@ -3136,16 +3129,14 @@ ClearHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) return NS_OK; } -HelperBase::ChildProcessSendResult -ClearHelper::MaybeSendResponseToChildProcess(nsresult aResultCode) +AsyncConnectionHelper::ChildProcessSendResult +ClearHelper::SendResponseToChildProcess(nsresult aResultCode) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!"); IndexedDBRequestParentBase* actor = mRequest->GetActorParent(); - if (!actor) { - return Success_NotSent; - } + NS_ASSERTION(actor, "How did we get this far without an actor?"); ResponseValue response; if (NS_FAILED(aResultCode)) { @@ -3371,18 +3362,15 @@ OpenCursorHelper::PackArgumentsForParentProcess( return NS_OK; } -HelperBase::ChildProcessSendResult -OpenCursorHelper::MaybeSendResponseToChildProcess(nsresult aResultCode) +AsyncConnectionHelper::ChildProcessSendResult +OpenCursorHelper::SendResponseToChildProcess(nsresult aResultCode) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!"); + NS_ASSERTION(!mCursor, "Shouldn't have this yet!"); IndexedDBRequestParentBase* actor = mRequest->GetActorParent(); - if (!actor) { - return Success_NotSent; - } - - NS_ASSERTION(!mCursor, "Shouldn't have this yet!"); + NS_ASSERTION(actor, "How did we get this far without an actor?"); InfallibleTArray blobsParent; @@ -3814,19 +3802,16 @@ GetAllHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) return NS_OK; } -HelperBase::ChildProcessSendResult -GetAllHelper::MaybeSendResponseToChildProcess(nsresult aResultCode) +AsyncConnectionHelper::ChildProcessSendResult +GetAllHelper::SendResponseToChildProcess(nsresult aResultCode) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!"); IndexedDBRequestParentBase* actor = mRequest->GetActorParent(); - if (!actor) { - return Success_NotSent; - } - - GetAllResponse getAllResponse; + NS_ASSERTION(actor, "How did we get this far without an actor?"); + GetAllResponse getAllResponse; if (NS_SUCCEEDED(aResultCode) && !mCloneReadInfos.IsEmpty()) { IDBDatabase* database = mObjectStore->Transaction()->Database(); NS_ASSERTION(database, "This should never be null!"); @@ -4011,16 +3996,14 @@ CountHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) return NS_OK; } -HelperBase::ChildProcessSendResult -CountHelper::MaybeSendResponseToChildProcess(nsresult aResultCode) +AsyncConnectionHelper::ChildProcessSendResult +CountHelper::SendResponseToChildProcess(nsresult aResultCode) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!"); IndexedDBRequestParentBase* actor = mRequest->GetActorParent(); - if (!actor) { - return Success_NotSent; - } + NS_ASSERTION(actor, "How did we get this far without an actor?"); ResponseValue response; if (NS_FAILED(aResultCode)) { diff --git a/dom/indexedDB/OpenDatabaseHelper.cpp b/dom/indexedDB/OpenDatabaseHelper.cpp index fcbe754e7283..8f5521819d2b 100644 --- a/dom/indexedDB/OpenDatabaseHelper.cpp +++ b/dom/indexedDB/OpenDatabaseHelper.cpp @@ -1361,7 +1361,7 @@ protected: MOZ_OVERRIDE; virtual ChildProcessSendResult - MaybeSendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE + SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE { return Success_NotSent; } @@ -1435,7 +1435,7 @@ protected: } virtual ChildProcessSendResult - MaybeSendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE + SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE { return Success_NotSent; } diff --git a/dom/indexedDB/OpenDatabaseHelper.h b/dom/indexedDB/OpenDatabaseHelper.h index fa1ba0b5b310..587301b9eaf5 100644 --- a/dom/indexedDB/OpenDatabaseHelper.h +++ b/dom/indexedDB/OpenDatabaseHelper.h @@ -57,12 +57,6 @@ public: mResultCode = rv; } - virtual ChildProcessSendResult - MaybeSendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE - { - return Success_NotSent; - } - virtual nsresult GetResultCode() MOZ_OVERRIDE { return mResultCode; diff --git a/dom/indexedDB/ipc/IndexedDBChild.cpp b/dom/indexedDB/ipc/IndexedDBChild.cpp index 6cfec468b3a1..34d6dcde60b4 100644 --- a/dom/indexedDB/ipc/IndexedDBChild.cpp +++ b/dom/indexedDB/ipc/IndexedDBChild.cpp @@ -41,7 +41,7 @@ public: MOZ_OVERRIDE; virtual ChildProcessSendResult - MaybeSendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; + SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; virtual nsresult GetSuccessResult(JSContext* aCx, jsval* aVal) MOZ_OVERRIDE; @@ -86,7 +86,7 @@ public: MOZ_OVERRIDE; virtual ChildProcessSendResult - MaybeSendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; + SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; virtual nsresult DoDatabaseWork(mozIStorageConnection* aConnection) MOZ_OVERRIDE; @@ -110,7 +110,7 @@ public: MOZ_OVERRIDE; virtual ChildProcessSendResult - MaybeSendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; + SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; virtual nsresult GetSuccessResult(JSContext* aCx, jsval* aVal) MOZ_OVERRIDE; @@ -1147,8 +1147,8 @@ IPCOpenDatabaseHelper::UnpackResponseFromParentProcess( return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } -HelperBase::ChildProcessSendResult -IPCOpenDatabaseHelper::MaybeSendResponseToChildProcess(nsresult aResultCode) +AsyncConnectionHelper::ChildProcessSendResult +IPCOpenDatabaseHelper::SendResponseToChildProcess(nsresult aResultCode) { MOZ_NOT_REACHED("Don't call me!"); return Error; @@ -1176,8 +1176,8 @@ IPCSetVersionHelper::UnpackResponseFromParentProcess( return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } -HelperBase::ChildProcessSendResult -IPCSetVersionHelper::MaybeSendResponseToChildProcess(nsresult aResultCode) +AsyncConnectionHelper::ChildProcessSendResult +IPCSetVersionHelper::SendResponseToChildProcess(nsresult aResultCode) { MOZ_NOT_REACHED("Don't call me!"); return Error; @@ -1214,8 +1214,8 @@ IPCDeleteDatabaseHelper::UnpackResponseFromParentProcess( return NS_ERROR_FAILURE; } -HelperBase::ChildProcessSendResult -IPCDeleteDatabaseHelper::MaybeSendResponseToChildProcess(nsresult aResultCode) +AsyncConnectionHelper::ChildProcessSendResult +IPCDeleteDatabaseHelper::SendResponseToChildProcess(nsresult aResultCode) { MOZ_NOT_REACHED("Don't call me!"); return Error; diff --git a/dom/indexedDB/ipc/IndexedDBParent.cpp b/dom/indexedDB/ipc/IndexedDBParent.cpp index 38669ec40e3b..7594d702709d 100644 --- a/dom/indexedDB/ipc/IndexedDBParent.cpp +++ b/dom/indexedDB/ipc/IndexedDBParent.cpp @@ -52,6 +52,7 @@ AutoSetCurrentTransaction::~AutoSetCurrentTransaction() ******************************************************************************/ IndexedDBParent::IndexedDBParent() + : mDisconnected(false) { MOZ_COUNT_CTOR(IndexedDBParent); } @@ -61,6 +62,19 @@ IndexedDBParent::~IndexedDBParent() MOZ_COUNT_DTOR(IndexedDBParent); } +void +IndexedDBParent::Disconnect() +{ + mDisconnected = true; + + const InfallibleTArray& dbs = + ManagedPIndexedDBDatabaseParent(); + + for (uint32_t i = 0; i < dbs.Length(); ++i) { + static_cast(dbs[i])->Disconnect(); + } +} + void IndexedDBParent::ActorDestroy(ActorDestroyReason aWhy) { @@ -184,6 +198,11 @@ IndexedDBDatabaseParent::HandleEvent(nsIDOMEvent* aEvent) { MOZ_ASSERT(aEvent); + if (Manager() && + static_cast(Manager())->IsDisconnected()) { + return NS_OK; + } + nsString type; nsresult rv = aEvent->GetType(type); NS_ENSURE_SUCCESS(rv, rv); @@ -214,6 +233,14 @@ IndexedDBDatabaseParent::HandleEvent(nsIDOMEvent* aEvent) return NS_ERROR_UNEXPECTED; } +void +IndexedDBDatabaseParent::Disconnect() +{ + if (mDatabase) { + mDatabase->DisconnectFromActor(); + } +} + nsresult IndexedDBDatabaseParent::HandleRequestEvent(nsIDOMEvent* aEvent, const nsAString& aType) @@ -1779,6 +1806,11 @@ IndexedDBDeleteDatabaseRequestParent::~IndexedDBDeleteDatabaseRequestParent() nsresult IndexedDBDeleteDatabaseRequestParent::HandleEvent(nsIDOMEvent* aEvent) { + if (Manager() && + static_cast(Manager())->IsDisconnected()) { + return NS_OK; + } + MOZ_ASSERT(aEvent); nsString type; diff --git a/dom/indexedDB/ipc/IndexedDBParent.h b/dom/indexedDB/ipc/IndexedDBParent.h index 725b10686d7e..8d7740002e5e 100644 --- a/dom/indexedDB/ipc/IndexedDBParent.h +++ b/dom/indexedDB/ipc/IndexedDBParent.h @@ -137,6 +137,7 @@ class IndexedDBParent : public PIndexedDBParent nsRefPtr mFactory; nsCString mASCIIOrigin; + bool mDisconnected; public: IndexedDBParent(); @@ -148,6 +149,15 @@ public: return mASCIIOrigin; } + void + Disconnect(); + + bool + IsDisconnected() const + { + return mDisconnected; + } + protected: virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE; @@ -199,6 +209,9 @@ public: nsresult HandleEvent(nsIDOMEvent* aEvent); + void + Disconnect(); + protected: nsresult HandleRequestEvent(nsIDOMEvent* aEvent, const nsAString& aType); diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index da9989ef6dad..62ba42bb799b 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -462,14 +462,20 @@ ContentParent::SetManifestFromPreallocated(const nsAString& aAppManifestURL) void ContentParent::ShutDownProcess() { - if (mIsAlive) { - // Close() can only be called once. It kicks off the - // destruction sequence. - Close(); + if (mIsAlive) { + const InfallibleTArray& idbParents = + ManagedPIndexedDBParent(); + for (uint32_t i = 0; i < idbParents.Length(); ++i) { + static_cast(idbParents[i])->Disconnect(); } - // NB: must MarkAsDead() here so that this isn't accidentally - // returned from Get*() while in the midst of shutdown. - MarkAsDead(); + + // Close() can only be called once. It kicks off the + // destruction sequence. + Close(); + } + // NB: must MarkAsDead() here so that this isn't accidentally + // returned from Get*() while in the midst of shutdown. + MarkAsDead(); } void diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index 13a05addbe64..bac0328560cc 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -109,6 +109,12 @@ TabParent::Destroy() // destroy itself and send back __delete__(). unused << SendDestroy(); + const InfallibleTArray& idbParents = + ManagedPIndexedDBParent(); + for (uint32_t i = 0; i < idbParents.Length(); ++i) { + static_cast(idbParents[i])->Disconnect(); + } + if (RenderFrameParent* frame = GetRenderFrame()) { frame->Destroy(); }