Bug 808743 - ' Better protection for PBrowser shutdown and database invalidation in multiprocess scenarios'. r=khuey+cjones.

--HG--
extra : transplant_source : %BD%E4%ADA%09%CE%D9%BE%1C%7C%7B%1A%FC%86%5C%13%24%29%B4%16
This commit is contained in:
Ben Turner 2012-11-09 19:29:07 -08:00
parent 8f18022d36
commit 27072c3f92
20 changed files with 794 additions and 267 deletions

View File

@ -21,6 +21,7 @@
#include "TransactionThreadPool.h"
#include "ipc/IndexedDBChild.h"
#include "ipc/IndexedDBParent.h"
USING_INDEXEDDB_NAMESPACE
@ -203,36 +204,47 @@ AsyncConnectionHelper::Run()
MaybeSendResponseToChildProcess(mResultCode) :
Success_NotSent;
NS_ASSERTION(sendResult == Success_Sent || sendResult == Success_NotSent ||
sendResult == Error,
"Unknown result from MaybeSendResultsToChildProcess!");
if (sendResult == Success_Sent) {
if (mRequest) {
mRequest->NotifyHelperSentResultsToChildProcess(NS_OK);
}
}
else if (sendResult == Error) {
NS_WARNING("MaybeSendResultsToChildProcess failed!");
mResultCode = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
if (mRequest) {
mRequest->NotifyHelperSentResultsToChildProcess(mResultCode);
}
}
else if (sendResult == Success_NotSent) {
if (mRequest) {
nsresult rv = mRequest->NotifyHelperCompleted(this);
if (NS_SUCCEEDED(mResultCode) && NS_FAILED(rv)) {
mResultCode = rv;
switch (sendResult) {
case Success_Sent: {
if (mRequest) {
mRequest->NotifyHelperSentResultsToChildProcess(NS_OK);
}
break;
}
// Call OnError if the database had an error or if the OnSuccess handler
// has an error.
if (NS_FAILED(mResultCode) ||
NS_FAILED((mResultCode = OnSuccess()))) {
OnError();
case Success_NotSent: {
if (mRequest) {
nsresult rv = mRequest->NotifyHelperCompleted(this);
if (NS_SUCCEEDED(mResultCode) && NS_FAILED(rv)) {
mResultCode = rv;
}
}
// Call OnError if the database had an error or if the OnSuccess
// handler has an error.
if (NS_FAILED(mResultCode) ||
NS_FAILED((mResultCode = OnSuccess()))) {
OnError();
}
break;
}
case Success_ActorDisconnected: {
// Nothing needs to be done here.
break;
}
case Error: {
NS_WARNING("MaybeSendResultsToChildProcess failed!");
mResultCode = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
if (mRequest) {
mRequest->NotifyHelperSentResultsToChildProcess(mResultCode);
}
break;
}
default:
MOZ_NOT_REACHED("Unknown value for ChildProcessSendResult!");
}
NS_ASSERTION(gCurrentTransaction == mTransaction, "Should be unchanged!");
@ -532,7 +544,8 @@ AsyncConnectionHelper::MaybeSendResponseToChildProcess(nsresult aResultCode)
}
// Are we shutting down the child?
if (trans->Database()->IsDisconnectedFromActor()) {
IndexedDBDatabaseParent* dbActor = trans->Database()->GetActorParent();
if (dbActor && dbActor->IsDisconnected()) {
return Success_ActorDisconnected;
}

View File

@ -107,12 +107,17 @@ public:
static IDBTransaction* GetCurrentTransaction();
bool HasTransaction()
bool HasTransaction() const
{
return !!mTransaction;
}
IDBTransaction* GetTransaction() const
{
return mTransaction;
}
nsISupports* GetSource()
nsISupports* GetSource() const
{
return mRequest ? mRequest->Source() : nullptr;
}

View File

@ -768,6 +768,12 @@ CursorHelper::Dispatch(nsIEventTarget* aDatabaseThread)
return AsyncConnectionHelper::Dispatch(aDatabaseThread);
}
// If we've been invalidated then there's no point sending anything to the
// parent process.
if (mCursor->Transaction()->Database()->IsInvalidated()) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
IndexedDBCursorChild* cursorActor = mCursor->GetActorChild();
NS_ASSERTION(cursorActor, "Must have an actor here!");
@ -918,7 +924,7 @@ ContinueHelper::SendResponseToChildProcess(nsresult aResultCode)
response = continueResponse;
}
if (!actor->Send__delete__(actor, response)) {
if (!actor->SendResponse(response)) {
return Error;
}

View File

@ -137,6 +137,12 @@ public:
return mActorChild;
}
IndexedDBCursorParent*
GetActorParent() const
{
return mActorParent;
}
nsresult
ContinueInternal(const Key& aKey,
int32_t aCount);

View File

@ -10,7 +10,6 @@
#include "mozilla/Mutex.h"
#include "mozilla/storage.h"
#include "mozilla/unused.h"
#include "mozilla/dom/ContentParent.h"
#include "nsDOMClassInfo.h"
#include "nsDOMLists.h"
@ -219,7 +218,6 @@ IDBDatabase::IDBDatabase()
mActorParent(nullptr),
mContentParent(nullptr),
mInvalidated(false),
mDisconnected(false),
mRegistered(false),
mClosed(false),
mRunningVersionChange(false)
@ -277,21 +275,16 @@ IDBDatabase::Invalidate()
// And let the child process know as well.
if (mActorParent) {
NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
mozilla::unused << mActorParent->SendInvalidate();
mActorParent->Invalidate();
}
}
void
IDBDatabase::DisconnectFromActor()
IDBDatabase::DisconnectFromActorParent()
{
NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
if (IsDisconnectedFromActor()) {
return;
}
mDisconnected = true;
// Make sure we're closed too.
Close();
@ -302,13 +295,6 @@ IDBDatabase::DisconnectFromActor()
}
}
bool
IDBDatabase::IsDisconnectedFromActor() const
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
return mDisconnected;
}
void
IDBDatabase::CloseInternal(bool aIsDead)
{

View File

@ -110,12 +110,7 @@ public:
return mInvalidated;
}
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() const;
void DisconnectFromActorParent();
void CloseInternal(bool aIsDead);
@ -155,6 +150,12 @@ public:
return mActorChild;
}
IndexedDBDatabaseParent*
GetActorParent() const
{
return mActorParent;
}
mozilla::dom::ContentParent*
GetContentParent() const
{
@ -195,7 +196,6 @@ private:
mozilla::dom::ContentParent* mContentParent;
bool mInvalidated;
bool mDisconnected;
bool mRegistered;
bool mClosed;
bool mRunningVersionChange;

View File

@ -1017,6 +1017,12 @@ IndexHelper::Dispatch(nsIEventTarget* aDatabaseThread)
return AsyncConnectionHelper::Dispatch(aDatabaseThread);
}
// If we've been invalidated then there's no point sending anything to the
// parent process.
if (mIndex->ObjectStore()->Transaction()->Database()->IsInvalidated()) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
IndexedDBIndexChild* indexActor = mIndex->GetActorChild();
NS_ASSERTION(indexActor, "Must have an actor here!");
@ -1128,7 +1134,7 @@ GetKeyHelper::SendResponseToChildProcess(nsresult aResultCode)
response = getKeyResponse;
}
if (!actor->Send__delete__(actor, response)) {
if (!actor->SendResponse(response)) {
return Error;
}
@ -1271,7 +1277,7 @@ GetHelper::SendResponseToChildProcess(nsresult aResultCode)
response = getResponse;
}
if (!actor->Send__delete__(actor, response)) {
if (!actor->SendResponse(response)) {
return Error;
}
@ -1448,7 +1454,7 @@ GetAllKeysHelper::SendResponseToChildProcess(nsresult aResultCode)
response = getAllKeysResponse;
}
if (!actor->Send__delete__(actor, response)) {
if (!actor->SendResponse(response)) {
return Error;
}
@ -1638,7 +1644,7 @@ GetAllHelper::SendResponseToChildProcess(nsresult aResultCode)
response = getAllResponse;
}
if (!actor->Send__delete__(actor, response)) {
if (!actor->SendResponse(response)) {
return Error;
}
@ -1943,19 +1949,15 @@ OpenKeyCursorHelper::SendResponseToChildProcess(nsresult aResultCode)
params.objectKey() = mObjectKey;
params.optionalCloneInfo() = mozilla::void_t();
IndexedDBCursorParent* cursorActor = new IndexedDBCursorParent(mCursor);
if (!indexActor->SendPIndexedDBCursorConstructor(cursorActor, params)) {
if (!indexActor->OpenCursor(mCursor, params, openCursorResponse)) {
return Error;
}
openCursorResponse = cursorActor;
}
response = openCursorResponse;
}
if (!actor->Send__delete__(actor, response)) {
if (!actor->SendResponse(response)) {
return Error;
}
@ -2303,19 +2305,15 @@ OpenCursorHelper::SendResponseToChildProcess(nsresult aResultCode)
params.optionalCloneInfo() = mSerializedCloneReadInfo;
params.blobsParent().SwapElements(blobsParent);
IndexedDBCursorParent* cursorActor = new IndexedDBCursorParent(mCursor);
if (!indexActor->SendPIndexedDBCursorConstructor(cursorActor, params)) {
if (!indexActor->OpenCursor(mCursor, params, openCursorResponse)) {
return Error;
}
openCursorResponse = cursorActor;
}
response = openCursorResponse;
}
if (!actor->Send__delete__(actor, response)) {
if (!actor->SendResponse(response)) {
return Error;
}
@ -2432,7 +2430,7 @@ CountHelper::SendResponseToChildProcess(nsresult aResultCode)
response = countResponse;
}
if (!actor->Send__delete__(actor, response)) {
if (!actor->SendResponse(response)) {
return Error;
}

View File

@ -2560,6 +2560,12 @@ ObjectStoreHelper::Dispatch(nsIEventTarget* aDatabaseThread)
return AsyncConnectionHelper::Dispatch(aDatabaseThread);
}
// If we've been invalidated then there's no point sending anything to the
// parent process.
if (mObjectStore->Transaction()->Database()->IsInvalidated()) {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
IndexedDBObjectStoreChild* objectStoreActor = mObjectStore->GetActorChild();
NS_ASSERTION(objectStoreActor, "Must have an actor here!");
@ -2878,7 +2884,7 @@ AddHelper::SendResponseToChildProcess(nsresult aResultCode)
response = addResponse;
}
if (!actor->Send__delete__(actor, response)) {
if (!actor->SendResponse(response)) {
return Error;
}
@ -3013,7 +3019,7 @@ GetHelper::SendResponseToChildProcess(nsresult aResultCode)
response = getResponse;
}
if (!actor->Send__delete__(actor, response)) {
if (!actor->SendResponse(response)) {
return Error;
}
@ -3113,7 +3119,7 @@ DeleteHelper::SendResponseToChildProcess(nsresult aResultCode)
response = DeleteResponse();
}
if (!actor->Send__delete__(actor, response)) {
if (!actor->SendResponse(response)) {
return Error;
}
@ -3177,7 +3183,7 @@ ClearHelper::SendResponseToChildProcess(nsresult aResultCode)
response = ClearResponse();
}
if (!actor->Send__delete__(actor, response)) {
if (!actor->SendResponse(response)) {
return Error;
}
@ -3462,20 +3468,15 @@ OpenCursorHelper::SendResponseToChildProcess(nsresult aResultCode)
params.cloneInfo() = mSerializedCloneReadInfo;
params.blobsParent().SwapElements(blobsParent);
IndexedDBCursorParent* cursorActor = new IndexedDBCursorParent(mCursor);
if (!objectStoreActor->SendPIndexedDBCursorConstructor(cursorActor,
params)) {
if (!objectStoreActor->OpenCursor(mCursor, params, openCursorResponse)) {
return Error;
}
openCursorResponse = cursorActor;
}
response = openCursorResponse;
}
if (!actor->Send__delete__(actor, response)) {
if (!actor->SendResponse(response)) {
return Error;
}
@ -3893,7 +3894,7 @@ GetAllHelper::SendResponseToChildProcess(nsresult aResultCode)
response = getAllResponse;
}
if (!actor->Send__delete__(actor, response)) {
if (!actor->SendResponse(response)) {
return Error;
}
@ -4045,7 +4046,7 @@ CountHelper::SendResponseToChildProcess(nsresult aResultCode)
response = countResponse;
}
if (!actor->Send__delete__(actor, response)) {
if (!actor->SendResponse(response)) {
return Error;
}

View File

@ -232,11 +232,11 @@ IDBRequest::GetReadyState(nsAString& aReadyState)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
if (mHaveResultOrErrorCode) {
aReadyState.AssignLiteral("done");
if (IsPending()) {
aReadyState.AssignLiteral("pending");
}
else {
aReadyState.AssignLiteral("pending");
aReadyState.AssignLiteral("done");
}
return NS_OK;

View File

@ -84,6 +84,11 @@ public:
void FillScriptErrorEvent(nsScriptErrorEvent* aEvent) const;
bool IsPending() const
{
return !mHaveResultOrErrorCode;
}
protected:
IDBRequest();
~IDBRequest();

View File

@ -219,6 +219,14 @@ IDBTransaction::OnRequestFinished()
}
}
void
IDBTransaction::OnRequestDisconnected()
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(mPendingRequests, "Mismatched calls!");
--mPendingRequests;
}
void
IDBTransaction::RemoveObjectStore(const nsAString& aName)
{

View File

@ -101,6 +101,7 @@ public:
void OnNewRequest();
void OnRequestFinished();
void OnRequestDisconnected();
void RemoveObjectStore(const nsAString& aName);
@ -188,6 +189,12 @@ public:
return mActorChild;
}
IndexedDBTransactionParent*
GetActorParent() const
{
return mActorParent;
}
nsresult
ObjectStoreInternal(const nsAString& aName,
IDBObjectStore** _retval);

View File

@ -1769,10 +1769,8 @@ OriginClearRunnable::DeleteFiles(IndexedDatabaseManager* aManager)
NS_ENSURE_SUCCESS_VOID(rv);
nsCOMPtr<nsISimpleEnumerator> entries;
rv = directory->GetDirectoryEntries(getter_AddRefs(entries));
NS_ENSURE_SUCCESS_VOID(rv);
if (!entries) {
if (NS_FAILED(directory->GetDirectoryEntries(getter_AddRefs(entries))) ||
!entries) {
return;
}

View File

@ -159,6 +159,9 @@ public:
IndexedDBChild::IndexedDBChild(const nsCString& aASCIIOrigin)
: mFactory(nullptr), mASCIIOrigin(aASCIIOrigin)
#ifdef DEBUG
, mDisconnected(false)
#endif
{
MOZ_COUNT_CTOR(IndexedDBChild);
}
@ -179,6 +182,21 @@ IndexedDBChild::SetFactory(IDBFactory* aFactory)
mFactory = aFactory;
}
void
IndexedDBChild::Disconnect()
{
#ifdef DEBUG
MOZ_ASSERT(!mDisconnected);
mDisconnected = true;
#endif
const InfallibleTArray<PIndexedDBDatabaseChild*>& databases =
ManagedPIndexedDBDatabaseChild();
for (uint32_t i = 0; i < databases.Length(); ++i) {
static_cast<IndexedDBDatabaseChild*>(databases[i])->Disconnect();
}
}
void
IndexedDBChild::ActorDestroy(ActorDestroyReason aWhy)
{
@ -246,6 +264,16 @@ IndexedDBDatabaseChild::SetRequest(IDBOpenDBRequest* aRequest)
mRequest = aRequest;
}
void
IndexedDBDatabaseChild::Disconnect()
{
const InfallibleTArray<PIndexedDBTransactionChild*>& transactions =
ManagedPIndexedDBTransactionChild();
for (uint32_t i = 0; i < transactions.Length(); ++i) {
static_cast<IndexedDBTransactionChild*>(transactions[i])->Disconnect();
}
}
bool
IndexedDBDatabaseChild::EnsureDatabase(
IDBOpenDBRequest* aRequest,
@ -552,6 +580,16 @@ IndexedDBTransactionChild::SetTransaction(IDBTransaction* aTransaction)
mStrongTransaction = aTransaction;
}
void
IndexedDBTransactionChild::Disconnect()
{
const InfallibleTArray<PIndexedDBObjectStoreChild*>& objectStores =
ManagedPIndexedDBObjectStoreChild();
for (uint32_t i = 0; i < objectStores.Length(); ++i) {
static_cast<IndexedDBObjectStoreChild*>(objectStores[i])->Disconnect();
}
}
void
IndexedDBTransactionChild::FireCompleteEvent(nsresult aRv)
{
@ -654,6 +692,28 @@ IndexedDBObjectStoreChild::~IndexedDBObjectStoreChild()
MOZ_ASSERT(!mObjectStore);
}
void
IndexedDBObjectStoreChild::Disconnect()
{
const InfallibleTArray<PIndexedDBRequestChild*>& requests =
ManagedPIndexedDBRequestChild();
for (uint32_t i = 0; i < requests.Length(); ++i) {
static_cast<IndexedDBRequestChildBase*>(requests[i])->Disconnect();
}
const InfallibleTArray<PIndexedDBIndexChild*>& indexes =
ManagedPIndexedDBIndexChild();
for (uint32_t i = 0; i < indexes.Length(); ++i) {
static_cast<IndexedDBIndexChild*>(indexes[i])->Disconnect();
}
const InfallibleTArray<PIndexedDBCursorChild*>& cursors =
ManagedPIndexedDBCursorChild();
for (uint32_t i = 0; i < cursors.Length(); ++i) {
static_cast<IndexedDBCursorChild*>(cursors[i])->Disconnect();
}
}
void
IndexedDBObjectStoreChild::ActorDestroy(ActorDestroyReason aWhy)
{
@ -760,6 +820,22 @@ IndexedDBIndexChild::~IndexedDBIndexChild()
MOZ_ASSERT(!mIndex);
}
void
IndexedDBIndexChild::Disconnect()
{
const InfallibleTArray<PIndexedDBRequestChild*>& requests =
ManagedPIndexedDBRequestChild();
for (uint32_t i = 0; i < requests.Length(); ++i) {
static_cast<IndexedDBRequestChildBase*>(requests[i])->Disconnect();
}
const InfallibleTArray<PIndexedDBCursorChild*>& cursors =
ManagedPIndexedDBCursorChild();
for (uint32_t i = 0; i < cursors.Length(); ++i) {
static_cast<IndexedDBCursorChild*>(cursors[i])->Disconnect();
}
}
void
IndexedDBIndexChild::ActorDestroy(ActorDestroyReason aWhy)
{
@ -882,6 +958,16 @@ IndexedDBCursorChild::SetCursor(IDBCursor* aCursor)
mStrongCursor = aCursor;
}
void
IndexedDBCursorChild::Disconnect()
{
const InfallibleTArray<PIndexedDBRequestChild*>& requests =
ManagedPIndexedDBRequestChild();
for (uint32_t i = 0; i < requests.Length(); ++i) {
static_cast<IndexedDBRequestChildBase*>(requests[i])->Disconnect();
}
}
void
IndexedDBCursorChild::ActorDestroy(ActorDestroyReason aWhy)
{
@ -926,7 +1012,24 @@ IndexedDBRequestChildBase::~IndexedDBRequestChildBase()
IDBRequest*
IndexedDBRequestChildBase::GetRequest() const
{
return mHelper ? mHelper->GetRequest() : NULL;
return mHelper ? mHelper->GetRequest() : nullptr;
}
void
IndexedDBRequestChildBase::Disconnect()
{
if (mHelper) {
IDBRequest* request = mHelper->GetRequest();
if (request->IsPending()) {
request->SetError(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
IDBTransaction* transaction = mHelper->GetTransaction();
if (transaction) {
transaction->OnRequestDisconnected();
}
}
}
}
bool

View File

@ -39,6 +39,10 @@ class IndexedDBChild : public PIndexedDBChild
IDBFactory* mFactory;
nsCString mASCIIOrigin;
#ifdef DEBUG
bool mDisconnected;
#endif
public:
IndexedDBChild(const nsCString& aASCIIOrigin);
virtual ~IndexedDBChild();
@ -52,6 +56,9 @@ public:
void
SetFactory(IDBFactory* aFactory);
void
Disconnect();
protected:
virtual void
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
@ -95,6 +102,9 @@ public:
void
SetRequest(IDBOpenDBRequest* aRequest);
void
Disconnect();
protected:
bool
EnsureDatabase(IDBOpenDBRequest* aRequest,
@ -158,6 +168,9 @@ public:
return mTransaction;
}
void
Disconnect();
protected:
void
FireCompleteEvent(nsresult aRv);
@ -188,6 +201,9 @@ public:
IndexedDBObjectStoreChild(IDBObjectStore* aObjectStore);
virtual ~IndexedDBObjectStoreChild();
void
Disconnect();
protected:
virtual void
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
@ -230,6 +246,9 @@ public:
IndexedDBIndexChild(IDBIndex* aIndex);
virtual ~IndexedDBIndexChild();
void
Disconnect();
protected:
virtual void
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
@ -276,6 +295,9 @@ public:
return mStrongCursor.forget();
}
void
Disconnect();
protected:
virtual void
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
@ -300,6 +322,9 @@ public:
IDBRequest*
GetRequest() const;
void
Disconnect();
protected:
IndexedDBRequestChildBase(AsyncConnectionHelper* aHelper);
virtual ~IndexedDBRequestChildBase();

View File

@ -14,6 +14,7 @@
#include "mozilla/AppProcessPermissions.h"
#include "mozilla/Assertions.h"
#include "mozilla/unused.h"
#include "mozilla/Util.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/TabParent.h"
@ -82,13 +83,14 @@ IndexedDBParent::~IndexedDBParent()
void
IndexedDBParent::Disconnect()
{
MOZ_ASSERT(!mDisconnected);
mDisconnected = true;
const InfallibleTArray<PIndexedDBDatabaseParent*>& dbs =
const InfallibleTArray<PIndexedDBDatabaseParent*>& databases =
ManagedPIndexedDBDatabaseParent();
for (uint32_t i = 0; i < dbs.Length(); ++i) {
static_cast<IndexedDBDatabaseParent*>(dbs[i])->Disconnect();
for (uint32_t i = 0; i < databases.Length(); ++i) {
static_cast<IndexedDBDatabaseParent*>(databases[i])->Disconnect();
}
}
@ -145,12 +147,19 @@ IndexedDBParent::RecvPIndexedDBDatabaseConstructor(
const nsString& aName,
const uint64_t& aVersion)
{
MOZ_ASSERT(mFactory);
if (!CheckReadPermission(aName)) {
return false;
}
if (IsDisconnected()) {
// We're shutting down, ignore this request.
return true;
}
if (!mFactory) {
return true;
}
nsRefPtr<IDBOpenDBRequest> request;
nsresult rv =
mFactory->OpenCommon(aName, aVersion, false, nullptr,
@ -171,12 +180,19 @@ IndexedDBParent::RecvPIndexedDBDeleteDatabaseRequestConstructor(
PIndexedDBDeleteDatabaseRequestParent* aActor,
const nsString& aName)
{
MOZ_ASSERT(mFactory);
if (!CheckWritePermission(aName)) {
return false;
}
if (IsDisconnected()) {
// We're shutting down, ignore this request.
return true;
}
if (!mFactory) {
return true;
}
IndexedDBDeleteDatabaseRequestParent* actor =
static_cast<IndexedDBDeleteDatabaseRequestParent*>(aActor);
@ -196,11 +212,6 @@ PIndexedDBDatabaseParent*
IndexedDBParent::AllocPIndexedDBDatabase(const nsString& aName,
const uint64_t& aVersion)
{
if (!mFactory) {
// This can happen if the child process dies before we set the factory.
return nullptr;
}
return new IndexedDBDatabaseParent();
}
@ -214,11 +225,6 @@ IndexedDBParent::DeallocPIndexedDBDatabase(PIndexedDBDatabaseParent* aActor)
PIndexedDBDeleteDatabaseRequestParent*
IndexedDBParent::AllocPIndexedDBDeleteDatabaseRequest(const nsString& aName)
{
if (!mFactory) {
// This can happen if the child process dies before we set the factory.
return nullptr;
}
return new IndexedDBDeleteDatabaseRequestParent(mFactory);
}
@ -278,8 +284,8 @@ IndexedDBDatabaseParent::HandleEvent(nsIDOMEvent* aEvent)
{
MOZ_ASSERT(aEvent);
if (Manager() &&
static_cast<IndexedDBParent*>(Manager())->IsDisconnected()) {
if (IsDisconnected()) {
// We're shutting down, ignore this event.
return NS_OK;
}
@ -317,7 +323,7 @@ void
IndexedDBDatabaseParent::Disconnect()
{
if (mDatabase) {
mDatabase->DisconnectFromActor();
mDatabase->DisconnectFromActorParent();
}
}
@ -330,11 +336,22 @@ IndexedDBDatabaseParent::CheckWritePermission(const nsAString& aDatabaseName)
return manager->CheckWritePermission(aDatabaseName);
}
void
IndexedDBDatabaseParent::Invalidate()
{
MOZ_ASSERT(mDatabase);
if (!IsDisconnected()) {
mozilla::unused << SendInvalidate();
}
}
nsresult
IndexedDBDatabaseParent::HandleRequestEvent(nsIDOMEvent* aEvent,
const nsAString& aType)
{
MOZ_ASSERT(mOpenRequest);
MOZ_ASSERT(!IsDisconnected());
nsresult rv;
@ -510,6 +527,7 @@ IndexedDBDatabaseParent::HandleDatabaseEvent(nsIDOMEvent* aEvent,
MOZ_ASSERT(mDatabase);
MOZ_ASSERT(!aType.EqualsLiteral(ERROR_EVT_STR),
"Should never get error events in the parent process!");
MOZ_ASSERT(!IsDisconnected());
nsresult rv;
@ -562,6 +580,11 @@ IndexedDBDatabaseParent::RecvClose(const bool& aUnlinked)
{
MOZ_ASSERT(mDatabase);
if (IsDisconnected()) {
// We're shutting down, ignore this request.
return true;
}
mDatabase->CloseInternal(aUnlinked);
return true;
}
@ -574,7 +597,15 @@ IndexedDBDatabaseParent::RecvPIndexedDBTransactionConstructor(
MOZ_ASSERT(aParams.type() ==
TransactionParams::TNormalTransactionParams);
MOZ_ASSERT(!mOpenRequest);
MOZ_ASSERT(mDatabase);
if (IsDisconnected()) {
// We're shutting down, ignore this request.
return true;
}
if (!mDatabase) {
return true;
}
IndexedDBTransactionParent* actor =
static_cast<IndexedDBTransactionParent*>(aActor);
@ -586,6 +617,11 @@ IndexedDBDatabaseParent::RecvPIndexedDBTransactionConstructor(
return false;
}
if (mDatabase->IsClosed()) {
// If the window was navigated then we won't be able to do anything here.
return true;
}
nsTArray<nsString> storesToOpen;
storesToOpen.AppendElements(params.names());
@ -603,11 +639,6 @@ PIndexedDBTransactionParent*
IndexedDBDatabaseParent::AllocPIndexedDBTransaction(
const TransactionParams& aParams)
{
if (!mDatabase) {
// This can happen if the child process dies before we set the database.
return nullptr;
}
MOZ_ASSERT(aParams.type() ==
TransactionParams::TNormalTransactionParams);
return new IndexedDBTransactionParent();
@ -665,6 +696,13 @@ IndexedDBTransactionParent::SetTransaction(IDBTransaction* aTransaction)
nsresult
IndexedDBTransactionParent::HandleEvent(nsIDOMEvent* aEvent)
{
MOZ_ASSERT(aEvent);
if (IsDisconnected()) {
// We're shutting down, ignore this event.
return NS_OK;
}
nsString type;
nsresult rv = aEvent->GetType(type);
NS_ENSURE_SUCCESS(rv, rv);
@ -723,6 +761,12 @@ bool
IndexedDBTransactionParent::RecvAbort(const nsresult& aAbortCode)
{
MOZ_ASSERT(mTransaction);
if (IsDisconnected()) {
// We're shutting down, ignore this request.
return true;
}
mTransaction->Abort(aAbortCode);
return true;
}
@ -733,6 +777,11 @@ IndexedDBTransactionParent::RecvAllRequestsFinished()
MOZ_ASSERT(mTransaction);
MOZ_ASSERT(mArtificialRequestCount);
if (IsDisconnected()) {
// We're shutting down, ignore this request.
return true;
}
mTransaction->OnRequestFinished();
mArtificialRequestCount = false;
@ -751,7 +800,14 @@ IndexedDBTransactionParent::RecvPIndexedDBObjectStoreConstructor(
PIndexedDBObjectStoreParent* aActor,
const ObjectStoreConstructorParams& aParams)
{
MOZ_ASSERT(mTransaction);
if (IsDisconnected()) {
// We're shutting down, ignore this request.
return true;
}
if (!mTransaction) {
return true;
}
IndexedDBObjectStoreParent* actor =
static_cast<IndexedDBObjectStoreParent*>(aActor);
@ -791,11 +847,6 @@ PIndexedDBObjectStoreParent*
IndexedDBTransactionParent::AllocPIndexedDBObjectStore(
const ObjectStoreConstructorParams& aParams)
{
if (!mTransaction) {
// This can happen if the child process dies before we set the transaction.
return nullptr;
}
return new IndexedDBObjectStoreParent();
}
@ -827,7 +878,23 @@ bool
IndexedDBVersionChangeTransactionParent::RecvDeleteObjectStore(
const nsString& aName)
{
MOZ_ASSERT(mTransaction->GetMode() == IDBTransaction::VERSION_CHANGE);
MOZ_ASSERT(!mTransaction ||
mTransaction->GetMode() == IDBTransaction::VERSION_CHANGE);
if (IsDisconnected()) {
// We're shutting down, ignore this request.
return true;
}
if (!mTransaction) {
return true;
}
if (mTransaction->Database()->IsInvalidated()) {
// If we've invalidated this database in the parent then we should bail out
// now to avoid logic problems that could force-kill the child.
return true;
}
IDBDatabase* db = mTransaction->Database();
MOZ_ASSERT(db);
@ -850,7 +917,20 @@ IndexedDBVersionChangeTransactionParent::RecvPIndexedDBObjectStoreConstructor(
PIndexedDBObjectStoreParent* aActor,
const ObjectStoreConstructorParams& aParams)
{
MOZ_ASSERT(mTransaction);
if (IsDisconnected()) {
// We're shutting down, ignore this request.
return true;
}
if (!mTransaction) {
return true;
}
if (mTransaction->Database()->IsInvalidated()) {
// If we've invalidated this database in the parent then we should bail out
// now to avoid logic problems that could force-kill the child.
return true;
}
IndexedDBObjectStoreParent* actor =
static_cast<IndexedDBObjectStoreParent*>(aActor);
@ -894,11 +974,6 @@ PIndexedDBObjectStoreParent*
IndexedDBVersionChangeTransactionParent::AllocPIndexedDBObjectStore(
const ObjectStoreConstructorParams& aParams)
{
if (!mTransaction) {
// This can happen if the child process dies before we set the transaction.
return nullptr;
}
if (aParams.type() ==
ObjectStoreConstructorParams::TCreateObjectStoreParams ||
mTransaction->GetMode() == IDBTransaction::VERSION_CHANGE) {
@ -908,6 +983,86 @@ IndexedDBVersionChangeTransactionParent::AllocPIndexedDBObjectStore(
return IndexedDBTransactionParent::AllocPIndexedDBObjectStore(aParams);
}
/*******************************************************************************
* IndexedDBCursorParent
******************************************************************************/
IndexedDBCursorParent::IndexedDBCursorParent(IDBCursor* aCursor)
: mCursor(aCursor)
{
MOZ_COUNT_CTOR(IndexedDBCursorParent);
MOZ_ASSERT(aCursor);
aCursor->SetActor(this);
}
IndexedDBCursorParent::~IndexedDBCursorParent()
{
MOZ_COUNT_DTOR(IndexedDBCursorParent);
}
bool
IndexedDBCursorParent::IsDisconnected() const
{
MOZ_ASSERT(mCursor);
return mCursor->Transaction()->GetActorParent()->IsDisconnected();
}
void
IndexedDBCursorParent::ActorDestroy(ActorDestroyReason aWhy)
{
MOZ_ASSERT(mCursor);
mCursor->SetActor(static_cast<IndexedDBCursorParent*>(NULL));
}
bool
IndexedDBCursorParent::RecvPIndexedDBRequestConstructor(
PIndexedDBRequestParent* aActor,
const CursorRequestParams& aParams)
{
MOZ_ASSERT(mCursor);
if (IsDisconnected()) {
// We're shutting down, ignore this request.
return true;
}
IndexedDBCursorRequestParent* actor =
static_cast<IndexedDBCursorRequestParent*>(aActor);
if (mCursor->Transaction()->Database()->IsInvalidated()) {
// If we've invalidated this database in the parent then we should bail out
// now to avoid logic problems that could force-kill the child.
return actor->Send__delete__(actor, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
}
switch (aParams.type()) {
case CursorRequestParams::TContinueParams:
return actor->Continue(aParams.get_ContinueParams());
default:
MOZ_NOT_REACHED("Unknown type!");
return false;
}
MOZ_NOT_REACHED("Should never get here!");
return false;
}
PIndexedDBRequestParent*
IndexedDBCursorParent::AllocPIndexedDBRequest(
const CursorRequestParams& aParams)
{
MOZ_ASSERT(mCursor);
return new IndexedDBCursorRequestParent(mCursor, aParams.type());
}
bool
IndexedDBCursorParent::DeallocPIndexedDBRequest(PIndexedDBRequestParent* aActor)
{
delete aActor;
return true;
}
/*******************************************************************************
* IndexedDBObjectStoreParent
******************************************************************************/
@ -925,7 +1080,7 @@ IndexedDBObjectStoreParent::~IndexedDBObjectStoreParent()
void
IndexedDBObjectStoreParent::SetObjectStore(IDBObjectStore* aObjectStore)
{
MOZ_ASSERT(aObjectStore);
// Sadly can't assert aObjectStore here...
MOZ_ASSERT(!mObjectStore);
mObjectStore = aObjectStore;
@ -951,11 +1106,24 @@ IndexedDBObjectStoreParent::RecvPIndexedDBRequestConstructor(
PIndexedDBRequestParent* aActor,
const ObjectStoreRequestParams& aParams)
{
MOZ_ASSERT(mObjectStore);
if (IsDisconnected()) {
// We're shutting down, ignore this request.
return true;
}
if (!mObjectStore) {
return true;
}
IndexedDBObjectStoreRequestParent* actor =
static_cast<IndexedDBObjectStoreRequestParent*>(aActor);
if (mObjectStore->Transaction()->Database()->IsInvalidated()) {
// If we've invalidated this database in the parent then we should bail out
// now to avoid logic problems that could force-kill the child.
return actor->Send__delete__(actor, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
}
switch (aParams.type()) {
case ObjectStoreRequestParams::TGetParams:
return actor->Get(aParams.get_GetParams());
@ -995,7 +1163,14 @@ IndexedDBObjectStoreParent::RecvPIndexedDBIndexConstructor(
PIndexedDBIndexParent* aActor,
const IndexConstructorParams& aParams)
{
MOZ_ASSERT(mObjectStore);
if (IsDisconnected()) {
// We're shutting down, ignore this request.
return true;
}
if (!mObjectStore) {
return true;
}
IndexedDBIndexParent* actor = static_cast<IndexedDBIndexParent*>(aActor);
@ -1031,11 +1206,6 @@ PIndexedDBRequestParent*
IndexedDBObjectStoreParent::AllocPIndexedDBRequest(
const ObjectStoreRequestParams& aParams)
{
if (!mObjectStore) {
// This can happen if the child process dies before we set the objectStore.
return nullptr;
}
return new IndexedDBObjectStoreRequestParent(mObjectStore, aParams.type());
}
@ -1051,11 +1221,6 @@ PIndexedDBIndexParent*
IndexedDBObjectStoreParent::AllocPIndexedDBIndex(
const IndexConstructorParams& aParams)
{
if (!mObjectStore) {
// This can happen if the child process dies before we set the objectStore.
return nullptr;
}
return new IndexedDBIndexParent();
}
@ -1102,9 +1267,25 @@ IndexedDBVersionChangeObjectStoreParent::
bool
IndexedDBVersionChangeObjectStoreParent::RecvDeleteIndex(const nsString& aName)
{
MOZ_ASSERT(mObjectStore->Transaction()->GetMode() ==
MOZ_ASSERT(!mObjectStore ||
mObjectStore->Transaction()->GetMode() ==
IDBTransaction::VERSION_CHANGE);
if (IsDisconnected()) {
// We're shutting down, ignore this request.
return true;
}
if (!mObjectStore) {
return true;
}
if (mObjectStore->Transaction()->Database()->IsInvalidated()) {
// If we've invalidated this database in the parent then we should bail out
// now to avoid logic problems that could force-kill the child.
return true;
}
nsresult rv;
{
@ -1123,7 +1304,20 @@ IndexedDBVersionChangeObjectStoreParent::RecvPIndexedDBIndexConstructor(
PIndexedDBIndexParent* aActor,
const IndexConstructorParams& aParams)
{
MOZ_ASSERT(mObjectStore);
if (IsDisconnected()) {
// We're shutting down, ignore this request.
return true;
}
if (!mObjectStore) {
return true;
}
if (mObjectStore->Transaction()->Database()->IsInvalidated()) {
// If we've invalidated this database in the parent then we should bail out
// now to avoid logic problems that could force-kill the child.
return true;
}
IndexedDBIndexParent* actor = static_cast<IndexedDBIndexParent*>(aActor);
@ -1191,11 +1385,24 @@ IndexedDBIndexParent::RecvPIndexedDBRequestConstructor(
PIndexedDBRequestParent* aActor,
const IndexRequestParams& aParams)
{
MOZ_ASSERT(mIndex);
if (IsDisconnected()) {
// We're shutting down, ignore this request.
return true;
}
if (!mIndex) {
return true;
}
IndexedDBIndexRequestParent* actor =
static_cast<IndexedDBIndexRequestParent*>(aActor);
if (mIndex->ObjectStore()->Transaction()->Database()->IsInvalidated()) {
// If we've invalidated this database in the parent then we should bail out
// now to avoid logic problems that could force-kill the child.
return actor->Send__delete__(actor, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
}
switch (aParams.type()) {
case IndexRequestParams::TGetParams:
return actor->Get(aParams.get_GetParams());
@ -1230,11 +1437,6 @@ IndexedDBIndexParent::RecvPIndexedDBRequestConstructor(
PIndexedDBRequestParent*
IndexedDBIndexParent::AllocPIndexedDBRequest(const IndexRequestParams& aParams)
{
if (!mIndex) {
// This can happen if the child process dies before we set the index.
return nullptr;
}
return new IndexedDBIndexRequestParent(mIndex, aParams.type());
}
@ -1260,68 +1462,6 @@ IndexedDBIndexParent::DeallocPIndexedDBCursor(PIndexedDBCursorParent* aActor)
return true;
}
/*******************************************************************************
* IndexedDBCursorParent
******************************************************************************/
IndexedDBCursorParent::IndexedDBCursorParent(IDBCursor* aCursor)
: mCursor(aCursor)
{
MOZ_COUNT_CTOR(IndexedDBCursorParent);
MOZ_ASSERT(aCursor);
aCursor->SetActor(this);
}
IndexedDBCursorParent::~IndexedDBCursorParent()
{
MOZ_COUNT_DTOR(IndexedDBCursorParent);
}
void
IndexedDBCursorParent::ActorDestroy(ActorDestroyReason aWhy)
{
MOZ_ASSERT(mCursor);
mCursor->SetActor(static_cast<IndexedDBCursorParent*>(NULL));
}
bool
IndexedDBCursorParent::RecvPIndexedDBRequestConstructor(
PIndexedDBRequestParent* aActor,
const CursorRequestParams& aParams)
{
MOZ_ASSERT(mCursor);
IndexedDBCursorRequestParent* actor =
static_cast<IndexedDBCursorRequestParent*>(aActor);
switch (aParams.type()) {
case CursorRequestParams::TContinueParams:
return actor->Continue(aParams.get_ContinueParams());
default:
MOZ_NOT_REACHED("Unknown type!");
return false;
}
MOZ_NOT_REACHED("Should never get here!");
return false;
}
PIndexedDBRequestParent*
IndexedDBCursorParent::AllocPIndexedDBRequest(
const CursorRequestParams& aParams)
{
MOZ_ASSERT(mCursor);
return new IndexedDBCursorRequestParent(mCursor, aParams.type());
}
bool
IndexedDBCursorParent::DeallocPIndexedDBRequest(PIndexedDBRequestParent* aActor)
{
delete aActor;
return true;
}
/*******************************************************************************
* IndexedDBRequestParentBase
******************************************************************************/
@ -1354,7 +1494,7 @@ IndexedDBObjectStoreRequestParent::IndexedDBObjectStoreRequestParent(
: mObjectStore(aObjectStore), mRequestType(aRequestType)
{
MOZ_COUNT_CTOR(IndexedDBObjectStoreRequestParent);
MOZ_ASSERT(aObjectStore);
// Sadly can't assert aObjectStore here...
MOZ_ASSERT(aRequestType > ParamsUnionType::T__None &&
aRequestType <= ParamsUnionType::T__Last);
}
@ -1370,6 +1510,7 @@ IndexedDBObjectStoreRequestParent::ConvertBlobActors(
nsTArray<nsCOMPtr<nsIDOMBlob> >& aBlobs)
{
MOZ_ASSERT(aBlobs.IsEmpty());
MOZ_ASSERT(mObjectStore);
if (!aActors.IsEmpty()) {
// Walk the chain to get to ContentParent.
@ -1385,10 +1526,19 @@ IndexedDBObjectStoreRequestParent::ConvertBlobActors(
}
}
bool
IndexedDBObjectStoreRequestParent::IsDisconnected()
{
MOZ_ASSERT(mObjectStore);
MOZ_ASSERT(mObjectStore->GetActorParent());
return mObjectStore->GetActorParent()->IsDisconnected();
}
bool
IndexedDBObjectStoreRequestParent::Get(const GetParams& aParams)
{
MOZ_ASSERT(mRequestType == ParamsUnionType::TGetParams);
MOZ_ASSERT(mObjectStore);
nsRefPtr<IDBRequest> request;
@ -1406,6 +1556,7 @@ IndexedDBObjectStoreRequestParent::Get(const GetParams& aParams)
request->SetActor(this);
mRequest.swap(request);
return true;
}
@ -1413,6 +1564,7 @@ bool
IndexedDBObjectStoreRequestParent::GetAll(const GetAllParams& aParams)
{
MOZ_ASSERT(mRequestType == ParamsUnionType::TGetAllParams);
MOZ_ASSERT(mObjectStore);
nsRefPtr<IDBRequest> request;
@ -1453,6 +1605,7 @@ bool
IndexedDBObjectStoreRequestParent::Add(const AddParams& aParams)
{
MOZ_ASSERT(mRequestType == ParamsUnionType::TAddParams);
MOZ_ASSERT(mObjectStore);
ipc::AddPutParams params = aParams.commonParams();
@ -1480,6 +1633,7 @@ bool
IndexedDBObjectStoreRequestParent::Put(const PutParams& aParams)
{
MOZ_ASSERT(mRequestType == ParamsUnionType::TPutParams);
MOZ_ASSERT(mObjectStore);
ipc::AddPutParams params = aParams.commonParams();
@ -1507,6 +1661,7 @@ bool
IndexedDBObjectStoreRequestParent::Delete(const DeleteParams& aParams)
{
MOZ_ASSERT(mRequestType == ParamsUnionType::TDeleteParams);
MOZ_ASSERT(mObjectStore);
nsRefPtr<IDBRequest> request;
@ -1531,6 +1686,7 @@ bool
IndexedDBObjectStoreRequestParent::Clear(const ClearParams& aParams)
{
MOZ_ASSERT(mRequestType == ParamsUnionType::TClearParams);
MOZ_ASSERT(mObjectStore);
nsRefPtr<IDBRequest> request;
@ -1550,6 +1706,7 @@ bool
IndexedDBObjectStoreRequestParent::Count(const CountParams& aParams)
{
MOZ_ASSERT(mRequestType == ParamsUnionType::TCountParams);
MOZ_ASSERT(mObjectStore);
const ipc::FIXME_Bug_521898_objectstore::OptionalKeyRange keyRangeUnion =
aParams.optionalKeyRange();
@ -1589,6 +1746,7 @@ bool
IndexedDBObjectStoreRequestParent::OpenCursor(const OpenCursorParams& aParams)
{
MOZ_ASSERT(mRequestType == ParamsUnionType::TOpenCursorParams);
MOZ_ASSERT(mObjectStore);
const ipc::FIXME_Bug_521898_objectstore::OptionalKeyRange keyRangeUnion =
aParams.optionalKeyRange();
@ -1637,7 +1795,7 @@ IndexedDBIndexRequestParent::IndexedDBIndexRequestParent(
: mIndex(aIndex), mRequestType(aRequestType)
{
MOZ_COUNT_CTOR(IndexedDBIndexRequestParent);
MOZ_ASSERT(aIndex);
// Sadly can't assert aIndex here...
MOZ_ASSERT(aRequestType > ParamsUnionType::T__None &&
aRequestType <= ParamsUnionType::T__Last);
}
@ -1647,10 +1805,19 @@ IndexedDBIndexRequestParent::~IndexedDBIndexRequestParent()
MOZ_COUNT_DTOR(IndexedDBIndexRequestParent);
}
bool
IndexedDBIndexRequestParent::IsDisconnected()
{
MOZ_ASSERT(mIndex);
MOZ_ASSERT(mIndex->GetActorParent());
return mIndex->GetActorParent()->IsDisconnected();
}
bool
IndexedDBIndexRequestParent::Get(const GetParams& aParams)
{
MOZ_ASSERT(mRequestType == ParamsUnionType::TGetParams);
MOZ_ASSERT(mIndex);
nsRefPtr<IDBRequest> request;
@ -1675,6 +1842,7 @@ bool
IndexedDBIndexRequestParent::GetKey(const GetKeyParams& aParams)
{
MOZ_ASSERT(mRequestType == ParamsUnionType::TGetKeyParams);
MOZ_ASSERT(mIndex);
nsRefPtr<IDBRequest> request;
@ -1699,6 +1867,7 @@ bool
IndexedDBIndexRequestParent::GetAll(const GetAllParams& aParams)
{
MOZ_ASSERT(mRequestType == ParamsUnionType::TGetAllParams);
MOZ_ASSERT(mIndex);
nsRefPtr<IDBRequest> request;
@ -1738,6 +1907,7 @@ bool
IndexedDBIndexRequestParent::GetAllKeys(const GetAllKeysParams& aParams)
{
MOZ_ASSERT(mRequestType == ParamsUnionType::TGetAllKeysParams);
MOZ_ASSERT(mIndex);
nsRefPtr<IDBRequest> request;
@ -1777,6 +1947,7 @@ bool
IndexedDBIndexRequestParent::Count(const CountParams& aParams)
{
MOZ_ASSERT(mRequestType == ParamsUnionType::TCountParams);
MOZ_ASSERT(mIndex);
const ipc::FIXME_Bug_521898_index::OptionalKeyRange keyRangeUnion =
aParams.optionalKeyRange();
@ -1816,6 +1987,7 @@ bool
IndexedDBIndexRequestParent::OpenCursor(const OpenCursorParams& aParams)
{
MOZ_ASSERT(mRequestType == ParamsUnionType::TOpenCursorParams);
MOZ_ASSERT(mIndex);
const ipc::FIXME_Bug_521898_index::OptionalKeyRange keyRangeUnion =
aParams.optionalKeyRange();
@ -1858,6 +2030,7 @@ bool
IndexedDBIndexRequestParent::OpenKeyCursor(const OpenKeyCursorParams& aParams)
{
MOZ_ASSERT(mRequestType == ParamsUnionType::TOpenKeyCursorParams);
MOZ_ASSERT(mIndex);
const ipc::FIXME_Bug_521898_index::OptionalKeyRange keyRangeUnion =
aParams.optionalKeyRange();
@ -1916,9 +2089,18 @@ IndexedDBCursorRequestParent::~IndexedDBCursorRequestParent()
MOZ_COUNT_DTOR(IndexedDBCursorRequestParent);
}
bool
IndexedDBCursorRequestParent::IsDisconnected()
{
MOZ_ASSERT(mCursor);
MOZ_ASSERT(mCursor->GetActorParent());
return mCursor->GetActorParent()->IsDisconnected();
}
bool
IndexedDBCursorRequestParent::Continue(const ContinueParams& aParams)
{
MOZ_ASSERT(mCursor);
MOZ_ASSERT(mRequestType == ParamsUnionType::TContinueParams);
{
@ -1955,13 +2137,13 @@ IndexedDBDeleteDatabaseRequestParent::~IndexedDBDeleteDatabaseRequestParent()
nsresult
IndexedDBDeleteDatabaseRequestParent::HandleEvent(nsIDOMEvent* aEvent)
{
if (Manager() &&
static_cast<IndexedDBParent*>(Manager())->IsDisconnected()) {
MOZ_ASSERT(aEvent);
if (IsDisconnected()) {
// We're shutting down, ignore this event.
return NS_OK;
}
MOZ_ASSERT(aEvent);
nsString type;
nsresult rv = aEvent->GetType(type);
NS_ENSURE_SUCCESS(rv, rv);

View File

@ -41,6 +41,15 @@ class IDBObjectStore;
class IDBOpenDBRequest;
class IDBTransaction;
class IndexedDBCursorParent;
class IndexedDBDatabaseParent;
class IndexedDBDeleteDatabaseRequestParent;
class IndexedDBIndexParent;
class IndexedDBObjectStoreParent;
class IndexedDBTransactionParent;
class IndexedDBVersionChangeTransactionParent;
class IndexedDBVersionChangeObjectStoreParent;
/*******************************************************************************
* AutoSetCurrentTransaction
******************************************************************************/
@ -130,10 +139,12 @@ public:
* IndexedDBParent
******************************************************************************/
class IndexedDBParent : public PIndexedDBParent
class IndexedDBParent : private PIndexedDBParent
{
friend class mozilla::dom::ContentParent;
friend class mozilla::dom::TabParent;
friend class IndexedDBDatabaseParent;
friend class IndexedDBDeleteDatabaseRequestParent;
nsRefPtr<IDBFactory> mFactory;
nsCString mASCIIOrigin;
@ -220,8 +231,12 @@ protected:
* IndexedDBDatabaseParent
******************************************************************************/
class IndexedDBDatabaseParent : public PIndexedDBDatabaseParent
class IndexedDBDatabaseParent : private PIndexedDBDatabaseParent
{
friend class IndexedDBParent;
friend class IndexedDBTransactionParent;
friend class IndexedDBVersionChangeTransactionParent;
AutoWeakEventListener<IndexedDBDatabaseParent> mEventListener;
nsRefPtr<IDBOpenDBRequest> mOpenRequest;
@ -240,9 +255,18 @@ public:
void
Disconnect();
bool
IsDisconnected() const
{
return static_cast<IndexedDBParent*>(Manager())->IsDisconnected();
}
bool
CheckWritePermission(const nsAString& aDatabaseName);
void
Invalidate();
protected:
nsresult
HandleRequestEvent(nsIDOMEvent* aEvent, const nsAString& aType);
@ -273,8 +297,12 @@ protected:
* IndexedDBTransactionParent
******************************************************************************/
class IndexedDBTransactionParent : public PIndexedDBTransactionParent
class IndexedDBTransactionParent : protected PIndexedDBTransactionParent
{
friend class IndexedDBCursorParent;
friend class IndexedDBDatabaseParent;
friend class IndexedDBObjectStoreParent;
protected:
AutoWeakEventListener<IndexedDBTransactionParent> mEventListener;
@ -286,6 +314,12 @@ public:
IndexedDBTransactionParent();
virtual ~IndexedDBTransactionParent();
bool
IsDisconnected() const
{
return static_cast<IndexedDBDatabaseParent*>(Manager())->IsDisconnected();
}
nsresult
SetTransaction(IDBTransaction* aTransaction);
@ -333,10 +367,18 @@ protected:
class IndexedDBVersionChangeTransactionParent :
public IndexedDBTransactionParent
{
friend class IndexedDBVersionChangeObjectStoreParent;
public:
IndexedDBVersionChangeTransactionParent();
virtual ~IndexedDBVersionChangeTransactionParent();
bool
IsDisconnected() const
{
return static_cast<IndexedDBDatabaseParent*>(Manager())->IsDisconnected();
}
protected:
virtual bool
RecvDeleteObjectStore(const nsString& aName) MOZ_OVERRIDE;
@ -352,12 +394,58 @@ protected:
MOZ_OVERRIDE;
};
/*******************************************************************************
* IndexedDBCursorParent
******************************************************************************/
class IndexedDBCursorParent : private PIndexedDBCursorParent
{
friend class IndexedDBIndexParent;
friend class IndexedDBObjectStoreParent;
nsRefPtr<IDBCursor> mCursor;
public:
IDBCursor*
GetCursor() const
{
return mCursor;
}
bool
IsDisconnected() const;
protected:
IndexedDBCursorParent(IDBCursor* aCursor);
virtual ~IndexedDBCursorParent();
virtual void
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
virtual bool
RecvPIndexedDBRequestConstructor(PIndexedDBRequestParent* aActor,
const CursorRequestParams& aParams)
MOZ_OVERRIDE;
virtual PIndexedDBRequestParent*
AllocPIndexedDBRequest(const CursorRequestParams& aParams) MOZ_OVERRIDE;
virtual bool
DeallocPIndexedDBRequest(PIndexedDBRequestParent* aActor) MOZ_OVERRIDE;
};
/*******************************************************************************
* IndexedDBObjectStoreParent
******************************************************************************/
class IndexedDBObjectStoreParent : public PIndexedDBObjectStoreParent
class IndexedDBObjectStoreParent : protected PIndexedDBObjectStoreParent
{
friend class IndexedDBIndexParent;
friend class IndexedDBTransactionParent;
friend class IndexedDBVersionChangeTransactionParent;
typedef mozilla::dom::indexedDB::ipc::OpenCursorResponse OpenCursorResponse;
protected:
nsRefPtr<IDBObjectStore> mObjectStore;
@ -374,6 +462,38 @@ public:
return mObjectStore;
}
bool
IsDisconnected() const
{
IndexedDBTransactionParent* manager =
static_cast<IndexedDBTransactionParent*>(Manager());
return manager->IsDisconnected();
}
// Ordinarily callers could just do this manually using
// PIndexedDBObjectStoreParent::SendPIndexedDBCursorConstructor but we're
// inheriting the abstract protocol class privately to prevent outside code
// from sending messages without checking the disconnected state. Therefore
// we need a helper method.
bool
OpenCursor(IDBCursor* aCursor,
const ObjectStoreCursorConstructorParams& aParams,
OpenCursorResponse& aResponse) NS_WARN_UNUSED_RESULT
{
if (IsDisconnected()) {
return true;
}
IndexedDBCursorParent* cursorActor = new IndexedDBCursorParent(aCursor);
if (!SendPIndexedDBCursorConstructor(cursorActor, aParams)) {
return false;
}
aResponse = cursorActor;
return true;
}
protected:
virtual void
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
@ -418,11 +538,21 @@ protected:
class IndexedDBVersionChangeObjectStoreParent :
public IndexedDBObjectStoreParent
{
friend class IndexedDBVersionChangeTransactionParent;
public:
IndexedDBVersionChangeObjectStoreParent();
virtual ~IndexedDBVersionChangeObjectStoreParent();
protected:
bool
IsDisconnected() const
{
IndexedDBVersionChangeTransactionParent* manager =
static_cast<IndexedDBVersionChangeTransactionParent*>(Manager());
return manager->IsDisconnected();
}
virtual bool
RecvDeleteIndex(const nsString& aName) MOZ_OVERRIDE;
@ -436,8 +566,13 @@ protected:
* IndexedDBIndexParent
******************************************************************************/
class IndexedDBIndexParent : public PIndexedDBIndexParent
class IndexedDBIndexParent : private PIndexedDBIndexParent
{
friend class IndexedDBObjectStoreParent;
friend class IndexedDBVersionChangeObjectStoreParent;
typedef mozilla::dom::indexedDB::ipc::OpenCursorResponse OpenCursorResponse;
nsRefPtr<IDBIndex> mIndex;
public:
@ -453,6 +588,37 @@ public:
return mIndex;
}
// Ordinarily callers could just do this manually using
// PIndexedDBIndexParent::SendPIndexedDBCursorConstructor but we're
// inheriting the abstract protocol class privately to prevent outside code
// from sending messages without checking the disconnected state. Therefore
// we need a helper method.
bool
OpenCursor(IDBCursor* aCursor, const IndexCursorConstructorParams& aParams,
OpenCursorResponse& aResponse) NS_WARN_UNUSED_RESULT
{
if (IsDisconnected()) {
return true;
}
IndexedDBCursorParent* cursorActor = new IndexedDBCursorParent(aCursor);
if (!SendPIndexedDBCursorConstructor(cursorActor, aParams)) {
return false;
}
aResponse = cursorActor;
return true;
}
bool
IsDisconnected() const
{
IndexedDBObjectStoreParent* manager =
static_cast<IndexedDBObjectStoreParent*>(Manager());
return manager->IsDisconnected();
}
protected:
virtual void
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
@ -476,48 +642,29 @@ protected:
DeallocPIndexedDBCursor(PIndexedDBCursorParent* aActor) MOZ_OVERRIDE;
};
/*******************************************************************************
* IndexedDBCursorParent
******************************************************************************/
class IndexedDBCursorParent : public PIndexedDBCursorParent
{
nsRefPtr<IDBCursor> mCursor;
public:
IndexedDBCursorParent(IDBCursor* aCursor);
virtual ~IndexedDBCursorParent();
IDBCursor*
GetCursor() const
{
return mCursor;
}
protected:
virtual void
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
virtual bool
RecvPIndexedDBRequestConstructor(PIndexedDBRequestParent* aActor,
const CursorRequestParams& aParams)
MOZ_OVERRIDE;
virtual PIndexedDBRequestParent*
AllocPIndexedDBRequest(const CursorRequestParams& aParams) MOZ_OVERRIDE;
virtual bool
DeallocPIndexedDBRequest(PIndexedDBRequestParent* aActor) MOZ_OVERRIDE;
};
/*******************************************************************************
* IndexedDBRequestParentBase
******************************************************************************/
class IndexedDBRequestParentBase : public PIndexedDBRequestParent
{
public:
bool
SendResponse(const ResponseValue& aResponse) NS_WARN_UNUSED_RESULT
{
if (IsDisconnected()) {
return true;
}
return Send__delete__(this, aResponse);
}
protected:
// Don't let anyone call this directly, instead go through SendResponse.
using PIndexedDBRequestParent::Send__delete__;
typedef ipc::ResponseValue ResponseValue;
typedef PIndexedDBRequestParent::PBlobParent PBlobParent;
nsRefPtr<IDBRequest> mRequest;
@ -526,6 +673,9 @@ protected:
virtual void
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
virtual bool
IsDisconnected() = 0;
};
/*******************************************************************************
@ -534,6 +684,8 @@ protected:
class IndexedDBObjectStoreRequestParent : public IndexedDBRequestParentBase
{
friend class IndexedDBObjectStoreParent;
nsRefPtr<IDBObjectStore> mObjectStore;
typedef ipc::ObjectStoreRequestParams ParamsUnionType;
@ -582,6 +734,10 @@ protected:
void
ConvertBlobActors(const InfallibleTArray<PBlobParent*>& aActors,
nsTArray<nsCOMPtr<nsIDOMBlob> >& aBlobs);
private:
virtual bool
IsDisconnected() MOZ_OVERRIDE;
};
/*******************************************************************************
@ -590,6 +746,8 @@ protected:
class IndexedDBIndexRequestParent : public IndexedDBRequestParentBase
{
friend class IndexedDBIndexParent;
nsRefPtr<IDBIndex> mIndex;
typedef ipc::IndexRequestParams ParamsUnionType;
@ -628,6 +786,10 @@ public:
bool
OpenKeyCursor(const OpenKeyCursorParams& aParams);
private:
virtual bool
IsDisconnected() MOZ_OVERRIDE;
};
/*******************************************************************************
@ -636,6 +798,8 @@ public:
class IndexedDBCursorRequestParent : public IndexedDBRequestParentBase
{
friend class IndexedDBCursorParent;
nsRefPtr<IDBCursor> mCursor;
typedef ipc::CursorRequestParams ParamsUnionType;
@ -650,6 +814,10 @@ public:
bool
Continue(const ContinueParams& aParams);
private:
virtual bool
IsDisconnected() MOZ_OVERRIDE;
};
/*******************************************************************************
@ -657,25 +825,33 @@ public:
******************************************************************************/
class IndexedDBDeleteDatabaseRequestParent :
public PIndexedDBDeleteDatabaseRequestParent
private PIndexedDBDeleteDatabaseRequestParent
{
friend class IndexedDBParent;
AutoWeakEventListener<IndexedDBDeleteDatabaseRequestParent> mEventListener;
nsRefPtr<IDBFactory> mFactory;
nsRefPtr<IDBOpenDBRequest> mOpenRequest;
public:
nsresult
HandleEvent(nsIDOMEvent* aEvent);
protected:
IndexedDBDeleteDatabaseRequestParent(IDBFactory* aFactory);
virtual ~IndexedDBDeleteDatabaseRequestParent();
nsresult
SetOpenRequest(IDBOpenDBRequest* aOpenRequest);
nsresult
HandleEvent(nsIDOMEvent* aEvent);
bool
IsDisconnected() const
{
return static_cast<IndexedDBParent*>(Manager())->IsDisconnected();
}
};
END_INDEXEDDB_NAMESPACE
#endif // mozilla_dom_indexeddb_ipc_indexeddbparent_h__

View File

@ -1648,6 +1648,12 @@ TabChild::RecvDestroy()
observerService->RemoveObserver(this, BROWSER_ZOOM_TO_RECT);
observerService->RemoveObserver(this, BEFORE_FIRST_PAINT);
const InfallibleTArray<PIndexedDBChild*>& idbActors =
ManagedPIndexedDBChild();
for (uint32_t i = 0; i < idbActors.Length(); ++i) {
static_cast<IndexedDBChild*>(idbActors[i])->Disconnect();
}
// XXX what other code in ~TabChild() should we be running here?
DestroyWindow();

View File

@ -107,7 +107,9 @@ void Channel::ChannelImpl::Close() {
}
bool Channel::ChannelImpl::Send(Message* message) {
DCHECK(thread_check_->CalledOnValidThread());
if (thread_check_.get()) {
DCHECK(thread_check_->CalledOnValidThread());
}
chrome::Counters::ipc_send_counter().Increment();
#ifdef IPC_MESSAGE_DEBUG_EXTRA
DLOG(INFO) << "sending message @" << message << " on channel @" << this

View File

@ -2855,10 +2855,10 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
if not ptype.isToplevel():
if 1 == len(p.managers):
## manager()
## manager() const
managertype = p.managerActorType(self.side, ptr=1)
managermeth = MethodDefn(MethodDecl(
p.managerMethod().name, ret=managertype))
p.managerMethod().name, ret=managertype, const=1))
managermeth.addstmt(StmtReturn(
ExprCast(p.managerVar(), managertype, static=1)))