2010-06-23 12:46:08 -07:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=2 et sw=2 tw=80: */
|
2012-05-21 04:12:37 -07:00
|
|
|
/* 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/. */
|
2010-06-23 12:46:08 -07:00
|
|
|
|
|
|
|
#ifndef mozilla_dom_indexeddb_transactionthreadpool_h__
|
|
|
|
#define mozilla_dom_indexeddb_transactionthreadpool_h__
|
|
|
|
|
|
|
|
// Only meant to be included in IndexedDB source files, not exported.
|
|
|
|
#include "IndexedDatabase.h"
|
|
|
|
|
|
|
|
#include "nsIObserver.h"
|
2010-10-19 10:58:33 -07:00
|
|
|
#include "nsIRunnable.h"
|
2010-06-23 12:46:08 -07:00
|
|
|
|
2011-11-18 07:21:04 -08:00
|
|
|
#include "mozilla/Monitor.h"
|
2010-06-23 12:46:08 -07:00
|
|
|
#include "nsClassHashtable.h"
|
|
|
|
#include "nsHashKeys.h"
|
|
|
|
#include "nsRefPtrHashtable.h"
|
|
|
|
|
2010-06-28 09:46:21 -07:00
|
|
|
#include "IDBTransaction.h"
|
2010-06-23 12:46:08 -07:00
|
|
|
|
|
|
|
class nsIThreadPool;
|
|
|
|
|
|
|
|
BEGIN_INDEXEDDB_NAMESPACE
|
|
|
|
|
|
|
|
class FinishTransactionRunnable;
|
|
|
|
class QueuedDispatchInfo;
|
|
|
|
|
2010-10-19 10:58:33 -07:00
|
|
|
class TransactionThreadPool
|
2010-06-23 12:46:08 -07:00
|
|
|
{
|
2010-10-19 10:58:33 -07:00
|
|
|
friend class nsAutoPtr<TransactionThreadPool>;
|
2010-06-23 12:46:08 -07:00
|
|
|
friend class FinishTransactionRunnable;
|
|
|
|
|
|
|
|
public:
|
|
|
|
// returns a non-owning ref!
|
|
|
|
static TransactionThreadPool* GetOrCreate();
|
2010-10-19 10:58:33 -07:00
|
|
|
|
|
|
|
// returns a non-owning ref!
|
2010-09-10 12:12:11 -07:00
|
|
|
static TransactionThreadPool* Get();
|
2010-10-19 10:58:33 -07:00
|
|
|
|
2010-06-23 12:46:08 -07:00
|
|
|
static void Shutdown();
|
|
|
|
|
2010-06-28 09:46:21 -07:00
|
|
|
nsresult Dispatch(IDBTransaction* aTransaction,
|
2010-06-23 12:46:08 -07:00
|
|
|
nsIRunnable* aRunnable,
|
|
|
|
bool aFinish,
|
|
|
|
nsIRunnable* aFinishRunnable);
|
|
|
|
|
2012-08-10 09:15:02 -07:00
|
|
|
bool WaitForAllDatabasesToComplete(nsTArray<IDBDatabase*>& aDatabases,
|
|
|
|
nsIRunnable* aCallback);
|
2010-09-10 12:12:11 -07:00
|
|
|
|
2011-01-27 13:47:36 -08:00
|
|
|
// Abort all transactions, unless they are already in the process of being
|
|
|
|
// committed, for aDatabase.
|
|
|
|
void AbortTransactionsForDatabase(IDBDatabase* aDatabase);
|
|
|
|
|
2011-12-15 23:34:24 -08:00
|
|
|
// Returns true if there are running or pending transactions for aDatabase.
|
2011-01-27 13:47:36 -08:00
|
|
|
bool HasTransactionsForDatabase(IDBDatabase* aDatabase);
|
|
|
|
|
2010-06-23 12:46:08 -07:00
|
|
|
protected:
|
2012-05-14 21:50:29 -07:00
|
|
|
class TransactionQueue MOZ_FINAL : public nsIRunnable
|
2010-06-23 12:46:08 -07:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
NS_DECL_NSIRUNNABLE
|
|
|
|
|
2013-02-05 09:01:07 -08:00
|
|
|
TransactionQueue(IDBTransaction* aTransaction);
|
2010-06-23 12:46:08 -07:00
|
|
|
|
2013-02-05 09:01:07 -08:00
|
|
|
void Unblock();
|
2010-06-23 12:46:08 -07:00
|
|
|
|
2013-02-05 09:01:07 -08:00
|
|
|
void Dispatch(nsIRunnable* aRunnable);
|
|
|
|
|
|
|
|
void Finish(nsIRunnable* aFinishRunnable);
|
2010-06-23 12:46:08 -07:00
|
|
|
|
|
|
|
private:
|
2011-11-18 07:21:04 -08:00
|
|
|
mozilla::Monitor mMonitor;
|
2010-06-28 09:46:21 -07:00
|
|
|
IDBTransaction* mTransaction;
|
2010-06-23 12:46:08 -07:00
|
|
|
nsAutoTArray<nsCOMPtr<nsIRunnable>, 10> mQueue;
|
|
|
|
nsCOMPtr<nsIRunnable> mFinishRunnable;
|
|
|
|
bool mShouldFinish;
|
|
|
|
};
|
|
|
|
|
2013-02-05 09:01:07 -08:00
|
|
|
friend class TransactionQueue;
|
|
|
|
|
2010-06-23 12:46:08 -07:00
|
|
|
struct TransactionInfo
|
|
|
|
{
|
2013-02-05 09:01:07 -08:00
|
|
|
TransactionInfo(IDBTransaction* aTransaction,
|
|
|
|
const nsTArray<nsString>& aObjectStoreNames)
|
|
|
|
{
|
|
|
|
MOZ_COUNT_CTOR(TransactionInfo);
|
|
|
|
|
|
|
|
blockedOn.Init();
|
|
|
|
blocking.Init();
|
|
|
|
|
|
|
|
transaction = aTransaction;
|
|
|
|
queue = new TransactionQueue(aTransaction);
|
|
|
|
objectStoreNames.AppendElements(aObjectStoreNames);
|
|
|
|
}
|
|
|
|
|
|
|
|
~TransactionInfo()
|
|
|
|
{
|
|
|
|
MOZ_COUNT_DTOR(TransactionInfo);
|
|
|
|
}
|
|
|
|
|
2010-06-28 09:46:21 -07:00
|
|
|
nsRefPtr<IDBTransaction> transaction;
|
2010-06-23 12:46:08 -07:00
|
|
|
nsRefPtr<TransactionQueue> queue;
|
2010-07-12 07:05:01 -07:00
|
|
|
nsTArray<nsString> objectStoreNames;
|
2013-02-05 09:01:07 -08:00
|
|
|
nsTHashtable<nsPtrHashKey<TransactionInfo> > blockedOn;
|
|
|
|
nsTHashtable<nsPtrHashKey<TransactionInfo> > blocking;
|
2010-06-23 12:46:08 -07:00
|
|
|
};
|
|
|
|
|
2013-02-05 09:01:07 -08:00
|
|
|
struct TransactionInfoPair
|
2010-06-23 12:46:08 -07:00
|
|
|
{
|
2013-02-05 09:01:07 -08:00
|
|
|
TransactionInfoPair()
|
|
|
|
: lastBlockingReads(nullptr)
|
|
|
|
{
|
|
|
|
MOZ_COUNT_CTOR(TransactionInfoPair);
|
|
|
|
}
|
|
|
|
|
|
|
|
~TransactionInfoPair()
|
|
|
|
{
|
|
|
|
MOZ_COUNT_DTOR(TransactionInfoPair);
|
|
|
|
}
|
|
|
|
// Multiple reading transactions can block future writes.
|
|
|
|
nsTArray<TransactionInfo*> lastBlockingWrites;
|
|
|
|
// But only a single writing transaction can block future reads.
|
|
|
|
TransactionInfo* lastBlockingReads;
|
2010-07-12 07:05:01 -07:00
|
|
|
};
|
|
|
|
|
2013-02-05 09:01:07 -08:00
|
|
|
struct DatabaseTransactionInfo
|
2010-07-12 07:05:01 -07:00
|
|
|
{
|
2013-02-05 09:01:07 -08:00
|
|
|
DatabaseTransactionInfo()
|
|
|
|
{
|
|
|
|
MOZ_COUNT_CTOR(DatabaseTransactionInfo);
|
|
|
|
|
|
|
|
transactions.Init();
|
|
|
|
blockingTransactions.Init();
|
|
|
|
}
|
|
|
|
|
|
|
|
~DatabaseTransactionInfo()
|
|
|
|
{
|
|
|
|
MOZ_COUNT_DTOR(DatabaseTransactionInfo);
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef nsClassHashtable<nsPtrHashKey<IDBTransaction>, TransactionInfo >
|
|
|
|
TransactionHashtable;
|
|
|
|
TransactionHashtable transactions;
|
|
|
|
nsClassHashtable<nsStringHashKey, TransactionInfoPair> blockingTransactions;
|
2010-06-23 12:46:08 -07:00
|
|
|
};
|
|
|
|
|
2013-02-05 09:01:07 -08:00
|
|
|
static PLDHashOperator
|
|
|
|
CollectTransactions(IDBTransaction* aKey,
|
|
|
|
TransactionInfo* aValue,
|
|
|
|
void* aUserArg);
|
|
|
|
|
|
|
|
static PLDHashOperator
|
|
|
|
FindTransaction(IDBTransaction* aKey,
|
|
|
|
TransactionInfo* aValue,
|
|
|
|
void* aUserArg);
|
|
|
|
|
|
|
|
static PLDHashOperator
|
|
|
|
MaybeUnblockTransaction(nsPtrHashKey<TransactionInfo>* aKey,
|
|
|
|
void* aUserArg);
|
|
|
|
|
2010-10-19 10:58:52 -07:00
|
|
|
struct DatabasesCompleteCallback
|
2010-10-19 10:58:33 -07:00
|
|
|
{
|
2012-08-10 09:15:02 -07:00
|
|
|
nsTArray<IDBDatabase*> mDatabases;
|
2010-10-19 10:58:52 -07:00
|
|
|
nsCOMPtr<nsIRunnable> mCallback;
|
2010-10-19 10:58:33 -07:00
|
|
|
};
|
|
|
|
|
2010-06-23 12:46:08 -07:00
|
|
|
TransactionThreadPool();
|
|
|
|
~TransactionThreadPool();
|
|
|
|
|
|
|
|
nsresult Init();
|
|
|
|
nsresult Cleanup();
|
|
|
|
|
2010-06-28 09:46:21 -07:00
|
|
|
void FinishTransaction(IDBTransaction* aTransaction);
|
2010-06-23 12:46:08 -07:00
|
|
|
|
2013-02-05 09:01:07 -08:00
|
|
|
TransactionQueue& GetQueueForTransaction(IDBTransaction* aTransaction);
|
2010-06-23 12:46:08 -07:00
|
|
|
|
2012-06-03 09:33:52 -07:00
|
|
|
bool MaybeFireCallback(DatabasesCompleteCallback& aCallback);
|
2010-10-19 10:58:52 -07:00
|
|
|
|
2010-06-23 12:46:08 -07:00
|
|
|
nsCOMPtr<nsIThreadPool> mThreadPool;
|
|
|
|
|
2011-11-02 05:53:12 -07:00
|
|
|
nsClassHashtable<nsISupportsHashKey, DatabaseTransactionInfo>
|
2010-06-23 12:46:08 -07:00
|
|
|
mTransactionsInProgress;
|
|
|
|
|
2010-10-19 10:58:52 -07:00
|
|
|
nsTArray<DatabasesCompleteCallback> mCompleteCallbacks;
|
2010-06-23 12:46:08 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
END_INDEXEDDB_NAMESPACE
|
|
|
|
|
|
|
|
#endif // mozilla_dom_indexeddb_transactionthreadpool_h__
|