Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
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 mozStorageAsyncStatementExecution_h
8 #define mozStorageAsyncStatementExecution_h
10 #include "nscore.h"
11 #include "nsTArray.h"
12 #include "nsAutoPtr.h"
13 #include "mozilla/Mutex.h"
14 #include "mozilla/TimeStamp.h"
15 #include "mozilla/Attributes.h"
16 #include "nsIRunnable.h"
18 #include "SQLiteMutex.h"
19 #include "mozIStoragePendingStatement.h"
20 #include "mozIStorageStatementCallback.h"
21 #include "mozStorageHelper.h"
23 struct sqlite3_stmt;
25 namespace mozilla {
26 namespace storage {
28 class Connection;
29 class ResultSet;
30 class StatementData;
32 class AsyncExecuteStatements MOZ_FINAL : public nsIRunnable
33 , public mozIStoragePendingStatement
34 {
35 public:
36 NS_DECL_THREADSAFE_ISUPPORTS
37 NS_DECL_NSIRUNNABLE
38 NS_DECL_MOZISTORAGEPENDINGSTATEMENT
40 /**
41 * Describes the state of execution.
42 */
43 enum ExecutionState {
44 PENDING = -1,
45 COMPLETED = mozIStorageStatementCallback::REASON_FINISHED,
46 CANCELED = mozIStorageStatementCallback::REASON_CANCELED,
47 ERROR = mozIStorageStatementCallback::REASON_ERROR
48 };
50 typedef nsTArray<StatementData> StatementDataArray;
52 /**
53 * Executes a statement in the background, and passes results back to the
54 * caller.
55 *
56 * @param aStatements
57 * The statements to execute and possibly bind in the background.
58 * Ownership is transfered from the caller.
59 * @param aConnection
60 * The connection that created the statements to execute.
61 * @param aNativeConnection
62 * The native Sqlite connection that created the statements to execute.
63 * @param aCallback
64 * The callback that is notified of results, completion, and errors.
65 * @param _stmt
66 * The handle to control the execution of the statements.
67 */
68 static nsresult execute(StatementDataArray &aStatements,
69 Connection *aConnection,
70 sqlite3 *aNativeConnection,
71 mozIStorageStatementCallback *aCallback,
72 mozIStoragePendingStatement **_stmt);
74 /**
75 * Indicates when events on the calling thread should run or not. Certain
76 * events posted back to the calling thread should call this see if they
77 * should run or not.
78 *
79 * @pre mMutex is not held
80 *
81 * @returns true if the event should notify still, false otherwise.
82 */
83 bool shouldNotify();
85 private:
86 AsyncExecuteStatements(StatementDataArray &aStatements,
87 Connection *aConnection,
88 sqlite3 *aNativeConnection,
89 mozIStorageStatementCallback *aCallback);
90 ~AsyncExecuteStatements();
92 /**
93 * Binds and then executes a given statement until completion, an error
94 * occurs, or we are canceled. If aLastStatement is true, we should set
95 * mState accordingly.
96 *
97 * @pre mMutex is not held
98 *
99 * @param aData
100 * The StatementData to bind, execute, and then process.
101 * @param aLastStatement
102 * Indicates if this is the last statement or not. If it is, we have
103 * to set the proper state.
104 * @returns true if we should continue to process statements, false otherwise.
105 */
106 bool bindExecuteAndProcessStatement(StatementData &aData,
107 bool aLastStatement);
109 /**
110 * Executes a given statement until completion, an error occurs, or we are
111 * canceled. If aLastStatement is true, we should set mState accordingly.
112 *
113 * @pre mMutex is not held
114 *
115 * @param aStatement
116 * The statement to execute and then process.
117 * @param aLastStatement
118 * Indicates if this is the last statement or not. If it is, we have
119 * to set the proper state.
120 * @returns true if we should continue to process statements, false otherwise.
121 */
122 bool executeAndProcessStatement(sqlite3_stmt *aStatement,
123 bool aLastStatement);
125 /**
126 * Executes a statement to completion, properly handling any error conditions.
127 *
128 * @pre mMutex is not held
129 *
130 * @param aStatement
131 * The statement to execute to completion.
132 * @returns true if results were obtained, false otherwise.
133 */
134 bool executeStatement(sqlite3_stmt *aStatement);
136 /**
137 * Builds a result set up with a row from a given statement. If we meet the
138 * right criteria, go ahead and notify about this results too.
139 *
140 * @pre mMutex is not held
141 *
142 * @param aStatement
143 * The statement to get the row data from.
144 */
145 nsresult buildAndNotifyResults(sqlite3_stmt *aStatement);
147 /**
148 * Notifies callback about completion, and does any necessary cleanup.
149 *
150 * @pre mMutex is not held
151 */
152 nsresult notifyComplete();
154 /**
155 * Notifies callback about an error.
156 *
157 * @pre mMutex is not held
158 * @pre mDBMutex is not held
159 *
160 * @param aErrorCode
161 * The error code defined in mozIStorageError for the error.
162 * @param aMessage
163 * The error string, if any.
164 * @param aError
165 * The error object to notify the caller with.
166 */
167 nsresult notifyError(int32_t aErrorCode, const char *aMessage);
168 nsresult notifyError(mozIStorageError *aError);
170 /**
171 * Notifies the callback about a result set.
172 *
173 * @pre mMutex is not held
174 */
175 nsresult notifyResults();
177 /**
178 * Tests whether the current statements should be wrapped in an explicit
179 * transaction.
180 *
181 * @return true if an explicit transaction is needed, false otherwise.
182 */
183 bool statementsNeedTransaction();
185 StatementDataArray mStatements;
186 nsRefPtr<Connection> mConnection;
187 sqlite3 *mNativeConnection;
188 bool mHasTransaction;
189 mozIStorageStatementCallback *mCallback;
190 nsCOMPtr<nsIThread> mCallingThread;
191 nsRefPtr<ResultSet> mResultSet;
193 /**
194 * The maximum amount of time we want to wait between results. Defined by
195 * MAX_MILLISECONDS_BETWEEN_RESULTS and set at construction.
196 */
197 const TimeDuration mMaxWait;
199 /**
200 * The start time since our last set of results.
201 */
202 TimeStamp mIntervalStart;
204 /**
205 * Indicates our state of execution.
206 */
207 ExecutionState mState;
209 /**
210 * Indicates if we should try to cancel at a cancelation point.
211 */
212 bool mCancelRequested;
214 /**
215 * This is the mutex that protects our state from changing between threads.
216 * This includes the following variables:
217 * - mCancelRequested is only set on the calling thread while the lock is
218 * held. It is always read from within the lock on the background thread,
219 * but not on the calling thread (see shouldNotify for why).
220 */
221 Mutex &mMutex;
223 /**
224 * The wrapped SQLite recursive connection mutex. We use it whenever we call
225 * sqlite3_step and care about having reliable error messages. By taking it
226 * prior to the call and holding it until the point where we no longer care
227 * about the error message, the user gets reliable error messages.
228 */
229 SQLiteMutex &mDBMutex;
231 /**
232 * The instant at which the request was started.
233 *
234 * Used by telemetry.
235 */
236 TimeStamp mRequestStartDate;
237 };
239 } // namespace storage
240 } // namespace mozilla
242 #endif // mozStorageAsyncStatementExecution_h