зеркало из https://github.com/mozilla/gecko-dev.git
Bug 584319 - 'IndexedDB: Out of Memory error and crash when calling moz_indexedDB.open a lot'. r=sicking
This commit is contained in:
Родитель
e8315ce8b9
Коммит
88b443f419
|
@ -172,12 +172,6 @@ AsyncConnectionHelper::Run()
|
||||||
NS_ASSERTION(connection, "This should never be null!");
|
NS_ASSERTION(connection, "This should never be null!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mDatabase) {
|
|
||||||
rv = mDatabase->GetOrCreateConnection(getter_AddRefs(connection));
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
NS_ASSERTION(connection, "This should never be null!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connection) {
|
if (connection) {
|
||||||
rv = connection->SetProgressHandler(kProgressHandlerGranularity, this,
|
rv = connection->SetProgressHandler(kProgressHandlerGranularity, this,
|
||||||
|
|
|
@ -147,14 +147,14 @@ CheckPermissionsHelper::Run()
|
||||||
nsRefPtr<AsyncConnectionHelper> helper;
|
nsRefPtr<AsyncConnectionHelper> helper;
|
||||||
helper.swap(mHelper);
|
helper.swap(mHelper);
|
||||||
|
|
||||||
nsCOMPtr<nsIThread> thread;
|
|
||||||
thread.swap(mThread);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMWindow> window;
|
nsCOMPtr<nsIDOMWindow> window;
|
||||||
window.swap(mWindow);
|
window.swap(mWindow);
|
||||||
|
|
||||||
if (permission == nsIPermissionManager::ALLOW_ACTION) {
|
if (permission == nsIPermissionManager::ALLOW_ACTION) {
|
||||||
return helper->Dispatch(thread);
|
IndexedDatabaseManager* mgr = IndexedDatabaseManager::Get();
|
||||||
|
NS_ASSERTION(mgr, "This should never be null!");
|
||||||
|
|
||||||
|
return helper->Dispatch(mgr->IOThread());
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_ASSERTION(permission == nsIPermissionManager::UNKNOWN_ACTION ||
|
NS_ASSERTION(permission == nsIPermissionManager::UNKNOWN_ACTION ||
|
||||||
|
|
|
@ -63,25 +63,21 @@ public:
|
||||||
NS_DECL_NSIOBSERVER
|
NS_DECL_NSIOBSERVER
|
||||||
|
|
||||||
CheckPermissionsHelper(AsyncConnectionHelper* aHelper,
|
CheckPermissionsHelper(AsyncConnectionHelper* aHelper,
|
||||||
nsIThread* aThread,
|
|
||||||
nsIDOMWindow* aWindow,
|
nsIDOMWindow* aWindow,
|
||||||
const nsACString& aASCIIOrigin)
|
const nsACString& aASCIIOrigin)
|
||||||
: mHelper(aHelper),
|
: mHelper(aHelper),
|
||||||
mThread(aThread),
|
|
||||||
mWindow(aWindow),
|
mWindow(aWindow),
|
||||||
mASCIIOrigin(aASCIIOrigin),
|
mASCIIOrigin(aASCIIOrigin),
|
||||||
mHasPrompted(PR_FALSE),
|
mHasPrompted(PR_FALSE),
|
||||||
mPromptResult(0)
|
mPromptResult(0)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(aHelper, "Null pointer!");
|
NS_ASSERTION(aHelper, "Null pointer!");
|
||||||
NS_ASSERTION(aThread, "Null pointer!");
|
|
||||||
NS_ASSERTION(aWindow, "Null pointer!");
|
NS_ASSERTION(aWindow, "Null pointer!");
|
||||||
NS_ASSERTION(!aASCIIOrigin.IsEmpty(), "Empty host!");
|
NS_ASSERTION(!aASCIIOrigin.IsEmpty(), "Empty host!");
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsRefPtr<AsyncConnectionHelper> mHelper;
|
nsRefPtr<AsyncConnectionHelper> mHelper;
|
||||||
nsCOMPtr<nsIThread> mThread;
|
|
||||||
nsCOMPtr<nsIDOMWindow> mWindow;
|
nsCOMPtr<nsIDOMWindow> mWindow;
|
||||||
nsCString mASCIIOrigin;
|
nsCString mASCIIOrigin;
|
||||||
PRBool mHasPrompted;
|
PRBool mHasPrompted;
|
||||||
|
|
|
@ -81,6 +81,54 @@ EnumerateObjectStoreNames(const nsAString& aKey,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||||
|
DatabaseInfo::DatabaseInfo()
|
||||||
|
: id(0)
|
||||||
|
{
|
||||||
|
MOZ_COUNT_CTOR(DatabaseInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
DatabaseInfo::~DatabaseInfo()
|
||||||
|
{
|
||||||
|
MOZ_COUNT_DTOR(DatabaseInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
IndexInfo::IndexInfo()
|
||||||
|
: id(LL_MININT),
|
||||||
|
unique(false),
|
||||||
|
autoIncrement(false)
|
||||||
|
{
|
||||||
|
MOZ_COUNT_CTOR(IndexInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
IndexInfo::~IndexInfo()
|
||||||
|
{
|
||||||
|
MOZ_COUNT_DTOR(IndexInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectStoreInfo::ObjectStoreInfo()
|
||||||
|
: id(0),
|
||||||
|
autoIncrement(false),
|
||||||
|
databaseId(0)
|
||||||
|
{
|
||||||
|
MOZ_COUNT_CTOR(ObjectStoreInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectStoreInfo::~ObjectStoreInfo()
|
||||||
|
{
|
||||||
|
MOZ_COUNT_DTOR(ObjectStoreInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
IndexUpdateInfo::IndexUpdateInfo()
|
||||||
|
{
|
||||||
|
MOZ_COUNT_CTOR(IndexUpdateInfo);
|
||||||
|
}
|
||||||
|
IndexUpdateInfo::~IndexUpdateInfo()
|
||||||
|
{
|
||||||
|
MOZ_COUNT_DTOR(IndexUpdateInfo);
|
||||||
|
}
|
||||||
|
#endif /* NS_BUILD_REFCNT_LOGGING */
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool
|
bool
|
||||||
DatabaseInfo::Get(PRUint32 aId,
|
DatabaseInfo::Get(PRUint32 aId,
|
||||||
|
|
|
@ -57,8 +57,13 @@ struct DatabaseInfo
|
||||||
|
|
||||||
nsAutoRefCnt referenceCount;
|
nsAutoRefCnt referenceCount;
|
||||||
|
|
||||||
|
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||||
|
DatabaseInfo();
|
||||||
|
~DatabaseInfo();
|
||||||
|
#else
|
||||||
DatabaseInfo()
|
DatabaseInfo()
|
||||||
: id(0) { }
|
: id(0) { }
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool Get(PRUint32 aId,
|
static bool Get(PRUint32 aId,
|
||||||
DatabaseInfo** aInfo);
|
DatabaseInfo** aInfo);
|
||||||
|
@ -73,8 +78,13 @@ struct DatabaseInfo
|
||||||
|
|
||||||
struct IndexInfo
|
struct IndexInfo
|
||||||
{
|
{
|
||||||
|
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||||
|
IndexInfo();
|
||||||
|
~IndexInfo();
|
||||||
|
#else
|
||||||
IndexInfo()
|
IndexInfo()
|
||||||
: id(LL_MININT), unique(false), autoIncrement(false) { }
|
: id(LL_MININT), unique(false), autoIncrement(false) { }
|
||||||
|
#endif
|
||||||
|
|
||||||
PRInt64 id;
|
PRInt64 id;
|
||||||
nsString name;
|
nsString name;
|
||||||
|
@ -92,8 +102,13 @@ struct ObjectStoreInfo
|
||||||
PRUint32 databaseId;
|
PRUint32 databaseId;
|
||||||
nsTArray<IndexInfo> indexes;
|
nsTArray<IndexInfo> indexes;
|
||||||
|
|
||||||
|
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||||
|
ObjectStoreInfo();
|
||||||
|
~ObjectStoreInfo();
|
||||||
|
#else
|
||||||
ObjectStoreInfo()
|
ObjectStoreInfo()
|
||||||
: id(0), autoIncrement(false), databaseId(0) { }
|
: id(0), autoIncrement(false), databaseId(0) { }
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool Get(PRUint32 aDatabaseId,
|
static bool Get(PRUint32 aDatabaseId,
|
||||||
const nsAString& aName,
|
const nsAString& aName,
|
||||||
|
@ -107,6 +122,11 @@ struct ObjectStoreInfo
|
||||||
|
|
||||||
struct IndexUpdateInfo
|
struct IndexUpdateInfo
|
||||||
{
|
{
|
||||||
|
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||||
|
IndexUpdateInfo();
|
||||||
|
~IndexUpdateInfo();
|
||||||
|
#endif
|
||||||
|
|
||||||
IndexInfo info;
|
IndexInfo info;
|
||||||
Key value;
|
Key value;
|
||||||
};
|
};
|
||||||
|
|
|
@ -224,14 +224,10 @@ already_AddRefed<IDBDatabase>
|
||||||
IDBDatabase::Create(nsIScriptContext* aScriptContext,
|
IDBDatabase::Create(nsIScriptContext* aScriptContext,
|
||||||
nsPIDOMWindow* aOwner,
|
nsPIDOMWindow* aOwner,
|
||||||
DatabaseInfo* aDatabaseInfo,
|
DatabaseInfo* aDatabaseInfo,
|
||||||
LazyIdleThread* aThread,
|
|
||||||
nsCOMPtr<mozIStorageConnection>& aConnection,
|
|
||||||
const nsACString& aASCIIOrigin)
|
const nsACString& aASCIIOrigin)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
NS_ASSERTION(aDatabaseInfo, "Null pointer!");
|
NS_ASSERTION(aDatabaseInfo, "Null pointer!");
|
||||||
NS_ASSERTION(aThread, "Null pointer!");
|
|
||||||
NS_ASSERTION(aConnection, "Null pointer!");
|
|
||||||
NS_ASSERTION(!aASCIIOrigin.IsEmpty(), "Empty origin!");
|
NS_ASSERTION(!aASCIIOrigin.IsEmpty(), "Empty origin!");
|
||||||
|
|
||||||
nsRefPtr<IDBDatabase> db(new IDBDatabase());
|
nsRefPtr<IDBDatabase> db(new IDBDatabase());
|
||||||
|
@ -245,16 +241,11 @@ IDBDatabase::Create(nsIScriptContext* aScriptContext,
|
||||||
db->mFilePath = aDatabaseInfo->filePath;
|
db->mFilePath = aDatabaseInfo->filePath;
|
||||||
db->mASCIIOrigin = aASCIIOrigin;
|
db->mASCIIOrigin = aASCIIOrigin;
|
||||||
|
|
||||||
aThread->SetWeakIdleObserver(db);
|
|
||||||
db->mConnectionThread = aThread;
|
|
||||||
|
|
||||||
db->mConnection.swap(aConnection);
|
|
||||||
|
|
||||||
IndexedDatabaseManager* mgr = IndexedDatabaseManager::Get();
|
IndexedDatabaseManager* mgr = IndexedDatabaseManager::Get();
|
||||||
NS_ASSERTION(mgr, "This should never be null!");
|
NS_ASSERTION(mgr, "This should never be null!");
|
||||||
|
|
||||||
if (!mgr->RegisterDatabase(db)) {
|
if (!mgr->RegisterDatabase(db)) {
|
||||||
NS_WARNING("Out of memory?");
|
// Either out of memory or shutting down.
|
||||||
return nsnull;
|
return nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,7 +254,8 @@ IDBDatabase::Create(nsIScriptContext* aScriptContext,
|
||||||
|
|
||||||
IDBDatabase::IDBDatabase()
|
IDBDatabase::IDBDatabase()
|
||||||
: mDatabaseId(0),
|
: mDatabaseId(0),
|
||||||
mInvalidated(0)
|
mInvalidated(0),
|
||||||
|
mRegistered(false)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
@ -276,17 +268,14 @@ IDBDatabase::IDBDatabase()
|
||||||
IDBDatabase::~IDBDatabase()
|
IDBDatabase::~IDBDatabase()
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
IndexedDatabaseManager* mgr = IndexedDatabaseManager::Get();
|
|
||||||
if (mgr) {
|
|
||||||
mgr->UnregisterDatabase(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mConnectionThread) {
|
if (mRegistered) {
|
||||||
mConnectionThread->SetWeakIdleObserver(nsnull);
|
IndexedDatabaseManager* mgr = IndexedDatabaseManager::Get();
|
||||||
|
if (mgr) {
|
||||||
|
mgr->UnregisterDatabase(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseConnection();
|
|
||||||
|
|
||||||
if (mDatabaseId && !mInvalidated) {
|
if (mDatabaseId && !mInvalidated) {
|
||||||
DatabaseInfo* info;
|
DatabaseInfo* info;
|
||||||
if (!DatabaseInfo::Get(mDatabaseId, &info)) {
|
if (!DatabaseInfo::Get(mDatabaseId, &info)) {
|
||||||
|
@ -314,40 +303,6 @@ IDBDatabase::~IDBDatabase()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
|
||||||
IDBDatabase::GetOrCreateConnection(mozIStorageConnection** aResult)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
|
||||||
|
|
||||||
if (mInvalidated) {
|
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mConnection) {
|
|
||||||
mConnection = IDBFactory::GetConnection(mFilePath);
|
|
||||||
NS_ENSURE_TRUE(mConnection, NS_ERROR_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<mozIStorageConnection> result(mConnection);
|
|
||||||
result.forget(aResult);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
IDBDatabase::CloseConnection()
|
|
||||||
{
|
|
||||||
if (mConnection) {
|
|
||||||
if (mConnectionThread) {
|
|
||||||
NS_ProxyRelease(mConnectionThread, mConnection, PR_TRUE);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
NS_ERROR("Leaking connection!");
|
|
||||||
mozIStorageConnection* leak;
|
|
||||||
mConnection.forget(&leak);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
IDBDatabase::IsQuotaDisabled()
|
IDBDatabase::IsQuotaDisabled()
|
||||||
{
|
{
|
||||||
|
@ -415,7 +370,6 @@ IDBDatabase::Invalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
PR_AtomicSet(&mInvalidated, 1);
|
PR_AtomicSet(&mInvalidated, 1);
|
||||||
CloseConnection();
|
|
||||||
|
|
||||||
DatabaseInfo* info;
|
DatabaseInfo* info;
|
||||||
if (!DatabaseInfo::Get(mDatabaseId, &info)) {
|
if (!DatabaseInfo::Get(mDatabaseId, &info)) {
|
||||||
|
@ -448,7 +402,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||||
|
|
||||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBDatabase)
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBDatabase)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIIDBDatabase)
|
NS_INTERFACE_MAP_ENTRY(nsIIDBDatabase)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
|
||||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBDatabase)
|
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBDatabase)
|
||||||
NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
|
NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
|
||||||
|
|
||||||
|
@ -653,6 +606,10 @@ IDBDatabase::Transaction(nsIVariant* aStoreNames,
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
if (IndexedDatabaseManager::IsShuttingDown()) {
|
||||||
|
return NS_ERROR_ILLEGAL_DURING_SHUTDOWN;
|
||||||
|
}
|
||||||
|
|
||||||
if (aOptionalArgCount) {
|
if (aOptionalArgCount) {
|
||||||
if (aMode != nsIIDBTransaction::READ_WRITE &&
|
if (aMode != nsIIDBTransaction::READ_WRITE &&
|
||||||
aMode != nsIIDBTransaction::READ_ONLY &&
|
aMode != nsIIDBTransaction::READ_ONLY &&
|
||||||
|
@ -831,19 +788,6 @@ IDBDatabase::ObjectStore(const nsAString& aName,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
IDBDatabase::Observe(nsISupports* aSubject,
|
|
||||||
const char* aTopic,
|
|
||||||
const PRUnichar* aData)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
NS_ENSURE_FALSE(strcmp(aTopic, IDLE_THREAD_TOPIC), NS_ERROR_UNEXPECTED);
|
|
||||||
|
|
||||||
CloseConnection();
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRUint16
|
PRUint16
|
||||||
SetVersionHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
SetVersionHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,16 +41,13 @@
|
||||||
#define mozilla_dom_indexeddb_idbdatabase_h__
|
#define mozilla_dom_indexeddb_idbdatabase_h__
|
||||||
|
|
||||||
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
|
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
|
||||||
#include "mozilla/dom/indexedDB/LazyIdleThread.h"
|
|
||||||
|
|
||||||
#include "nsIIDBDatabase.h"
|
#include "nsIIDBDatabase.h"
|
||||||
#include "nsIObserver.h"
|
|
||||||
|
|
||||||
#include "nsCycleCollectionParticipant.h"
|
#include "nsCycleCollectionParticipant.h"
|
||||||
#include "nsDOMEventTargetHelper.h"
|
#include "nsDOMEventTargetHelper.h"
|
||||||
#include "nsDOMLists.h"
|
#include "nsDOMLists.h"
|
||||||
|
|
||||||
class mozIStorageConnection;
|
|
||||||
class nsIScriptContext;
|
class nsIScriptContext;
|
||||||
class nsPIDOMWindow;
|
class nsPIDOMWindow;
|
||||||
|
|
||||||
|
@ -59,17 +56,17 @@ BEGIN_INDEXEDDB_NAMESPACE
|
||||||
class AsyncConnectionHelper;
|
class AsyncConnectionHelper;
|
||||||
struct DatabaseInfo;
|
struct DatabaseInfo;
|
||||||
class IDBTransaction;
|
class IDBTransaction;
|
||||||
|
class IndexedDatabaseManager;
|
||||||
|
|
||||||
class IDBDatabase : public nsDOMEventTargetHelper,
|
class IDBDatabase : public nsDOMEventTargetHelper,
|
||||||
public nsIIDBDatabase,
|
public nsIIDBDatabase
|
||||||
public nsIObserver
|
|
||||||
{
|
{
|
||||||
friend class AsyncConnectionHelper;
|
friend class AsyncConnectionHelper;
|
||||||
|
friend class IndexedDatabaseManager;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
NS_DECL_NSIIDBDATABASE
|
NS_DECL_NSIIDBDATABASE
|
||||||
NS_DECL_NSIOBSERVER
|
|
||||||
|
|
||||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBDatabase,
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBDatabase,
|
||||||
nsDOMEventTargetHelper)
|
nsDOMEventTargetHelper)
|
||||||
|
@ -78,17 +75,8 @@ public:
|
||||||
Create(nsIScriptContext* aScriptContext,
|
Create(nsIScriptContext* aScriptContext,
|
||||||
nsPIDOMWindow* aOwner,
|
nsPIDOMWindow* aOwner,
|
||||||
DatabaseInfo* aDatabaseInfo,
|
DatabaseInfo* aDatabaseInfo,
|
||||||
LazyIdleThread* aThread,
|
|
||||||
nsCOMPtr<mozIStorageConnection>& aConnection,
|
|
||||||
const nsACString& aASCIIOrigin);
|
const nsACString& aASCIIOrigin);
|
||||||
|
|
||||||
nsIThread* ConnectionThread()
|
|
||||||
{
|
|
||||||
return mConnectionThread;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CloseConnection();
|
|
||||||
|
|
||||||
PRUint32 Id()
|
PRUint32 Id()
|
||||||
{
|
{
|
||||||
return mDatabaseId;
|
return mDatabaseId;
|
||||||
|
@ -111,8 +99,7 @@ public:
|
||||||
return mOwner;
|
return mOwner;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool IsQuotaDisabled();
|
||||||
IsQuotaDisabled();
|
|
||||||
|
|
||||||
nsCString& Origin()
|
nsCString& Origin()
|
||||||
{
|
{
|
||||||
|
@ -126,21 +113,13 @@ private:
|
||||||
IDBDatabase();
|
IDBDatabase();
|
||||||
~IDBDatabase();
|
~IDBDatabase();
|
||||||
|
|
||||||
// Only meant to be called on mStorageThread!
|
|
||||||
nsresult GetOrCreateConnection(mozIStorageConnection** aConnection);
|
|
||||||
|
|
||||||
PRUint32 mDatabaseId;
|
PRUint32 mDatabaseId;
|
||||||
nsString mName;
|
nsString mName;
|
||||||
nsString mDescription;
|
nsString mDescription;
|
||||||
nsString mFilePath;
|
nsString mFilePath;
|
||||||
nsCString mASCIIOrigin;
|
nsCString mASCIIOrigin;
|
||||||
PRInt32 mInvalidated;
|
PRInt32 mInvalidated;
|
||||||
|
bool mRegistered;
|
||||||
nsRefPtr<LazyIdleThread> mConnectionThread;
|
|
||||||
|
|
||||||
// Only touched on mStorageThread! These must be destroyed in the
|
|
||||||
// FireCloseConnectionRunnable method.
|
|
||||||
nsCOMPtr<mozIStorageConnection> mConnection;
|
|
||||||
|
|
||||||
// Only touched on the main thread.
|
// Only touched on the main thread.
|
||||||
nsRefPtr<nsDOMEventListenerWrapper> mOnErrorListener;
|
nsRefPtr<nsDOMEventListenerWrapper> mOnErrorListener;
|
||||||
|
|
|
@ -128,30 +128,24 @@ public:
|
||||||
OpenDatabaseHelper(IDBRequest* aRequest,
|
OpenDatabaseHelper(IDBRequest* aRequest,
|
||||||
const nsAString& aName,
|
const nsAString& aName,
|
||||||
const nsAString& aDescription,
|
const nsAString& aDescription,
|
||||||
const nsACString& aASCIIOrigin,
|
const nsACString& aASCIIOrigin)
|
||||||
LazyIdleThread* aThread)
|
|
||||||
: AsyncConnectionHelper(static_cast<IDBDatabase*>(nsnull), aRequest),
|
: AsyncConnectionHelper(static_cast<IDBDatabase*>(nsnull), aRequest),
|
||||||
mName(aName), mDescription(aDescription), mASCIIOrigin(aASCIIOrigin),
|
mName(aName), mDescription(aDescription), mASCIIOrigin(aASCIIOrigin),
|
||||||
mThread(aThread), mDatabaseId(0)
|
mDatabaseId(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
PRUint16 DoDatabaseWork(mozIStorageConnection* aConnection);
|
PRUint16 DoDatabaseWork(mozIStorageConnection* aConnection);
|
||||||
PRUint16 GetSuccessResult(nsIWritableVariant* aResult);
|
PRUint16 GetSuccessResult(nsIWritableVariant* aResult);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PRUint16 DoDatabaseWorkInternal(mozIStorageConnection* aConnection);
|
|
||||||
|
|
||||||
// In-params.
|
// In-params.
|
||||||
nsString mName;
|
nsString mName;
|
||||||
nsString mDescription;
|
nsString mDescription;
|
||||||
nsCString mASCIIOrigin;
|
nsCString mASCIIOrigin;
|
||||||
nsRefPtr<LazyIdleThread> mThread;
|
|
||||||
|
|
||||||
// Out-params.
|
// Out-params.
|
||||||
nsTArray<nsAutoPtr<ObjectStoreInfo> > mObjectStores;
|
nsTArray<nsAutoPtr<ObjectStoreInfo> > mObjectStores;
|
||||||
nsString mVersion;
|
nsString mVersion;
|
||||||
|
|
||||||
nsCOMPtr<mozIStorageConnection> mConnection;
|
|
||||||
nsString mDatabaseFilePath;
|
nsString mDatabaseFilePath;
|
||||||
PRUint32 mDatabaseId;
|
PRUint32 mDatabaseId;
|
||||||
};
|
};
|
||||||
|
@ -718,14 +712,11 @@ IDBFactory::Open(const nsAString& aName,
|
||||||
nsRefPtr<IDBRequest> request = IDBRequest::Create(this, context, innerWindow);
|
nsRefPtr<IDBRequest> request = IDBRequest::Create(this, context, innerWindow);
|
||||||
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
nsRefPtr<LazyIdleThread> thread(new LazyIdleThread(kDefaultThreadTimeoutMS,
|
|
||||||
nsnull));
|
|
||||||
|
|
||||||
nsRefPtr<OpenDatabaseHelper> openHelper =
|
nsRefPtr<OpenDatabaseHelper> openHelper =
|
||||||
new OpenDatabaseHelper(request, aName, aDescription, origin, thread);
|
new OpenDatabaseHelper(request, aName, aDescription, origin);
|
||||||
|
|
||||||
nsRefPtr<CheckPermissionsHelper> permissionHelper =
|
nsRefPtr<CheckPermissionsHelper> permissionHelper =
|
||||||
new CheckPermissionsHelper(openHelper, thread, innerWindow, origin);
|
new CheckPermissionsHelper(openHelper, innerWindow, origin);
|
||||||
|
|
||||||
nsRefPtr<IndexedDatabaseManager> mgr = IndexedDatabaseManager::GetOrCreate();
|
nsRefPtr<IndexedDatabaseManager> mgr = IndexedDatabaseManager::GetOrCreate();
|
||||||
NS_ENSURE_TRUE(mgr, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(mgr, NS_ERROR_FAILURE);
|
||||||
|
@ -839,30 +830,26 @@ IDBFactory::MakeBoundKeyRange(nsIVariant* aLeft,
|
||||||
|
|
||||||
PRUint16
|
PRUint16
|
||||||
OpenDatabaseHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
OpenDatabaseHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||||
{
|
|
||||||
PRUint16 result = DoDatabaseWorkInternal(aConnection);
|
|
||||||
if (result != OK) {
|
|
||||||
mConnection = nsnull;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRUint16
|
|
||||||
OpenDatabaseHelper::DoDatabaseWorkInternal(mozIStorageConnection* aConnection)
|
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
{
|
{
|
||||||
PRBool correctThread;
|
PRBool correctThread;
|
||||||
NS_ASSERTION(NS_SUCCEEDED(mThread->IsOnCurrentThread(&correctThread)) &&
|
NS_ASSERTION(NS_SUCCEEDED(IndexedDatabaseManager::Get()->IOThread()->
|
||||||
|
IsOnCurrentThread(&correctThread)) &&
|
||||||
correctThread,
|
correctThread,
|
||||||
"Running on the wrong thread!");
|
"Running on the wrong thread!");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
NS_ASSERTION(!aConnection, "Huh?!");
|
NS_ASSERTION(!aConnection, "Huh?!");
|
||||||
|
|
||||||
|
if (IndexedDatabaseManager::IsShuttingDown()) {
|
||||||
|
return nsIIDBDatabaseException::UNKNOWN_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<mozIStorageConnection> connection;
|
||||||
nsresult rv = CreateDatabaseConnection(mASCIIOrigin, mName, mDescription,
|
nsresult rv = CreateDatabaseConnection(mASCIIOrigin, mName, mDescription,
|
||||||
mDatabaseFilePath,
|
mDatabaseFilePath,
|
||||||
getter_AddRefs(mConnection));
|
getter_AddRefs(connection));
|
||||||
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
|
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
|
||||||
|
|
||||||
mDatabaseId = HashString(mDatabaseFilePath);
|
mDatabaseId = HashString(mDatabaseFilePath);
|
||||||
|
@ -872,7 +859,7 @@ OpenDatabaseHelper::DoDatabaseWorkInternal(mozIStorageConnection* aConnection)
|
||||||
|
|
||||||
{ // Load object store names and ids.
|
{ // Load object store names and ids.
|
||||||
nsCOMPtr<mozIStorageStatement> stmt;
|
nsCOMPtr<mozIStorageStatement> stmt;
|
||||||
rv = mConnection->CreateStatement(NS_LITERAL_CSTRING(
|
rv = connection->CreateStatement(NS_LITERAL_CSTRING(
|
||||||
"SELECT name, id, key_path, auto_increment "
|
"SELECT name, id, key_path, auto_increment "
|
||||||
"FROM object_store"
|
"FROM object_store"
|
||||||
), getter_AddRefs(stmt));
|
), getter_AddRefs(stmt));
|
||||||
|
@ -910,7 +897,7 @@ OpenDatabaseHelper::DoDatabaseWorkInternal(mozIStorageConnection* aConnection)
|
||||||
|
|
||||||
{ // Load index information
|
{ // Load index information
|
||||||
nsCOMPtr<mozIStorageStatement> stmt;
|
nsCOMPtr<mozIStorageStatement> stmt;
|
||||||
rv = mConnection->CreateStatement(NS_LITERAL_CSTRING(
|
rv = connection->CreateStatement(NS_LITERAL_CSTRING(
|
||||||
"SELECT object_store_id, id, name, key_path, unique_index, "
|
"SELECT object_store_id, id, name, key_path, unique_index, "
|
||||||
"object_store_autoincrement "
|
"object_store_autoincrement "
|
||||||
"FROM object_store_index"
|
"FROM object_store_index"
|
||||||
|
@ -951,7 +938,7 @@ OpenDatabaseHelper::DoDatabaseWorkInternal(mozIStorageConnection* aConnection)
|
||||||
|
|
||||||
{ // Load version information.
|
{ // Load version information.
|
||||||
nsCOMPtr<mozIStorageStatement> stmt;
|
nsCOMPtr<mozIStorageStatement> stmt;
|
||||||
rv = mConnection->CreateStatement(NS_LITERAL_CSTRING(
|
rv = connection->CreateStatement(NS_LITERAL_CSTRING(
|
||||||
"SELECT version "
|
"SELECT version "
|
||||||
"FROM database"
|
"FROM database"
|
||||||
), getter_AddRefs(stmt));
|
), getter_AddRefs(stmt));
|
||||||
|
@ -975,8 +962,6 @@ OpenDatabaseHelper::DoDatabaseWorkInternal(mozIStorageConnection* aConnection)
|
||||||
PRUint16
|
PRUint16
|
||||||
OpenDatabaseHelper::GetSuccessResult(nsIWritableVariant* aResult)
|
OpenDatabaseHelper::GetSuccessResult(nsIWritableVariant* aResult)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(mConnection, "Should have a connection!");
|
|
||||||
|
|
||||||
DatabaseInfo* dbInfo;
|
DatabaseInfo* dbInfo;
|
||||||
if (DatabaseInfo::Get(mDatabaseId, &dbInfo)) {
|
if (DatabaseInfo::Get(mDatabaseId, &dbInfo)) {
|
||||||
NS_ASSERTION(dbInfo->referenceCount, "Bad reference count!");
|
NS_ASSERTION(dbInfo->referenceCount, "Bad reference count!");
|
||||||
|
@ -1064,10 +1049,10 @@ OpenDatabaseHelper::GetSuccessResult(nsIWritableVariant* aResult)
|
||||||
|
|
||||||
nsRefPtr<IDBDatabase> db =
|
nsRefPtr<IDBDatabase> db =
|
||||||
IDBDatabase::Create(mRequest->ScriptContext(), mRequest->Owner(), dbInfo,
|
IDBDatabase::Create(mRequest->ScriptContext(), mRequest->Owner(), dbInfo,
|
||||||
mThread, mConnection, mASCIIOrigin);
|
mASCIIOrigin);
|
||||||
NS_ASSERTION(db, "This can't fail!");
|
if (!db) {
|
||||||
|
return nsIIDBDatabaseException::UNKNOWN_ERR;
|
||||||
NS_ASSERTION(!mConnection, "Should have swapped out!");
|
}
|
||||||
|
|
||||||
aResult->SetAsISupports(static_cast<nsPIDOMEventTarget*>(db));
|
aResult->SetAsISupports(static_cast<nsPIDOMEventTarget*>(db));
|
||||||
return OK;
|
return OK;
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
#include "nsHashKeys.h"
|
#include "nsHashKeys.h"
|
||||||
#include "nsInterfaceHashtable.h"
|
#include "nsInterfaceHashtable.h"
|
||||||
|
|
||||||
|
class mozIStorageConnection;
|
||||||
class mozIStorageStatement;
|
class mozIStorageStatement;
|
||||||
class nsIThread;
|
class nsIThread;
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ using namespace mozilla::services;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
bool gShutdown = false;
|
PRInt32 gShutdown = 0;
|
||||||
|
|
||||||
// Does not hold a reference.
|
// Does not hold a reference.
|
||||||
IndexedDatabaseManager* gInstance = nsnull;
|
IndexedDatabaseManager* gInstance = nsnull;
|
||||||
|
@ -116,7 +116,7 @@ IndexedDatabaseManager::GetOrCreate()
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
if (gShutdown) {
|
if (IsShuttingDown()) {
|
||||||
NS_ERROR("Calling GetOrCreateInstance() after shutdown!");
|
NS_ERROR("Calling GetOrCreateInstance() after shutdown!");
|
||||||
return nsnull;
|
return nsnull;
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,8 @@ IndexedDatabaseManager::GetOrCreate()
|
||||||
|
|
||||||
// Make a lazy thread for any IO we need (like clearing or enumerating the
|
// Make a lazy thread for any IO we need (like clearing or enumerating the
|
||||||
// contents of indexedDB database directories).
|
// contents of indexedDB database directories).
|
||||||
instance->mIOThread = new LazyIdleThread(DEFAULT_THREAD_TIMEOUT_MS);
|
instance->mIOThread = new LazyIdleThread(DEFAULT_THREAD_TIMEOUT_MS,
|
||||||
|
LazyIdleThread::ManualShutdown);
|
||||||
|
|
||||||
// The observer service will hold our last reference, don't AddRef here.
|
// The observer service will hold our last reference, don't AddRef here.
|
||||||
gInstance = instance;
|
gInstance = instance;
|
||||||
|
@ -187,7 +188,7 @@ IndexedDatabaseManager::RegisterDatabase(IDBDatabase* aDatabase)
|
||||||
NS_ASSERTION(aDatabase, "Null pointer!");
|
NS_ASSERTION(aDatabase, "Null pointer!");
|
||||||
|
|
||||||
// Don't allow any new databases to be created after shutdown.
|
// Don't allow any new databases to be created after shutdown.
|
||||||
if (gShutdown) {
|
if (IsShuttingDown()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,6 +206,8 @@ IndexedDatabaseManager::RegisterDatabase(IDBDatabase* aDatabase)
|
||||||
NS_WARNING("Out of memory?");
|
NS_WARNING("Out of memory?");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aDatabase->mRegistered = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,6 +290,13 @@ IndexedDatabaseManager::WaitForClearAndDispatch(const nsACString& aOrigin,
|
||||||
return NS_DispatchToCurrentThread(aRunnable);
|
return NS_DispatchToCurrentThread(aRunnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool
|
||||||
|
IndexedDatabaseManager::IsShuttingDown()
|
||||||
|
{
|
||||||
|
return !!gShutdown;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS2(IndexedDatabaseManager, nsIIndexedDatabaseManager,
|
NS_IMPL_ISUPPORTS2(IndexedDatabaseManager, nsIIndexedDatabaseManager,
|
||||||
nsIObserver)
|
nsIObserver)
|
||||||
|
|
||||||
|
@ -445,9 +455,11 @@ IndexedDatabaseManager::Observe(nsISupports* aSubject,
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID)) {
|
if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID)) {
|
||||||
// Setting this flag prevents the servic from being recreated and prevents
|
// Setting this flag prevents the service from being recreated and prevents
|
||||||
// further databases from being created.
|
// further databases from being created.
|
||||||
gShutdown = true;
|
if (PR_AtomicSet(&gShutdown, 1)) {
|
||||||
|
NS_ERROR("Shutdown more than once?!");
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure to join with our IO thread.
|
// Make sure to join with our IO thread.
|
||||||
if (NS_FAILED(mIOThread->Shutdown())) {
|
if (NS_FAILED(mIOThread->Shutdown())) {
|
||||||
|
|
|
@ -80,6 +80,14 @@ public:
|
||||||
nsresult WaitForClearAndDispatch(const nsACString& aOrigin,
|
nsresult WaitForClearAndDispatch(const nsACString& aOrigin,
|
||||||
nsIRunnable* aRunnable);
|
nsIRunnable* aRunnable);
|
||||||
|
|
||||||
|
nsIThread* IOThread()
|
||||||
|
{
|
||||||
|
NS_ASSERTION(mIOThread, "This should never be null!");
|
||||||
|
return mIOThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsShuttingDown();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IndexedDatabaseManager();
|
IndexedDatabaseManager();
|
||||||
~IndexedDatabaseManager();
|
~IndexedDatabaseManager();
|
||||||
|
|
|
@ -64,6 +64,7 @@ USING_INDEXEDDB_NAMESPACE
|
||||||
using mozilla::MutexAutoLock;
|
using mozilla::MutexAutoLock;
|
||||||
|
|
||||||
LazyIdleThread::LazyIdleThread(PRUint32 aIdleTimeoutMS,
|
LazyIdleThread::LazyIdleThread(PRUint32 aIdleTimeoutMS,
|
||||||
|
ShutdownMethod aShutdownMethod,
|
||||||
nsIObserver* aIdleObserver)
|
nsIObserver* aIdleObserver)
|
||||||
: mMutex("LazyIdleThread::mMutex"),
|
: mMutex("LazyIdleThread::mMutex"),
|
||||||
mOwningThread(NS_GetCurrentThread()),
|
mOwningThread(NS_GetCurrentThread()),
|
||||||
|
@ -71,6 +72,7 @@ LazyIdleThread::LazyIdleThread(PRUint32 aIdleTimeoutMS,
|
||||||
mIdleTimeoutMS(aIdleTimeoutMS),
|
mIdleTimeoutMS(aIdleTimeoutMS),
|
||||||
mPendingEventCount(0),
|
mPendingEventCount(0),
|
||||||
mIdleNotificationCount(0),
|
mIdleNotificationCount(0),
|
||||||
|
mShutdownMethod(aShutdownMethod),
|
||||||
mShutdown(PR_FALSE),
|
mShutdown(PR_FALSE),
|
||||||
mThreadIsShuttingDown(PR_FALSE),
|
mThreadIsShuttingDown(PR_FALSE),
|
||||||
mIdleTimeoutEnabled(PR_TRUE)
|
mIdleTimeoutEnabled(PR_TRUE)
|
||||||
|
@ -172,7 +174,7 @@ LazyIdleThread::EnsureThread()
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
if (NS_IsMainThread()) {
|
if (mShutdownMethod == AutomaticShutdown && NS_IsMainThread()) {
|
||||||
nsCOMPtr<nsIObserverService> obs =
|
nsCOMPtr<nsIObserverService> obs =
|
||||||
do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv);
|
do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
@ -257,7 +259,7 @@ LazyIdleThread::ShutdownThread()
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
if (mThread) {
|
if (mThread) {
|
||||||
if (NS_IsMainThread()) {
|
if (mShutdownMethod == AutomaticShutdown && NS_IsMainThread()) {
|
||||||
nsCOMPtr<nsIObserverService> obs =
|
nsCOMPtr<nsIObserverService> obs =
|
||||||
do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
|
do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
|
||||||
NS_WARN_IF_FALSE(obs, "Failed to get observer service!");
|
NS_WARN_IF_FALSE(obs, "Failed to get observer service!");
|
||||||
|
@ -504,8 +506,10 @@ LazyIdleThread::Observe(nsISupports* /* aSubject */,
|
||||||
const PRUnichar* /* aData */)
|
const PRUnichar* /* aData */)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
NS_ENSURE_FALSE(strcmp("xpcom-shutdown-threads", aTopic),
|
NS_ASSERTION(mShutdownMethod == AutomaticShutdown,
|
||||||
NS_ERROR_UNEXPECTED);
|
"Should not receive notifications if not AutomaticShutdown!");
|
||||||
|
NS_ASSERTION(!strcmp("xpcom-shutdown-threads", aTopic), "Bad topic!");
|
||||||
|
|
||||||
Shutdown();
|
Shutdown();
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,11 +72,17 @@ public:
|
||||||
NS_DECL_NSITHREADOBSERVER
|
NS_DECL_NSITHREADOBSERVER
|
||||||
NS_DECL_NSIOBSERVER
|
NS_DECL_NSIOBSERVER
|
||||||
|
|
||||||
|
enum ShutdownMethod {
|
||||||
|
AutomaticShutdown = 0,
|
||||||
|
ManualShutdown
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new LazyIdleThread that will destroy its thread after the given
|
* Create a new LazyIdleThread that will destroy its thread after the given
|
||||||
* number of milliseconds.
|
* number of milliseconds.
|
||||||
*/
|
*/
|
||||||
LazyIdleThread(PRUint32 aIdleTimeoutMS,
|
LazyIdleThread(PRUint32 aIdleTimeoutMS,
|
||||||
|
ShutdownMethod aShutdownMethod = AutomaticShutdown,
|
||||||
nsIObserver* aIdleObserver = nsnull);
|
nsIObserver* aIdleObserver = nsnull);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -191,6 +197,13 @@ private:
|
||||||
*/
|
*/
|
||||||
PRUint32 mIdleNotificationCount;
|
PRUint32 mIdleNotificationCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not the thread should automatically shutdown. If the owner
|
||||||
|
* specified ManualShutdown at construction time then the owner should take
|
||||||
|
* care to call Shutdown() manually when appropriate.
|
||||||
|
*/
|
||||||
|
ShutdownMethod mShutdownMethod;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Only accessed on the owning thread. Set to true when Shutdown() has been
|
* Only accessed on the owning thread. Set to true when Shutdown() has been
|
||||||
* called and prevents EnsureThread() from recreating mThread.
|
* called and prevents EnsureThread() from recreating mThread.
|
||||||
|
|
Загрузка…
Ссылка в новой задаче