dom/indexedDB/TransactionThreadPool.h

changeset 2
7e26c7da4463
equal deleted inserted replaced
-1:000000000000 0:43a4ec85c5e4
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/. */
6
7 #ifndef mozilla_dom_indexeddb_transactionthreadpool_h__
8 #define mozilla_dom_indexeddb_transactionthreadpool_h__
9
10 // Only meant to be included in IndexedDB source files, not exported.
11 #include "IndexedDatabase.h"
12
13 #include "nsIObserver.h"
14 #include "nsIRunnable.h"
15
16 #include "mozilla/Monitor.h"
17 #include "nsClassHashtable.h"
18 #include "nsHashKeys.h"
19
20 #include "IDBTransaction.h"
21
22 class nsIThreadPool;
23
24 BEGIN_INDEXEDDB_NAMESPACE
25
26 class FinishTransactionRunnable;
27 class QueuedDispatchInfo;
28
29 class TransactionThreadPool
30 {
31 friend class nsAutoPtr<TransactionThreadPool>;
32 friend class FinishTransactionRunnable;
33
34 public:
35 // returns a non-owning ref!
36 static TransactionThreadPool* GetOrCreate();
37
38 // returns a non-owning ref!
39 static TransactionThreadPool* Get();
40
41 static void Shutdown();
42
43 nsresult Dispatch(IDBTransaction* aTransaction,
44 nsIRunnable* aRunnable,
45 bool aFinish,
46 nsIRunnable* aFinishRunnable);
47
48 void WaitForDatabasesToComplete(nsTArray<nsRefPtr<IDBDatabase> >& aDatabases,
49 nsIRunnable* aCallback);
50
51 // Abort all transactions, unless they are already in the process of being
52 // committed, for aDatabase.
53 void AbortTransactionsForDatabase(IDBDatabase* aDatabase);
54
55 // Returns true if there are running or pending transactions for aDatabase.
56 bool HasTransactionsForDatabase(IDBDatabase* aDatabase);
57
58 protected:
59 class TransactionQueue MOZ_FINAL : public nsIRunnable
60 {
61 public:
62 NS_DECL_THREADSAFE_ISUPPORTS
63 NS_DECL_NSIRUNNABLE
64
65 TransactionQueue(IDBTransaction* aTransaction);
66
67 void Unblock();
68
69 void Dispatch(nsIRunnable* aRunnable);
70
71 void Finish(nsIRunnable* aFinishRunnable);
72
73 private:
74 mozilla::Monitor mMonitor;
75 IDBTransaction* mTransaction;
76 nsAutoTArray<nsCOMPtr<nsIRunnable>, 10> mQueue;
77 nsCOMPtr<nsIRunnable> mFinishRunnable;
78 bool mShouldFinish;
79 };
80
81 friend class TransactionQueue;
82
83 struct TransactionInfo
84 {
85 TransactionInfo(IDBTransaction* aTransaction)
86 {
87 MOZ_COUNT_CTOR(TransactionInfo);
88
89 transaction = aTransaction;
90 queue = new TransactionQueue(aTransaction);
91 }
92
93 ~TransactionInfo()
94 {
95 MOZ_COUNT_DTOR(TransactionInfo);
96 }
97
98 nsRefPtr<IDBTransaction> transaction;
99 nsRefPtr<TransactionQueue> queue;
100 nsTHashtable<nsPtrHashKey<TransactionInfo> > blockedOn;
101 nsTHashtable<nsPtrHashKey<TransactionInfo> > blocking;
102 };
103
104 struct TransactionInfoPair
105 {
106 TransactionInfoPair()
107 : lastBlockingReads(nullptr)
108 {
109 MOZ_COUNT_CTOR(TransactionInfoPair);
110 }
111
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 };
121
122 struct DatabaseTransactionInfo
123 {
124 DatabaseTransactionInfo()
125 {
126 MOZ_COUNT_CTOR(DatabaseTransactionInfo);
127 }
128
129 ~DatabaseTransactionInfo()
130 {
131 MOZ_COUNT_DTOR(DatabaseTransactionInfo);
132 }
133
134 typedef nsClassHashtable<nsPtrHashKey<IDBTransaction>, TransactionInfo >
135 TransactionHashtable;
136 TransactionHashtable transactions;
137 nsClassHashtable<nsStringHashKey, TransactionInfoPair> blockingTransactions;
138 };
139
140 static PLDHashOperator
141 CollectTransactions(IDBTransaction* aKey,
142 TransactionInfo* aValue,
143 void* aUserArg);
144
145 static PLDHashOperator
146 FindTransaction(IDBTransaction* aKey,
147 TransactionInfo* aValue,
148 void* aUserArg);
149
150 static PLDHashOperator
151 MaybeUnblockTransaction(nsPtrHashKey<TransactionInfo>* aKey,
152 void* aUserArg);
153
154 struct DatabasesCompleteCallback
155 {
156 nsTArray<nsRefPtr<IDBDatabase> > mDatabases;
157 nsCOMPtr<nsIRunnable> mCallback;
158 };
159
160 TransactionThreadPool();
161 ~TransactionThreadPool();
162
163 nsresult Init();
164 nsresult Cleanup();
165
166 void FinishTransaction(IDBTransaction* aTransaction);
167
168 TransactionQueue& GetQueueForTransaction(IDBTransaction* aTransaction);
169
170 bool MaybeFireCallback(DatabasesCompleteCallback aCallback);
171
172 nsCOMPtr<nsIThreadPool> mThreadPool;
173
174 nsClassHashtable<nsCStringHashKey, DatabaseTransactionInfo>
175 mTransactionsInProgress;
176
177 nsTArray<DatabasesCompleteCallback> mCompleteCallbacks;
178 };
179
180 END_INDEXEDDB_NAMESPACE
181
182 #endif // mozilla_dom_indexeddb_transactionthreadpool_h__

mercurial