Wed, 31 Dec 2014 06:55:50 +0100
Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_indexeddb_transactionthreadpool_h__
8 #define mozilla_dom_indexeddb_transactionthreadpool_h__
10 // Only meant to be included in IndexedDB source files, not exported.
11 #include "IndexedDatabase.h"
13 #include "nsIObserver.h"
14 #include "nsIRunnable.h"
16 #include "mozilla/Monitor.h"
17 #include "nsClassHashtable.h"
18 #include "nsHashKeys.h"
20 #include "IDBTransaction.h"
22 class nsIThreadPool;
24 BEGIN_INDEXEDDB_NAMESPACE
26 class FinishTransactionRunnable;
27 class QueuedDispatchInfo;
29 class TransactionThreadPool
30 {
31 friend class nsAutoPtr<TransactionThreadPool>;
32 friend class FinishTransactionRunnable;
34 public:
35 // returns a non-owning ref!
36 static TransactionThreadPool* GetOrCreate();
38 // returns a non-owning ref!
39 static TransactionThreadPool* Get();
41 static void Shutdown();
43 nsresult Dispatch(IDBTransaction* aTransaction,
44 nsIRunnable* aRunnable,
45 bool aFinish,
46 nsIRunnable* aFinishRunnable);
48 void WaitForDatabasesToComplete(nsTArray<nsRefPtr<IDBDatabase> >& aDatabases,
49 nsIRunnable* aCallback);
51 // Abort all transactions, unless they are already in the process of being
52 // committed, for aDatabase.
53 void AbortTransactionsForDatabase(IDBDatabase* aDatabase);
55 // Returns true if there are running or pending transactions for aDatabase.
56 bool HasTransactionsForDatabase(IDBDatabase* aDatabase);
58 protected:
59 class TransactionQueue MOZ_FINAL : public nsIRunnable
60 {
61 public:
62 NS_DECL_THREADSAFE_ISUPPORTS
63 NS_DECL_NSIRUNNABLE
65 TransactionQueue(IDBTransaction* aTransaction);
67 void Unblock();
69 void Dispatch(nsIRunnable* aRunnable);
71 void Finish(nsIRunnable* aFinishRunnable);
73 private:
74 mozilla::Monitor mMonitor;
75 IDBTransaction* mTransaction;
76 nsAutoTArray<nsCOMPtr<nsIRunnable>, 10> mQueue;
77 nsCOMPtr<nsIRunnable> mFinishRunnable;
78 bool mShouldFinish;
79 };
81 friend class TransactionQueue;
83 struct TransactionInfo
84 {
85 TransactionInfo(IDBTransaction* aTransaction)
86 {
87 MOZ_COUNT_CTOR(TransactionInfo);
89 transaction = aTransaction;
90 queue = new TransactionQueue(aTransaction);
91 }
93 ~TransactionInfo()
94 {
95 MOZ_COUNT_DTOR(TransactionInfo);
96 }
98 nsRefPtr<IDBTransaction> transaction;
99 nsRefPtr<TransactionQueue> queue;
100 nsTHashtable<nsPtrHashKey<TransactionInfo> > blockedOn;
101 nsTHashtable<nsPtrHashKey<TransactionInfo> > blocking;
102 };
104 struct TransactionInfoPair
105 {
106 TransactionInfoPair()
107 : lastBlockingReads(nullptr)
108 {
109 MOZ_COUNT_CTOR(TransactionInfoPair);
110 }
112 ~TransactionInfoPair()
113 {
114 MOZ_COUNT_DTOR(TransactionInfoPair);
115 }
116 // Multiple reading transactions can block future writes.
117 nsTArray<TransactionInfo*> lastBlockingWrites;
118 // But only a single writing transaction can block future reads.
119 TransactionInfo* lastBlockingReads;
120 };
122 struct DatabaseTransactionInfo
123 {
124 DatabaseTransactionInfo()
125 {
126 MOZ_COUNT_CTOR(DatabaseTransactionInfo);
127 }
129 ~DatabaseTransactionInfo()
130 {
131 MOZ_COUNT_DTOR(DatabaseTransactionInfo);
132 }
134 typedef nsClassHashtable<nsPtrHashKey<IDBTransaction>, TransactionInfo >
135 TransactionHashtable;
136 TransactionHashtable transactions;
137 nsClassHashtable<nsStringHashKey, TransactionInfoPair> blockingTransactions;
138 };
140 static PLDHashOperator
141 CollectTransactions(IDBTransaction* aKey,
142 TransactionInfo* aValue,
143 void* aUserArg);
145 static PLDHashOperator
146 FindTransaction(IDBTransaction* aKey,
147 TransactionInfo* aValue,
148 void* aUserArg);
150 static PLDHashOperator
151 MaybeUnblockTransaction(nsPtrHashKey<TransactionInfo>* aKey,
152 void* aUserArg);
154 struct DatabasesCompleteCallback
155 {
156 nsTArray<nsRefPtr<IDBDatabase> > mDatabases;
157 nsCOMPtr<nsIRunnable> mCallback;
158 };
160 TransactionThreadPool();
161 ~TransactionThreadPool();
163 nsresult Init();
164 nsresult Cleanup();
166 void FinishTransaction(IDBTransaction* aTransaction);
168 TransactionQueue& GetQueueForTransaction(IDBTransaction* aTransaction);
170 bool MaybeFireCallback(DatabasesCompleteCallback aCallback);
172 nsCOMPtr<nsIThreadPool> mThreadPool;
174 nsClassHashtable<nsCStringHashKey, DatabaseTransactionInfo>
175 mTransactionsInProgress;
177 nsTArray<DatabasesCompleteCallback> mCompleteCallbacks;
178 };
180 END_INDEXEDDB_NAMESPACE
182 #endif // mozilla_dom_indexeddb_transactionthreadpool_h__