mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 08:12:05 +00:00
Bug 718132 - IndexedDB: Intermittent Failing to get JS wrapper in IDBRequest::NotifyHelperCompleted. r=khuey.
--HG-- extra : transplant_source : 1j%98%F9%1D%7F%C8%13%8E%9D%B0%05%05%93%D4%60%89%3D%06%19
This commit is contained in:
parent
84576fe4ec
commit
c597ebf39d
@ -5454,8 +5454,9 @@ public:
|
||||
}
|
||||
NS_IMETHOD_(void) NoteScriptChild(PRUint32 langID, void* child)
|
||||
{
|
||||
if (langID == nsIProgrammingLanguage::JAVASCRIPT) {
|
||||
mFound = child == mWrapper;
|
||||
if (langID == nsIProgrammingLanguage::JAVASCRIPT &&
|
||||
child == mWrapper) {
|
||||
mFound = true;
|
||||
}
|
||||
}
|
||||
NS_IMETHOD_(void) NoteXPCOMChild(nsISupports *child)
|
||||
|
@ -490,6 +490,7 @@
|
||||
#include "DOMSVGPointList.h"
|
||||
#include "DOMSVGTransformList.h"
|
||||
|
||||
#include "mozilla/dom/indexedDB/IDBWrapperCache.h"
|
||||
#include "mozilla/dom/indexedDB/IDBFactory.h"
|
||||
#include "mozilla/dom/indexedDB/IDBRequest.h"
|
||||
#include "mozilla/dom/indexedDB/IDBDatabase.h"
|
||||
@ -501,6 +502,8 @@
|
||||
#include "mozilla/dom/indexedDB/IDBIndex.h"
|
||||
#include "nsIIDBDatabaseException.h"
|
||||
|
||||
using mozilla::dom::indexedDB::IDBWrapperCache;
|
||||
|
||||
#include "nsIDOMMediaQueryList.h"
|
||||
|
||||
#include "nsDOMTouchEvent.h"
|
||||
@ -595,6 +598,10 @@ static const char kDOMStringBundleURL[] =
|
||||
(DOM_DEFAULT_SCRIPTABLE_FLAGS | \
|
||||
nsIXPCScriptable::WANT_ADDPROPERTY)
|
||||
|
||||
#define IDBEVENTTARGET_SCRIPTABLE_FLAGS \
|
||||
(EVENTTARGET_SCRIPTABLE_FLAGS | \
|
||||
nsIXPCScriptable::WANT_POSTCREATE)
|
||||
|
||||
#define DOMCLASSINFO_STANDARD_FLAGS \
|
||||
(nsIClassInfo::MAIN_THREAD_ONLY | nsIClassInfo::DOM_OBJECT)
|
||||
|
||||
@ -656,6 +663,37 @@ DOMCI_DATA(DOMConstructor, void)
|
||||
NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA_WITH_NAME(_class, _class, _helper, \
|
||||
_flags)
|
||||
|
||||
namespace {
|
||||
|
||||
class IDBEventTargetSH : public nsEventTargetSH
|
||||
{
|
||||
protected:
|
||||
IDBEventTargetSH(nsDOMClassInfoData* aData) : nsEventTargetSH(aData)
|
||||
{ }
|
||||
|
||||
virtual ~IDBEventTargetSH()
|
||||
{ }
|
||||
|
||||
public:
|
||||
NS_IMETHOD PreCreate(nsISupports *aNativeObj, JSContext *aCx,
|
||||
JSObject *aGlobalObj, JSObject **aParentObj);
|
||||
|
||||
NS_IMETHOD PostCreate(nsIXPConnectWrappedNative *aQrapper, JSContext *aCx,
|
||||
JSObject *aObj);
|
||||
|
||||
NS_IMETHOD AddProperty(nsIXPConnectWrappedNative *aWrapper, JSContext *aCx,
|
||||
JSObject *aObj, jsid aId, jsval *aVp, bool *aRetval);
|
||||
|
||||
virtual void PreserveWrapper(nsISupports *aNative);
|
||||
|
||||
static nsIClassInfo *doCreate(nsDOMClassInfoData *aData)
|
||||
{
|
||||
return new IDBEventTargetSH(aData);
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// This list of NS_DEFINE_CLASSINFO_DATA macros is what gives the DOM
|
||||
// classes their correct behavior when used through XPConnect. The
|
||||
// arguments that are passed to NS_DEFINE_CLASSINFO_DATA are
|
||||
@ -1539,14 +1577,14 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(IDBFactory, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(IDBRequest, nsEventTargetSH,
|
||||
EVENTTARGET_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(IDBDatabase, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(IDBRequest, IDBEventTargetSH,
|
||||
IDBEVENTTARGET_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(IDBDatabase, IDBEventTargetSH,
|
||||
IDBEVENTTARGET_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(IDBObjectStore, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(IDBTransaction, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(IDBTransaction, IDBEventTargetSH,
|
||||
IDBEVENTTARGET_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(IDBCursor, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(IDBCursorWithValue, nsDOMGenericSH,
|
||||
@ -1557,8 +1595,8 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(IDBVersionChangeEvent, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(IDBOpenDBRequest, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(IDBOpenDBRequest, IDBEventTargetSH,
|
||||
IDBEVENTTARGET_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(IDBDatabaseException, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
@ -7621,6 +7659,46 @@ nsEventTargetSH::PreserveWrapper(nsISupports *aNative)
|
||||
nsContentUtils::PreserveWrapper(aNative, target);
|
||||
}
|
||||
|
||||
// IDBEventTarget helper
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBEventTargetSH::PreCreate(nsISupports *aNativeObj, JSContext *aCx,
|
||||
JSObject *aGlobalObj, JSObject **aParentObj)
|
||||
{
|
||||
IDBWrapperCache *target = IDBWrapperCache::FromSupports(aNativeObj);
|
||||
JSObject *parent = target->GetParentObject();
|
||||
*aParentObj = parent ? parent : aGlobalObj;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBEventTargetSH::PostCreate(nsIXPConnectWrappedNative *aWrapper,
|
||||
JSContext *aCx, JSObject *aObj)
|
||||
{
|
||||
IDBWrapperCache *target = IDBWrapperCache::FromSupports(aWrapper->Native());
|
||||
target->OnWrapperCreated();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBEventTargetSH::AddProperty(nsIXPConnectWrappedNative *aWrapper,
|
||||
JSContext *aCx, JSObject *aObj, jsid aId,
|
||||
jsval *aVp, bool *aRetval)
|
||||
{
|
||||
if (aId == sAddEventListener_id) {
|
||||
return nsEventTargetSH::AddProperty(aWrapper, aCx, aObj, aId, aVp, aRetval);
|
||||
}
|
||||
|
||||
IDBEventTargetSH::PreserveWrapper(GetNative(aWrapper, aObj));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
IDBEventTargetSH::PreserveWrapper(nsISupports *aNative)
|
||||
{
|
||||
IDBWrapperCache *target = IDBWrapperCache::FromSupports(aNative);
|
||||
nsContentUtils::PreserveWrapper(aNative, target);
|
||||
}
|
||||
|
||||
// Element helper
|
||||
|
||||
|
@ -146,18 +146,11 @@ HelperBase::WrapNative(JSContext* aCx,
|
||||
NS_ASSERTION(aResult, "Null pointer!");
|
||||
NS_ASSERTION(mRequest, "Null request!");
|
||||
|
||||
JSObject* obj;
|
||||
if (mRequest->ScriptContext()) {
|
||||
obj = mRequest->ScriptContext()->GetNativeGlobal();
|
||||
}
|
||||
else {
|
||||
obj = mRequest->GetWrapper();
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE(obj, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
JSObject* global = mRequest->GetParentObject();
|
||||
NS_ASSERTION(global, "This should never be null!");
|
||||
|
||||
nsresult rv =
|
||||
nsContentUtils::WrapNative(aCx, obj, aNative, aResult);
|
||||
nsContentUtils::WrapNative(aCx, global, aNative, aResult);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
return NS_OK;
|
||||
@ -288,7 +281,7 @@ AsyncConnectionHelper::Run()
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
bool hasSavepoint = false;
|
||||
if (mDatabase) {
|
||||
IndexedDatabaseManager::SetCurrentWindow(mDatabase->Owner());
|
||||
IndexedDatabaseManager::SetCurrentWindow(mDatabase->GetOwner());
|
||||
|
||||
// Make the first savepoint.
|
||||
if (mTransaction) {
|
||||
|
@ -64,8 +64,7 @@ GenerateRequest(IDBCursor* aCursor)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
IDBDatabase* database = aCursor->Transaction()->Database();
|
||||
return IDBRequest::Create(aCursor, database->ScriptContext(),
|
||||
database->Owner(), aCursor->Transaction());
|
||||
return IDBRequest::Create(aCursor, database, aCursor->Transaction());
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
@ -262,11 +261,14 @@ IDBCursor::CreateCommon(IDBRequest* aRequest,
|
||||
|
||||
nsRefPtr<IDBCursor> cursor = new IDBCursor();
|
||||
|
||||
IDBDatabase* database = aTransaction->Database();
|
||||
cursor->mScriptContext = database->GetScriptContext();
|
||||
cursor->mOwner = database->GetOwner();
|
||||
cursor->mScriptOwner = database->GetScriptOwner();
|
||||
|
||||
cursor->mRequest = aRequest;
|
||||
cursor->mTransaction = aTransaction;
|
||||
cursor->mObjectStore = aObjectStore;
|
||||
cursor->mScriptContext = aTransaction->Database()->ScriptContext();
|
||||
cursor->mOwner = aTransaction->Database()->Owner();
|
||||
cursor->mDirection = aDirection;
|
||||
cursor->mContinueQuery = aContinueQuery;
|
||||
cursor->mContinueToQuery = aContinueToQuery;
|
||||
@ -276,7 +278,8 @@ IDBCursor::CreateCommon(IDBRequest* aRequest,
|
||||
}
|
||||
|
||||
IDBCursor::IDBCursor()
|
||||
: mType(OBJECTSTORE),
|
||||
: mScriptOwner(nsnull),
|
||||
mType(OBJECTSTORE),
|
||||
mDirection(nsIIDBCursor::NEXT),
|
||||
mCachedKey(JSVAL_VOID),
|
||||
mCachedPrimaryKey(JSVAL_VOID),
|
||||
@ -377,6 +380,10 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(IDBCursor)
|
||||
"Should have a cached primary key");
|
||||
NS_ASSERTION(tmp->mHaveCachedValue || JSVAL_IS_VOID(tmp->mCachedValue),
|
||||
"Should have a cached value");
|
||||
if (tmp->mScriptOwner) {
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(tmp->mScriptOwner,
|
||||
"mScriptOwner")
|
||||
}
|
||||
if (JSVAL_IS_GCTHING(tmp->mCachedKey)) {
|
||||
void *gcThing = JSVAL_TO_GCTHING(tmp->mCachedKey);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(gcThing, "mCachedKey")
|
||||
@ -395,6 +402,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IDBCursor)
|
||||
// Don't unlink mObjectStore, mIndex, or mTransaction!
|
||||
if (tmp->mRooted) {
|
||||
NS_DROP_JS_OBJECTS(tmp, IDBCursor);
|
||||
tmp->mScriptOwner = nsnull;
|
||||
tmp->mCachedKey = JSVAL_VOID;
|
||||
tmp->mCachedPrimaryKey = JSVAL_VOID;
|
||||
tmp->mCachedValue = JSVAL_VOID;
|
||||
|
@ -154,6 +154,7 @@ protected:
|
||||
|
||||
nsCOMPtr<nsIScriptContext> mScriptContext;
|
||||
nsCOMPtr<nsPIDOMWindow> mOwner;
|
||||
JSObject* mScriptOwner;
|
||||
|
||||
Type mType;
|
||||
PRUint16 mDirection;
|
||||
|
@ -148,8 +148,7 @@ private:
|
||||
|
||||
// static
|
||||
already_AddRefed<IDBDatabase>
|
||||
IDBDatabase::Create(nsIScriptContext* aScriptContext,
|
||||
nsPIDOMWindow* aOwner,
|
||||
IDBDatabase::Create(IDBWrapperCache* aOwnerCache,
|
||||
already_AddRefed<DatabaseInfo> aDatabaseInfo,
|
||||
const nsACString& aASCIIOrigin,
|
||||
FileManager* aFileManager)
|
||||
@ -162,8 +161,9 @@ IDBDatabase::Create(nsIScriptContext* aScriptContext,
|
||||
|
||||
nsRefPtr<IDBDatabase> db(new IDBDatabase());
|
||||
|
||||
db->mScriptContext = aScriptContext;
|
||||
db->mOwner = aOwner;
|
||||
db->mScriptContext = aOwnerCache->GetScriptContext();
|
||||
db->mOwner = aOwnerCache->GetOwner();
|
||||
db->mScriptOwner = aOwnerCache->GetScriptOwner();
|
||||
|
||||
db->mDatabaseId = databaseInfo->id;
|
||||
db->mName = databaseInfo->name;
|
||||
@ -205,6 +205,8 @@ IDBDatabase::~IDBDatabase()
|
||||
mgr->UnregisterDatabase(this);
|
||||
}
|
||||
}
|
||||
|
||||
nsContentUtils::ReleaseWrapper(static_cast<nsIDOMEventTarget*>(this), this);
|
||||
}
|
||||
|
||||
void
|
||||
@ -218,7 +220,7 @@ IDBDatabase::Invalidate()
|
||||
// When the IndexedDatabaseManager needs to invalidate databases, all it has
|
||||
// is an origin, so we call back into the manager to cancel any prompts for
|
||||
// our owner.
|
||||
IndexedDatabaseManager::CancelPromptsForWindow(Owner());
|
||||
IndexedDatabaseManager::CancelPromptsForWindow(GetOwner());
|
||||
|
||||
mInvalidated = true;
|
||||
}
|
||||
@ -280,7 +282,8 @@ void
|
||||
IDBDatabase::OnUnlink()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(!mOwner, "Should have been cleared already!");
|
||||
NS_ASSERTION(!GetOwner() && !GetScriptOwner(),
|
||||
"Should have been cleared already!");
|
||||
|
||||
// We've been unlinked, at the very least we should be able to prevent further
|
||||
// transactions from starting and unblock any other SetVersion callers.
|
||||
@ -298,18 +301,16 @@ IDBDatabase::OnUnlink()
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBDatabase)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBDatabase,
|
||||
nsDOMEventTargetHelper)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnAbortListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnErrorListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnVersionChangeListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBDatabase, IDBWrapperCache)
|
||||
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(abort)
|
||||
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(error)
|
||||
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(versionchange)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBDatabase,
|
||||
nsDOMEventTargetHelper)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnAbortListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnErrorListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnVersionChangeListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBDatabase, IDBWrapperCache)
|
||||
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(abort)
|
||||
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(error)
|
||||
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(versionchange)
|
||||
|
||||
// Do some cleanup.
|
||||
tmp->OnUnlink();
|
||||
@ -318,13 +319,17 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBDatabase)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIIDBDatabase)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBDatabase)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
|
||||
NS_INTERFACE_MAP_END_INHERITING(IDBWrapperCache)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(IDBDatabase, nsDOMEventTargetHelper)
|
||||
NS_IMPL_RELEASE_INHERITED(IDBDatabase, nsDOMEventTargetHelper)
|
||||
NS_IMPL_ADDREF_INHERITED(IDBDatabase, IDBWrapperCache)
|
||||
NS_IMPL_RELEASE_INHERITED(IDBDatabase, IDBWrapperCache)
|
||||
|
||||
DOMCI_DATA(IDBDatabase, IDBDatabase)
|
||||
|
||||
NS_IMPL_EVENT_HANDLER(IDBDatabase, abort);
|
||||
NS_IMPL_EVENT_HANDLER(IDBDatabase, error);
|
||||
NS_IMPL_EVENT_HANDLER(IDBDatabase, versionchange);
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBDatabase::GetName(nsAString& aName)
|
||||
{
|
||||
@ -668,47 +673,6 @@ IDBDatabase::Close()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBDatabase::SetOnabort(nsIDOMEventListener* aAbortListener)
|
||||
{
|
||||
return RemoveAddEventListener(NS_LITERAL_STRING(ABORT_EVT_STR),
|
||||
mOnAbortListener, aAbortListener);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBDatabase::GetOnabort(nsIDOMEventListener** aAbortListener)
|
||||
{
|
||||
return GetInnerEventListener(mOnAbortListener, aAbortListener);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBDatabase::SetOnerror(nsIDOMEventListener* aErrorListener)
|
||||
{
|
||||
return RemoveAddEventListener(NS_LITERAL_STRING(ERROR_EVT_STR),
|
||||
mOnErrorListener, aErrorListener);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBDatabase::GetOnerror(nsIDOMEventListener** aErrorListener)
|
||||
{
|
||||
return GetInnerEventListener(mOnErrorListener, aErrorListener);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBDatabase::SetOnversionchange(nsIDOMEventListener* aVersionChangeListener)
|
||||
{
|
||||
return RemoveAddEventListener(NS_LITERAL_STRING(VERSIONCHANGE_EVT_STR),
|
||||
mOnVersionChangeListener,
|
||||
aVersionChangeListener);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBDatabase::GetOnversionchange(nsIDOMEventListener** aVersionChangeListener)
|
||||
{
|
||||
return GetInnerEventListener(mOnVersionChangeListener,
|
||||
aVersionChangeListener);
|
||||
}
|
||||
|
||||
nsresult
|
||||
IDBDatabase::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
|
@ -41,13 +41,12 @@
|
||||
#define mozilla_dom_indexeddb_idbdatabase_h__
|
||||
|
||||
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
|
||||
#include "mozilla/dom/indexedDB/FileManager.h"
|
||||
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIIDBDatabase.h"
|
||||
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsDOMEventTargetHelper.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "mozilla/dom/indexedDB/IDBWrapperCache.h"
|
||||
#include "mozilla/dom/indexedDB/FileManager.h"
|
||||
|
||||
class nsIScriptContext;
|
||||
class nsPIDOMWindow;
|
||||
@ -61,7 +60,7 @@ class IDBObjectStore;
|
||||
class IDBTransaction;
|
||||
class IndexedDatabaseManager;
|
||||
|
||||
class IDBDatabase : public nsDOMEventTargetHelper,
|
||||
class IDBDatabase : public IDBWrapperCache,
|
||||
public nsIIDBDatabase
|
||||
{
|
||||
friend class AsyncConnectionHelper;
|
||||
@ -71,12 +70,10 @@ public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIIDBDATABASE
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBDatabase,
|
||||
nsDOMEventTargetHelper)
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBDatabase, IDBWrapperCache)
|
||||
|
||||
static already_AddRefed<IDBDatabase>
|
||||
Create(nsIScriptContext* aScriptContext,
|
||||
nsPIDOMWindow* aOwner,
|
||||
Create(IDBWrapperCache* aOwnerCache,
|
||||
already_AddRefed<DatabaseInfo> aDatabaseInfo,
|
||||
const nsACString& aASCIIOrigin,
|
||||
FileManager* aFileManager);
|
||||
@ -104,16 +101,6 @@ public:
|
||||
return mFilePath;
|
||||
}
|
||||
|
||||
nsIScriptContext* ScriptContext()
|
||||
{
|
||||
return mScriptContext;
|
||||
}
|
||||
|
||||
nsPIDOMWindow* Owner()
|
||||
{
|
||||
return mOwner;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDocument> GetOwnerDocument()
|
||||
{
|
||||
if (!mOwner) {
|
||||
@ -168,9 +155,9 @@ private:
|
||||
nsRefPtr<FileManager> mFileManager;
|
||||
|
||||
// Only touched on the main thread.
|
||||
nsRefPtr<nsDOMEventListenerWrapper> mOnAbortListener;
|
||||
nsRefPtr<nsDOMEventListenerWrapper> mOnErrorListener;
|
||||
nsRefPtr<nsDOMEventListenerWrapper> mOnVersionChangeListener;
|
||||
NS_DECL_EVENT_HANDLER(abort);
|
||||
NS_DECL_EVENT_HANDLER(error);
|
||||
NS_DECL_EVENT_HANDLER(versionchange);
|
||||
};
|
||||
|
||||
END_INDEXEDDB_NAMESPACE
|
||||
|
@ -69,7 +69,6 @@
|
||||
#include "IDBKeyRange.h"
|
||||
#include "IndexedDatabaseManager.h"
|
||||
#include "Key.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
@ -91,28 +90,49 @@ struct ObjectStoreInfoMap
|
||||
} // anonymous namespace
|
||||
|
||||
IDBFactory::IDBFactory()
|
||||
: mOwningObject(nsnull)
|
||||
{
|
||||
IDBFactory::NoteUsedByProcessType(XRE_GetProcessType());
|
||||
}
|
||||
|
||||
IDBFactory::~IDBFactory()
|
||||
{
|
||||
if (mOwningObject) {
|
||||
NS_DROP_JS_OBJECTS(this, IDBFactory);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<nsIIDBFactory>
|
||||
IDBFactory::Create(nsPIDOMWindow* aWindow)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
if (aWindow && aWindow->IsOuterWindow()) {
|
||||
NS_ENSURE_TRUE(aWindow, nsnull);
|
||||
|
||||
if (aWindow->IsOuterWindow()) {
|
||||
aWindow = aWindow->GetCurrentInnerWindow();
|
||||
NS_ENSURE_TRUE(aWindow, nsnull);
|
||||
}
|
||||
|
||||
nsRefPtr<IDBFactory> factory = new IDBFactory();
|
||||
factory->mWindow = aWindow;
|
||||
return factory.forget();
|
||||
}
|
||||
|
||||
if (aWindow) {
|
||||
factory->mWindow = do_GetWeakReference(aWindow);
|
||||
NS_ENSURE_TRUE(factory->mWindow, nsnull);
|
||||
}
|
||||
// static
|
||||
already_AddRefed<nsIIDBFactory>
|
||||
IDBFactory::Create(JSContext* aCx,
|
||||
JSObject* aOwningObject)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(aCx, "Null context!");
|
||||
NS_ASSERTION(aOwningObject, "Null object!");
|
||||
NS_ASSERTION(JS_GetGlobalForObject(aCx, aOwningObject) == aOwningObject,
|
||||
"Not a global object!");
|
||||
|
||||
nsRefPtr<IDBFactory> factory = new IDBFactory();
|
||||
factory->mOwningObject = aOwningObject;
|
||||
return factory.forget();
|
||||
}
|
||||
|
||||
@ -400,15 +420,36 @@ IDBFactory::SetDatabaseMetadata(DatabaseInfo* aDatabaseInfo,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(IDBFactory)
|
||||
NS_IMPL_RELEASE(IDBFactory)
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBFactory)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(IDBFactory)
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(IDBFactory)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(IDBFactory)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IDBFactory)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIIDBFactory)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBFactory)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IDBFactory)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mWindow)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IDBFactory)
|
||||
if (tmp->mOwningObject) {
|
||||
tmp->mOwningObject = nsnull;
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mWindow)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(IDBFactory)
|
||||
if (tmp->mOwningObject) {
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(tmp->mOwningObject,
|
||||
"mOwningObject")
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
DOMCI_DATA(IDBFactory, IDBFactory)
|
||||
|
||||
nsresult
|
||||
@ -418,6 +459,7 @@ IDBFactory::OpenCommon(const nsAString& aName,
|
||||
nsIIDBOpenDBRequest** _retval)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(mWindow || mOwningObject, "Must have one of these!");
|
||||
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
||||
// Force ContentChild to cache the path from the parent, so that
|
||||
@ -430,16 +472,19 @@ IDBFactory::OpenCommon(const nsAString& aName,
|
||||
nsCOMPtr<nsPIDOMWindow> window;
|
||||
nsCOMPtr<nsIScriptGlobalObject> sgo;
|
||||
nsIScriptContext* context = nsnull;
|
||||
JSObject* scriptOwner = nsnull;
|
||||
|
||||
if (mWindow) {
|
||||
window = do_QueryReferent(mWindow);
|
||||
NS_ENSURE_TRUE(window, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
sgo = do_QueryInterface(window);
|
||||
sgo = do_QueryInterface(mWindow);
|
||||
NS_ENSURE_TRUE(sgo, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
context = sgo->GetContext();
|
||||
NS_ENSURE_TRUE(context, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
window = mWindow;
|
||||
}
|
||||
else {
|
||||
scriptOwner = mOwningObject;
|
||||
}
|
||||
|
||||
nsCString origin;
|
||||
@ -448,7 +493,7 @@ IDBFactory::OpenCommon(const nsAString& aName,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsRefPtr<IDBOpenDBRequest> request =
|
||||
IDBOpenDBRequest::Create(context, window);
|
||||
IDBOpenDBRequest::Create(context, window, scriptOwner);
|
||||
NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
nsRefPtr<OpenDatabaseHelper> openHelper =
|
||||
|
@ -45,11 +45,11 @@
|
||||
#include "mozIStorageConnection.h"
|
||||
#include "nsIIDBFactory.h"
|
||||
|
||||
#include "nsIWeakReferenceUtils.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
class nsPIDOMWindow;
|
||||
class nsIAtom;
|
||||
class nsPIDOMWindow;
|
||||
|
||||
BEGIN_INDEXEDDB_NAMESPACE
|
||||
|
||||
@ -60,12 +60,17 @@ struct ObjectStoreInfo;
|
||||
class IDBFactory : public nsIIDBFactory
|
||||
{
|
||||
typedef nsTArray<nsRefPtr<ObjectStoreInfo> > ObjectStoreInfoArray;
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBFactory)
|
||||
NS_DECL_NSIIDBFACTORY
|
||||
|
||||
static already_AddRefed<nsIIDBFactory> Create(nsPIDOMWindow* aWindow);
|
||||
|
||||
static already_AddRefed<nsIIDBFactory> Create(JSContext* aCx,
|
||||
JSObject* aOwningObject);
|
||||
|
||||
static already_AddRefed<mozIStorageConnection>
|
||||
GetConnection(const nsAString& aDatabaseFilePath);
|
||||
|
||||
@ -96,7 +101,7 @@ public:
|
||||
|
||||
private:
|
||||
IDBFactory();
|
||||
~IDBFactory() { }
|
||||
~IDBFactory();
|
||||
|
||||
nsresult
|
||||
OpenCommon(const nsAString& aName,
|
||||
@ -104,7 +109,10 @@ private:
|
||||
bool aDeleting,
|
||||
nsIIDBOpenDBRequest** _retval);
|
||||
|
||||
nsCOMPtr<nsIWeakReference> mWindow;
|
||||
// If this factory lives on a window then mWindow must be non-null. Otherwise
|
||||
// mOwningObject must be non-null.
|
||||
nsCOMPtr<nsPIDOMWindow> mWindow;
|
||||
JSObject* mOwningObject;
|
||||
};
|
||||
|
||||
END_INDEXEDDB_NAMESPACE
|
||||
|
@ -294,8 +294,7 @@ GenerateRequest(IDBIndex* aIndex)
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
IDBTransaction* transaction = aIndex->ObjectStore()->Transaction();
|
||||
IDBDatabase* database = transaction->Database();
|
||||
return IDBRequest::Create(aIndex, database->ScriptContext(),
|
||||
database->Owner(), transaction);
|
||||
return IDBRequest::Create(aIndex, database, transaction);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
@ -313,9 +312,6 @@ IDBIndex::Create(IDBObjectStore* aObjectStore,
|
||||
|
||||
nsRefPtr<IDBIndex> index = new IDBIndex();
|
||||
|
||||
index->mScriptContext = database->ScriptContext();
|
||||
index->mOwner = database->Owner();
|
||||
|
||||
index->mObjectStore = aObjectStore;
|
||||
index->mId = aIndexInfo->id;
|
||||
index->mName = aIndexInfo->name;
|
||||
@ -343,14 +339,10 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(IDBIndex)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IDBIndex)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mObjectStore)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOwner)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mScriptContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IDBIndex)
|
||||
// Don't unlink mObjectStore!
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOwner)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mScriptContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IDBIndex)
|
||||
|
@ -113,9 +113,6 @@ private:
|
||||
|
||||
nsRefPtr<IDBObjectStore> mObjectStore;
|
||||
|
||||
nsCOMPtr<nsIScriptContext> mScriptContext;
|
||||
nsCOMPtr<nsPIDOMWindow> mOwner;
|
||||
|
||||
PRInt64 mId;
|
||||
nsString mName;
|
||||
nsString mKeyPath;
|
||||
|
@ -507,8 +507,8 @@ GenerateRequest(IDBObjectStore* aObjectStore)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
IDBDatabase* database = aObjectStore->Transaction()->Database();
|
||||
return IDBRequest::Create(aObjectStore, database->ScriptContext(),
|
||||
database->Owner(), aObjectStore->Transaction());
|
||||
return IDBRequest::Create(aObjectStore, database,
|
||||
aObjectStore->Transaction());
|
||||
}
|
||||
|
||||
JSClass gDummyPropClass = {
|
||||
@ -532,9 +532,6 @@ IDBObjectStore::Create(IDBTransaction* aTransaction,
|
||||
|
||||
nsRefPtr<IDBObjectStore> objectStore = new IDBObjectStore();
|
||||
|
||||
objectStore->mScriptContext = aTransaction->Database()->ScriptContext();
|
||||
objectStore->mOwner = aTransaction->Database()->Owner();
|
||||
|
||||
objectStore->mTransaction = aTransaction;
|
||||
objectStore->mName = aStoreInfo->name;
|
||||
objectStore->mId = aStoreInfo->id;
|
||||
@ -1376,8 +1373,6 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(IDBObjectStore)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IDBObjectStore)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mTransaction,
|
||||
nsIDOMEventTarget)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOwner)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mScriptContext)
|
||||
|
||||
for (PRUint32 i = 0; i < tmp->mCreatedIndexes.Length(); i++) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mCreatedIndexes[i]");
|
||||
@ -1387,8 +1382,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IDBObjectStore)
|
||||
// Don't unlink mTransaction!
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOwner)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mScriptContext)
|
||||
|
||||
tmp->mCreatedIndexes.Clear();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
@ -41,13 +41,14 @@
|
||||
#define mozilla_dom_indexeddb_idbobjectstore_h__
|
||||
|
||||
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
|
||||
#include "mozilla/dom/indexedDB/IDBTransaction.h"
|
||||
|
||||
#include "nsIIDBObjectStore.h"
|
||||
#include "nsIIDBTransaction.h"
|
||||
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
||||
#include "mozilla/dom/indexedDB/IDBTransaction.h"
|
||||
|
||||
class nsIScriptContext;
|
||||
class nsPIDOMWindow;
|
||||
|
||||
@ -204,9 +205,6 @@ protected:
|
||||
private:
|
||||
nsRefPtr<IDBTransaction> mTransaction;
|
||||
|
||||
nsCOMPtr<nsIScriptContext> mScriptContext;
|
||||
nsCOMPtr<nsPIDOMWindow> mOwner;
|
||||
|
||||
PRInt64 mId;
|
||||
nsString mName;
|
||||
nsString mKeyPath;
|
||||
|
@ -62,8 +62,8 @@ USING_INDEXEDDB_NAMESPACE
|
||||
IDBRequest::IDBRequest()
|
||||
: mResultVal(JSVAL_VOID),
|
||||
mErrorCode(0),
|
||||
mResultValRooted(false),
|
||||
mHaveResultOrErrorCode(false)
|
||||
mHaveResultOrErrorCode(false),
|
||||
mManuallyRooted(false)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
}
|
||||
@ -72,19 +72,13 @@ IDBRequest::~IDBRequest()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
if (mResultValRooted) {
|
||||
// Calling a virtual from the destructor is bad... But we know that we won't
|
||||
// call a subclass' implementation because mResultValRooted will be set to
|
||||
// false.
|
||||
UnrootResultVal();
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<IDBRequest>
|
||||
IDBRequest::Create(nsISupports* aSource,
|
||||
nsIScriptContext* aScriptContext,
|
||||
nsPIDOMWindow* aOwner,
|
||||
IDBWrapperCache* aOwnerCache,
|
||||
IDBTransaction* aTransaction)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
@ -92,8 +86,9 @@ IDBRequest::Create(nsISupports* aSource,
|
||||
|
||||
request->mSource = aSource;
|
||||
request->mTransaction = aTransaction;
|
||||
request->mScriptContext = aScriptContext;
|
||||
request->mOwner = aOwner;
|
||||
request->mScriptContext = aOwnerCache->GetScriptContext();
|
||||
request->mOwner = aOwnerCache->GetOwner();
|
||||
request->mScriptOwner = aOwnerCache->GetScriptOwner();
|
||||
|
||||
return request.forget();
|
||||
}
|
||||
@ -105,9 +100,7 @@ IDBRequest::Reset()
|
||||
mResultVal = JSVAL_VOID;
|
||||
mHaveResultOrErrorCode = false;
|
||||
mErrorCode = 0;
|
||||
if (mResultValRooted) {
|
||||
UnrootResultVal();
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -115,7 +108,7 @@ IDBRequest::NotifyHelperCompleted(HelperBase* aHelper)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(!mHaveResultOrErrorCode, "Already called!");
|
||||
NS_ASSERTION(!mResultValRooted, "Already rooted?!");
|
||||
NS_ASSERTION(!PreservingWrapper(), "Already rooted?!");
|
||||
NS_ASSERTION(JSVAL_IS_VOID(mResultVal), "Should be undefined!");
|
||||
|
||||
// See if our window is still valid. If not then we're going to pretend that
|
||||
@ -135,44 +128,39 @@ IDBRequest::NotifyHelperCompleted(HelperBase* aHelper)
|
||||
}
|
||||
|
||||
// Otherwise we need to get the result from the helper.
|
||||
JSContext* cx = nsnull;
|
||||
JSObject* obj = nsnull;
|
||||
if (mScriptContext) {
|
||||
cx = mScriptContext->GetNativeContext();
|
||||
NS_ASSERTION(cx, "Failed to get a context!");
|
||||
|
||||
obj = mScriptContext->GetNativeGlobal();
|
||||
NS_ASSERTION(obj, "Failed to get global object!");
|
||||
}
|
||||
else {
|
||||
JSContext* cx;
|
||||
if (mScriptOwner) {
|
||||
nsIThreadJSContextStack* cxStack = nsContentUtils::ThreadJSContextStack();
|
||||
NS_ASSERTION(cxStack, "Failed to get thread context stack!");
|
||||
|
||||
NS_ENSURE_SUCCESS(cxStack->GetSafeJSContext(&cx),
|
||||
NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
obj = GetWrapper();
|
||||
NS_ENSURE_TRUE(obj, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
if (NS_FAILED(cxStack->GetSafeJSContext(&cx))) {
|
||||
NS_WARNING("Failed to get safe JSContext!");
|
||||
rv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
mErrorCode = NS_ERROR_GET_CODE(rv);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
else {
|
||||
cx = mScriptContext->GetNativeContext();
|
||||
NS_ASSERTION(cx, "Failed to get a context!");
|
||||
}
|
||||
|
||||
JSObject* global = GetParentObject();
|
||||
NS_ASSERTION(global, "This should never be null!");
|
||||
|
||||
JSAutoRequest ar(cx);
|
||||
JSAutoEnterCompartment ac;
|
||||
if (!ac.enter(cx, obj)) {
|
||||
rv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
else {
|
||||
if (ac.enter(cx, global)) {
|
||||
RootResultVal();
|
||||
|
||||
rv = aHelper->GetSuccessResult(cx, &mResultVal);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Unroot if we don't really need to be rooted.
|
||||
if (!JSVAL_IS_GCTHING(mResultVal)) {
|
||||
UnrootResultVal();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("GetSuccessResult failed!");
|
||||
}
|
||||
}
|
||||
else {
|
||||
NS_WARNING("GetSuccessResult failed!");
|
||||
}
|
||||
NS_WARNING("Failed to enter correct compartment!");
|
||||
rv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
@ -189,17 +177,47 @@ IDBRequest::NotifyHelperCompleted(HelperBase* aHelper)
|
||||
void
|
||||
IDBRequest::RootResultVal()
|
||||
{
|
||||
NS_ASSERTION(!mResultValRooted, "This should be false!");
|
||||
// We want to use the preserved wrapper to keep our result alive, but we don't
|
||||
// always get a wrapper right away. Manually root if we don't have a wrapper.
|
||||
if (!PreservingWrapper() && GetWrapperPreserveColor()) {
|
||||
NS_ASSERTION(!mManuallyRooted, "Should not be manually rooted here!");
|
||||
nsContentUtils::PreserveWrapper(static_cast<nsIDOMEventTarget*>(this),
|
||||
this);
|
||||
}
|
||||
else if (!mManuallyRooted) {
|
||||
NS_HOLD_JS_OBJECTS(this, IDBRequest);
|
||||
mResultValRooted = true;
|
||||
mManuallyRooted = true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IDBRequest::UnrootResultVal()
|
||||
{
|
||||
NS_ASSERTION(mResultValRooted, "This should be true!");
|
||||
if (mManuallyRooted) {
|
||||
NS_ASSERTION(!PreservingWrapper(), "Shouldn't have a wrapper here!");
|
||||
NS_DROP_JS_OBJECTS(this, IDBRequest);
|
||||
mResultValRooted = false;
|
||||
mManuallyRooted = false;
|
||||
}
|
||||
else if (PreservingWrapper()) {
|
||||
nsContentUtils::ReleaseWrapper(static_cast<nsIDOMEventTarget*>(this), this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IDBRequest::OnWrapperCreated()
|
||||
{
|
||||
NS_ASSERTION(!PreservingWrapper(),
|
||||
"Shouldn't have had a wrapper before now!");
|
||||
|
||||
// Update our rooting strategy to accommodate new wrapper if needed. We have
|
||||
// to unroot the old way first. This is annoying because XPConnect uses a hash
|
||||
// table to store these so we could be just fine adding an entry for a second
|
||||
// time... However nsContentUtils keeps a counter that will get out of sync if
|
||||
// we do. Safest to just remove the old holder and then add a new one.
|
||||
if (mManuallyRooted) {
|
||||
UnrootResultVal();
|
||||
RootResultVal();
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -262,66 +280,32 @@ IDBRequest::GetErrorCode(PRUint16* aErrorCode)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBRequest::SetOnsuccess(nsIDOMEventListener* aSuccessListener)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
return RemoveAddEventListener(NS_LITERAL_STRING(SUCCESS_EVT_STR),
|
||||
mOnSuccessListener, aSuccessListener);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBRequest::GetOnsuccess(nsIDOMEventListener** aSuccessListener)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
return GetInnerEventListener(mOnSuccessListener, aSuccessListener);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBRequest::SetOnerror(nsIDOMEventListener* aErrorListener)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
return RemoveAddEventListener(NS_LITERAL_STRING(ERROR_EVT_STR),
|
||||
mOnErrorListener, aErrorListener);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBRequest::GetOnerror(nsIDOMEventListener** aErrorListener)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
return GetInnerEventListener(mOnErrorListener, aErrorListener);
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBRequest)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBRequest,
|
||||
nsDOMEventTargetWrapperCache)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnSuccessListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnErrorListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBRequest, IDBWrapperCache)
|
||||
// Don't need NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS because
|
||||
// nsDOMEventTargetHelper does it for us.
|
||||
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(success)
|
||||
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(error)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mSource)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mTransaction,
|
||||
nsPIDOMEventTarget)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBRequest,
|
||||
nsDOMEventTargetWrapperCache)
|
||||
if (tmp->mResultValRooted) {
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBRequest, IDBWrapperCache)
|
||||
tmp->mResultVal = JSVAL_VOID;
|
||||
if (tmp->mManuallyRooted) {
|
||||
tmp->UnrootResultVal();
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnSuccessListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnErrorListener)
|
||||
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(success)
|
||||
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(error)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mSource)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTransaction)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(IDBRequest,
|
||||
nsDOMEventTargetWrapperCache)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(IDBRequest, IDBWrapperCache)
|
||||
// Don't need NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER because
|
||||
// nsDOMEventTargetHelper does it for us.
|
||||
if (JSVAL_IS_GCTHING(tmp->mResultVal)) {
|
||||
void *gcThing = JSVAL_TO_GCTHING(tmp->mResultVal);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(gcThing, "mResultVal")
|
||||
@ -331,13 +315,16 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBRequest)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIIDBRequest)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBRequest)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetWrapperCache)
|
||||
NS_INTERFACE_MAP_END_INHERITING(IDBWrapperCache)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(IDBRequest, nsDOMEventTargetWrapperCache)
|
||||
NS_IMPL_RELEASE_INHERITED(IDBRequest, nsDOMEventTargetWrapperCache)
|
||||
NS_IMPL_ADDREF_INHERITED(IDBRequest, IDBWrapperCache)
|
||||
NS_IMPL_RELEASE_INHERITED(IDBRequest, IDBWrapperCache)
|
||||
|
||||
DOMCI_DATA(IDBRequest, IDBRequest)
|
||||
|
||||
NS_IMPL_EVENT_HANDLER(IDBRequest, success);
|
||||
NS_IMPL_EVENT_HANDLER(IDBRequest, error);
|
||||
|
||||
nsresult
|
||||
IDBRequest::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
@ -352,21 +339,21 @@ IDBOpenDBRequest::~IDBOpenDBRequest()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
if (mResultValRooted) {
|
||||
UnrootResultVal();
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<IDBOpenDBRequest>
|
||||
IDBOpenDBRequest::Create(nsIScriptContext* aScriptContext,
|
||||
nsPIDOMWindow* aOwner)
|
||||
nsPIDOMWindow* aOwner,
|
||||
JSObject* aScriptOwner)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
nsRefPtr<IDBOpenDBRequest> request(new IDBOpenDBRequest());
|
||||
|
||||
request->mScriptContext = aScriptContext;
|
||||
request->mOwner = aOwner;
|
||||
request->mScriptOwner = aScriptOwner;
|
||||
|
||||
return request.forget();
|
||||
}
|
||||
@ -377,37 +364,18 @@ IDBOpenDBRequest::SetTransaction(IDBTransaction* aTransaction)
|
||||
mTransaction = aTransaction;
|
||||
}
|
||||
|
||||
void
|
||||
IDBOpenDBRequest::RootResultVal()
|
||||
{
|
||||
NS_ASSERTION(!mResultValRooted, "This should be false!");
|
||||
NS_HOLD_JS_OBJECTS(this, IDBOpenDBRequest);
|
||||
mResultValRooted = true;
|
||||
}
|
||||
|
||||
void
|
||||
IDBOpenDBRequest::UnrootResultVal()
|
||||
{
|
||||
NS_ASSERTION(mResultValRooted, "This should be true!");
|
||||
NS_DROP_JS_OBJECTS(this, IDBOpenDBRequest);
|
||||
mResultValRooted = false;
|
||||
}
|
||||
|
||||
NS_IMPL_EVENT_HANDLER(IDBOpenDBRequest, blocked)
|
||||
NS_IMPL_EVENT_HANDLER(IDBOpenDBRequest, upgradeneeded)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBOpenDBRequest)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBOpenDBRequest,
|
||||
IDBRequest)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnupgradeneededListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnblockedListener)
|
||||
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(upgradeneeded)
|
||||
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(blocked)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBOpenDBRequest,
|
||||
IDBRequest)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnupgradeneededListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnblockedListener)
|
||||
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(upgradeneeded)
|
||||
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(blocked)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBOpenDBRequest)
|
||||
@ -419,3 +387,6 @@ NS_IMPL_ADDREF_INHERITED(IDBOpenDBRequest, IDBRequest)
|
||||
NS_IMPL_RELEASE_INHERITED(IDBOpenDBRequest, IDBRequest)
|
||||
|
||||
DOMCI_DATA(IDBOpenDBRequest, IDBOpenDBRequest)
|
||||
|
||||
NS_IMPL_EVENT_HANDLER(IDBOpenDBRequest, blocked);
|
||||
NS_IMPL_EVENT_HANDLER(IDBOpenDBRequest, upgradeneeded);
|
||||
|
@ -46,8 +46,7 @@
|
||||
#include "nsIIDBRequest.h"
|
||||
#include "nsIIDBOpenDBRequest.h"
|
||||
|
||||
#include "nsDOMEventTargetWrapperCache.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "mozilla/dom/indexedDB/IDBWrapperCache.h"
|
||||
|
||||
class nsIScriptContext;
|
||||
class nsPIDOMWindow;
|
||||
@ -57,19 +56,18 @@ BEGIN_INDEXEDDB_NAMESPACE
|
||||
class HelperBase;
|
||||
class IDBTransaction;
|
||||
|
||||
class IDBRequest : public nsDOMEventTargetWrapperCache,
|
||||
class IDBRequest : public IDBWrapperCache,
|
||||
public nsIIDBRequest
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIIDBREQUEST
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(IDBRequest,
|
||||
nsDOMEventTargetWrapperCache)
|
||||
IDBWrapperCache)
|
||||
|
||||
static
|
||||
already_AddRefed<IDBRequest> Create(nsISupports* aSource,
|
||||
nsIScriptContext* aScriptContext,
|
||||
nsPIDOMWindow* aOwner,
|
||||
IDBWrapperCache* aOwnerCache,
|
||||
IDBTransaction* aTransaction);
|
||||
|
||||
// nsIDOMEventTarget
|
||||
@ -92,18 +90,10 @@ public:
|
||||
mErrorCode = rv;
|
||||
}
|
||||
|
||||
nsIScriptContext* ScriptContext()
|
||||
{
|
||||
return mScriptContext;
|
||||
}
|
||||
void RootResultVal();
|
||||
void UnrootResultVal();
|
||||
|
||||
nsPIDOMWindow* Owner()
|
||||
{
|
||||
return mOwner;
|
||||
}
|
||||
|
||||
virtual void RootResultVal();
|
||||
virtual void UnrootResultVal();
|
||||
virtual void OnWrapperCreated();
|
||||
|
||||
protected:
|
||||
IDBRequest();
|
||||
@ -112,14 +102,14 @@ protected:
|
||||
nsCOMPtr<nsISupports> mSource;
|
||||
nsRefPtr<IDBTransaction> mTransaction;
|
||||
|
||||
nsRefPtr<nsDOMEventListenerWrapper> mOnSuccessListener;
|
||||
nsRefPtr<nsDOMEventListenerWrapper> mOnErrorListener;
|
||||
NS_DECL_EVENT_HANDLER(success);
|
||||
NS_DECL_EVENT_HANDLER(error);
|
||||
|
||||
jsval mResultVal;
|
||||
|
||||
PRUint16 mErrorCode;
|
||||
bool mResultValRooted;
|
||||
bool mHaveResultOrErrorCode;
|
||||
bool mManuallyRooted;
|
||||
};
|
||||
|
||||
class IDBOpenDBRequest : public IDBRequest,
|
||||
@ -129,24 +119,30 @@ public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_FORWARD_NSIIDBREQUEST(IDBRequest::)
|
||||
NS_DECL_NSIIDBOPENDBREQUEST
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBOpenDBRequest,
|
||||
IDBRequest)
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBOpenDBRequest, IDBRequest)
|
||||
|
||||
static
|
||||
already_AddRefed<IDBOpenDBRequest>
|
||||
Create(nsIScriptContext* aScriptContext,
|
||||
nsPIDOMWindow* aOwner);
|
||||
nsPIDOMWindow* aOwner,
|
||||
JSObject* aScriptOwner);
|
||||
|
||||
static
|
||||
already_AddRefed<IDBOpenDBRequest>
|
||||
Create(IDBWrapperCache* aOwnerCache)
|
||||
{
|
||||
return Create(aOwnerCache->GetScriptContext(), aOwnerCache->GetOwner(),
|
||||
aOwnerCache->GetScriptOwner());
|
||||
}
|
||||
|
||||
void SetTransaction(IDBTransaction* aTransaction);
|
||||
|
||||
virtual void RootResultVal();
|
||||
virtual void UnrootResultVal();
|
||||
|
||||
protected:
|
||||
~IDBOpenDBRequest();
|
||||
|
||||
nsRefPtr<nsDOMEventListenerWrapper> mOnblockedListener;
|
||||
nsRefPtr<nsDOMEventListenerWrapper> mOnupgradeneededListener;
|
||||
// Only touched on the main thread.
|
||||
NS_DECL_EVENT_HANDLER(blocked);
|
||||
NS_DECL_EVENT_HANDLER(upgradeneeded);
|
||||
};
|
||||
|
||||
END_INDEXEDDB_NAMESPACE
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "nsIScriptContext.h"
|
||||
|
||||
#include "mozilla/storage.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsDOMClassInfoID.h"
|
||||
#include "nsDOMLists.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
@ -116,8 +117,9 @@ IDBTransaction::Create(IDBDatabase* aDatabase,
|
||||
|
||||
nsRefPtr<IDBTransaction> transaction = new IDBTransaction();
|
||||
|
||||
transaction->mScriptContext = aDatabase->ScriptContext();
|
||||
transaction->mOwner = aDatabase->Owner();
|
||||
transaction->mScriptContext = aDatabase->GetScriptContext();
|
||||
transaction->mOwner = aDatabase->GetOwner();
|
||||
transaction->mScriptOwner = aDatabase->GetScriptOwner();
|
||||
|
||||
transaction->mDatabase = aDatabase;
|
||||
transaction->mMode = aMode;
|
||||
@ -184,6 +186,8 @@ IDBTransaction::~IDBTransaction()
|
||||
NS_ASSERTION(!mConnection, "Should have called CommitOrRollback!");
|
||||
NS_ASSERTION(!mCreating, "Should have been cleared already!");
|
||||
NS_ASSERTION(mFiredCompleteOrAbort, "Should have fired event!");
|
||||
|
||||
nsContentUtils::ReleaseWrapper(static_cast<nsIDOMEventTarget*>(this), this);
|
||||
}
|
||||
|
||||
void
|
||||
@ -474,27 +478,25 @@ IDBTransaction::ClearCreatedFileInfos()
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBTransaction)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBTransaction,
|
||||
nsDOMEventTargetHelper)
|
||||
IDBWrapperCache)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mDatabase,
|
||||
nsIDOMEventTarget)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnErrorListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnCompleteListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnAbortListener)
|
||||
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(error)
|
||||
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(complete)
|
||||
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(abort)
|
||||
|
||||
for (PRUint32 i = 0; i < tmp->mCreatedObjectStores.Length(); i++) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mCreatedObjectStores[i]");
|
||||
cb.NoteXPCOMChild(static_cast<nsIIDBObjectStore*>(
|
||||
tmp->mCreatedObjectStores[i].get()));
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBTransaction,
|
||||
nsDOMEventTargetHelper)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBTransaction, IDBWrapperCache)
|
||||
// Don't unlink mDatabase!
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnErrorListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnCompleteListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnAbortListener)
|
||||
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(error)
|
||||
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(complete)
|
||||
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(abort)
|
||||
|
||||
tmp->mCreatedObjectStores.Clear();
|
||||
|
||||
@ -504,13 +506,17 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBTransaction)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIIDBTransaction)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIThreadObserver)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBTransaction)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
|
||||
NS_INTERFACE_MAP_END_INHERITING(IDBWrapperCache)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(IDBTransaction, nsDOMEventTargetHelper)
|
||||
NS_IMPL_RELEASE_INHERITED(IDBTransaction, nsDOMEventTargetHelper)
|
||||
NS_IMPL_ADDREF_INHERITED(IDBTransaction, IDBWrapperCache)
|
||||
NS_IMPL_RELEASE_INHERITED(IDBTransaction, IDBWrapperCache)
|
||||
|
||||
DOMCI_DATA(IDBTransaction, IDBTransaction)
|
||||
|
||||
NS_IMPL_EVENT_HANDLER(IDBTransaction, error);
|
||||
NS_IMPL_EVENT_HANDLER(IDBTransaction, complete);
|
||||
NS_IMPL_EVENT_HANDLER(IDBTransaction, abort);
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBTransaction::GetDb(nsIIDBDatabase** aDB)
|
||||
{
|
||||
@ -626,53 +632,6 @@ IDBTransaction::Abort()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBTransaction::SetOnerror(nsIDOMEventListener* aErrorListener)
|
||||
{
|
||||
return RemoveAddEventListener(NS_LITERAL_STRING(ERROR_EVT_STR),
|
||||
mOnErrorListener, aErrorListener);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBTransaction::GetOnerror(nsIDOMEventListener** aErrorListener)
|
||||
{
|
||||
return GetInnerEventListener(mOnErrorListener, aErrorListener);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBTransaction::GetOncomplete(nsIDOMEventListener** aOncomplete)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
return GetInnerEventListener(mOnCompleteListener, aOncomplete);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBTransaction::SetOncomplete(nsIDOMEventListener* aOncomplete)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
return RemoveAddEventListener(NS_LITERAL_STRING(COMPLETE_EVT_STR),
|
||||
mOnCompleteListener, aOncomplete);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBTransaction::GetOnabort(nsIDOMEventListener** aOnabort)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
return GetInnerEventListener(mOnAbortListener, aOnabort);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IDBTransaction::SetOnabort(nsIDOMEventListener* aOnabort)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
return RemoveAddEventListener(NS_LITERAL_STRING(ABORT_EVT_STR),
|
||||
mOnAbortListener, aOnabort);
|
||||
}
|
||||
|
||||
nsresult
|
||||
IDBTransaction::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
@ -817,7 +776,7 @@ CommitHelper::Run()
|
||||
}
|
||||
|
||||
if (mConnection) {
|
||||
IndexedDatabaseManager::SetCurrentWindow(database->Owner());
|
||||
IndexedDatabaseManager::SetCurrentWindow(database->GetOwner());
|
||||
|
||||
if (!mAborted && mUpdateFileRefcountFunction &&
|
||||
NS_FAILED(mUpdateFileRefcountFunction->UpdateDatabase(mConnection))) {
|
||||
|
@ -41,8 +41,6 @@
|
||||
#define mozilla_dom_indexeddb_idbtransaction_h__
|
||||
|
||||
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
|
||||
#include "mozilla/dom/indexedDB/IDBDatabase.h"
|
||||
#include "mozilla/dom/indexedDB/FileInfo.h"
|
||||
|
||||
#include "mozIStorageConnection.h"
|
||||
#include "mozIStorageStatement.h"
|
||||
@ -51,14 +49,15 @@
|
||||
#include "nsIRunnable.h"
|
||||
#include "nsIThreadInternal.h"
|
||||
|
||||
#include "nsDOMEventTargetHelper.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsInterfaceHashtable.h"
|
||||
|
||||
#include "mozilla/dom/indexedDB/IDBDatabase.h"
|
||||
#include "mozilla/dom/indexedDB/IDBWrapperCache.h"
|
||||
#include "mozilla/dom/indexedDB/FileInfo.h"
|
||||
|
||||
class nsIThread;
|
||||
|
||||
BEGIN_INDEXEDDB_NAMESPACE
|
||||
@ -78,7 +77,7 @@ public:
|
||||
virtual nsresult NotifyTransactionComplete(IDBTransaction* aTransaction) = 0;
|
||||
};
|
||||
|
||||
class IDBTransaction : public nsDOMEventTargetHelper,
|
||||
class IDBTransaction : public IDBWrapperCache,
|
||||
public nsIIDBTransaction,
|
||||
public nsIThreadObserver
|
||||
{
|
||||
@ -92,8 +91,7 @@ public:
|
||||
NS_DECL_NSIIDBTRANSACTION
|
||||
NS_DECL_NSITHREADOBSERVER
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBTransaction,
|
||||
nsDOMEventTargetHelper)
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBTransaction, IDBWrapperCache)
|
||||
|
||||
static already_AddRefed<IDBTransaction>
|
||||
Create(IDBDatabase* aDatabase,
|
||||
@ -180,9 +178,9 @@ private:
|
||||
PRUint32 mCreatedRecursionDepth;
|
||||
|
||||
// Only touched on the main thread.
|
||||
nsRefPtr<nsDOMEventListenerWrapper> mOnErrorListener;
|
||||
nsRefPtr<nsDOMEventListenerWrapper> mOnCompleteListener;
|
||||
nsRefPtr<nsDOMEventListenerWrapper> mOnAbortListener;
|
||||
NS_DECL_EVENT_HANDLER(error);
|
||||
NS_DECL_EVENT_HANDLER(complete);
|
||||
NS_DECL_EVENT_HANDLER(abort);
|
||||
|
||||
nsInterfaceHashtable<nsCStringHashKey, mozIStorageStatement>
|
||||
mCachedStatements;
|
||||
|
38
dom/indexedDB/IDBWrapperCache.cpp
Normal file
38
dom/indexedDB/IDBWrapperCache.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "IDBWrapperCache.h"
|
||||
|
||||
USING_INDEXEDDB_NAMESPACE
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBWrapperCache)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBWrapperCache,
|
||||
nsDOMEventTargetWrapperCache)
|
||||
// Don't need NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS because
|
||||
// nsDOMEventTargetHelper does it for us.
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBWrapperCache,
|
||||
nsDOMEventTargetWrapperCache)
|
||||
tmp->mScriptOwner = nsnull;
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(IDBWrapperCache,
|
||||
nsDOMEventTargetWrapperCache)
|
||||
// Don't need NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER because
|
||||
// nsDOMEventTargetHelper does it for us.
|
||||
if (tmp->mScriptOwner) {
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(tmp->mScriptOwner,
|
||||
"mScriptOwner")
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBWrapperCache)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetWrapperCache)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(IDBWrapperCache, nsDOMEventTargetWrapperCache)
|
||||
NS_IMPL_RELEASE_INHERITED(IDBWrapperCache, nsDOMEventTargetWrapperCache)
|
74
dom/indexedDB/IDBWrapperCache.h
Normal file
74
dom/indexedDB/IDBWrapperCache.h
Normal file
@ -0,0 +1,74 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_indexeddb_idbwrappercache_h__
|
||||
#define mozilla_dom_indexeddb_idbwrappercache_h__
|
||||
|
||||
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
|
||||
|
||||
#include "nsDOMEventTargetWrapperCache.h"
|
||||
|
||||
BEGIN_INDEXEDDB_NAMESPACE
|
||||
|
||||
class IDBWrapperCache : public nsDOMEventTargetWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(
|
||||
IDBWrapperCache,
|
||||
nsDOMEventTargetWrapperCache)
|
||||
|
||||
JSObject* GetScriptOwner() const
|
||||
{
|
||||
return mScriptOwner;
|
||||
}
|
||||
|
||||
nsIScriptContext* GetScriptContext() const
|
||||
{
|
||||
return mScriptContext;
|
||||
}
|
||||
|
||||
nsPIDOMWindow* GetOwner() const
|
||||
{
|
||||
return mOwner;
|
||||
}
|
||||
|
||||
JSObject* GetParentObject()
|
||||
{
|
||||
if (mScriptOwner) {
|
||||
return mScriptOwner;
|
||||
}
|
||||
|
||||
// Do what nsEventTargetSH::PreCreate does.
|
||||
nsCOMPtr<nsIScriptGlobalObject> parent;
|
||||
nsDOMEventTargetWrapperCache::GetParentObject(getter_AddRefs(parent));
|
||||
|
||||
return parent ? parent->GetGlobalJSObject() : nsnull;
|
||||
}
|
||||
|
||||
virtual void OnWrapperCreated()
|
||||
{ }
|
||||
|
||||
static IDBWrapperCache* FromSupports(nsISupports* aSupports)
|
||||
{
|
||||
return static_cast<IDBWrapperCache*>(
|
||||
nsDOMEventTargetWrapperCache::FromSupports(aSupports));
|
||||
}
|
||||
|
||||
protected:
|
||||
IDBWrapperCache()
|
||||
: mScriptOwner(nsnull)
|
||||
{ }
|
||||
|
||||
virtual ~IDBWrapperCache()
|
||||
{ }
|
||||
|
||||
JSObject* mScriptOwner;
|
||||
};
|
||||
|
||||
END_INDEXEDDB_NAMESPACE
|
||||
|
||||
#endif // mozilla_dom_indexeddb_idbwrappercache_h__
|
@ -505,7 +505,7 @@ IndexedDatabaseManager::AbortCloseDatabasesForWindow(nsPIDOMWindow* aWindow)
|
||||
|
||||
for (PRUint32 index = 0; index < liveDatabases.Length(); index++) {
|
||||
IDBDatabase*& database = liveDatabases[index];
|
||||
if (database->Owner() == aWindow) {
|
||||
if (database->GetOwner() == aWindow) {
|
||||
if (NS_FAILED(database->Close())) {
|
||||
NS_WARNING("Failed to close database for dying window!");
|
||||
}
|
||||
@ -533,7 +533,7 @@ IndexedDatabaseManager::HasOpenTransactions(nsPIDOMWindow* aWindow)
|
||||
|
||||
for (PRUint32 index = 0; index < liveDatabases.Length(); index++) {
|
||||
IDBDatabase*& database = liveDatabases[index];
|
||||
if (database->Owner() == aWindow &&
|
||||
if (database->GetOwner() == aWindow &&
|
||||
pool->HasTransactionsForDatabase(database)) {
|
||||
return true;
|
||||
}
|
||||
@ -1591,26 +1591,26 @@ NS_IMETHODIMP
|
||||
IndexedDatabaseManager::InitWindowless(const jsval& aObj, JSContext* aCx)
|
||||
{
|
||||
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_ARG(!JSVAL_IS_PRIMITIVE(aObj));
|
||||
|
||||
// Instantiating this class will register exception providers so even
|
||||
// in xpcshell we will get typed (dom) exceptions, instead of general exceptions.
|
||||
// in xpcshell we will get typed (dom) exceptions, instead of general
|
||||
// exceptions.
|
||||
nsCOMPtr<nsIDOMScriptObjectFactory> sof(do_GetService(kDOMSOF_CID));
|
||||
|
||||
// Defining IDBKeyrange static functions on the global.
|
||||
if (JSVAL_IS_PRIMITIVE(aObj)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIIDBFactory> factory = IDBFactory::Create(nsnull);
|
||||
NS_ASSERTION(factory, "IDBFactory should not be null.");
|
||||
|
||||
JSObject* obj = JSVAL_TO_OBJECT(aObj);
|
||||
|
||||
JSObject* global = JS_GetGlobalForObject(aCx, obj);
|
||||
|
||||
nsCOMPtr<nsIIDBFactory> factory = IDBFactory::Create(aCx, global);
|
||||
NS_ENSURE_TRUE(factory, NS_ERROR_FAILURE);
|
||||
|
||||
jsval mozIndexedDBVal;
|
||||
nsresult rv = nsContentUtils::WrapNative(aCx, obj, factory, &mozIndexedDBVal);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!JS_DefineProperty(aCx, obj, "mozIndexedDB", mozIndexedDBVal,
|
||||
nsnull, nsnull, JSPROP_ENUMERATE)) {
|
||||
if (!JS_DefineProperty(aCx, obj, "mozIndexedDB", mozIndexedDBVal, nsnull,
|
||||
nsnull, JSPROP_ENUMERATE)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -61,16 +61,17 @@ CPPSRCS = \
|
||||
IDBCursor.cpp \
|
||||
IDBDatabase.cpp \
|
||||
IDBEvents.cpp \
|
||||
IDBFactory.cpp \
|
||||
IDBIndex.cpp \
|
||||
IDBKeyRange.cpp \
|
||||
IDBObjectStore.cpp \
|
||||
IDBRequest.cpp \
|
||||
IDBTransaction.cpp \
|
||||
IDBFactory.cpp \
|
||||
IDBWrapperCache.cpp \
|
||||
IndexedDatabaseManager.cpp \
|
||||
Key.cpp \
|
||||
OpenDatabaseHelper.cpp \
|
||||
TransactionThreadPool.cpp \
|
||||
Key.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS_mozilla/dom/indexedDB = \
|
||||
@ -82,6 +83,7 @@ EXPORTS_mozilla/dom/indexedDB = \
|
||||
IDBObjectStore.h \
|
||||
IDBRequest.h \
|
||||
IDBTransaction.h \
|
||||
IDBWrapperCache.h \
|
||||
IndexedDatabase.h \
|
||||
IndexedDatabaseManager.h \
|
||||
IDBFactory.h \
|
||||
|
@ -1611,7 +1611,9 @@ OpenDatabaseHelper::DoDatabaseWork()
|
||||
|
||||
NS_ASSERTION(mOpenDBRequest, "This should never be null!");
|
||||
|
||||
nsPIDOMWindow* window = mOpenDBRequest->Owner();
|
||||
// This will be null for non-window contexts.
|
||||
nsPIDOMWindow* window = mOpenDBRequest->GetOwner();
|
||||
|
||||
AutoEnterWindow autoWindow(window);
|
||||
|
||||
nsCOMPtr<nsIFile> dbDirectory;
|
||||
@ -2111,8 +2113,7 @@ OpenDatabaseHelper::EnsureSuccessResult()
|
||||
dbInfo->nextIndexId = mLastIndexId + 1;
|
||||
|
||||
nsRefPtr<IDBDatabase> database =
|
||||
IDBDatabase::Create(mOpenDBRequest->ScriptContext(),
|
||||
mOpenDBRequest->Owner(),
|
||||
IDBDatabase::Create(mOpenDBRequest,
|
||||
dbInfo.forget(),
|
||||
mASCIIOrigin,
|
||||
mFileManager);
|
||||
|
Loading…
Reference in New Issue
Block a user