|
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_asyncconnectionhelper_h__ |
|
8 #define mozilla_dom_indexeddb_asyncconnectionhelper_h__ |
|
9 |
|
10 // Only meant to be included in IndexedDB source files, not exported. |
|
11 #include "DatabaseInfo.h" |
|
12 #include "IndexedDatabase.h" |
|
13 #include "IDBDatabase.h" |
|
14 #include "IDBRequest.h" |
|
15 |
|
16 #include "mozIStorageProgressHandler.h" |
|
17 #include "nsIEventTarget.h" |
|
18 #include "nsIRunnable.h" |
|
19 |
|
20 class mozIStorageConnection; |
|
21 |
|
22 BEGIN_INDEXEDDB_NAMESPACE |
|
23 |
|
24 class AutoSetCurrentTransaction; |
|
25 class IDBTransaction; |
|
26 |
|
27 namespace ipc { |
|
28 class ResponseValue; |
|
29 } |
|
30 |
|
31 // A common base class for AsyncConnectionHelper and OpenDatabaseHelper that |
|
32 // IDBRequest can use. |
|
33 class HelperBase : public nsIRunnable |
|
34 { |
|
35 friend class IDBRequest; |
|
36 |
|
37 public: |
|
38 |
|
39 virtual nsresult GetResultCode() = 0; |
|
40 |
|
41 virtual nsresult GetSuccessResult(JSContext* aCx, |
|
42 JS::MutableHandle<JS::Value> aVal) = 0; |
|
43 |
|
44 IDBRequest* GetRequest() const |
|
45 { |
|
46 return mRequest; |
|
47 } |
|
48 |
|
49 protected: |
|
50 HelperBase(IDBRequest* aRequest) |
|
51 : mRequest(aRequest) |
|
52 { } |
|
53 |
|
54 virtual ~HelperBase(); |
|
55 |
|
56 /** |
|
57 * Helper to wrap a native into a jsval. Uses the global object of the request |
|
58 * to parent the native. |
|
59 */ |
|
60 nsresult WrapNative(JSContext* aCx, |
|
61 nsISupports* aNative, |
|
62 JS::MutableHandle<JS::Value> aResult); |
|
63 |
|
64 /** |
|
65 * Gives the subclass a chance to release any objects that must be released |
|
66 * on the main thread, regardless of success or failure. Subclasses that |
|
67 * implement this method *MUST* call the base class implementation as well. |
|
68 */ |
|
69 virtual void ReleaseMainThreadObjects(); |
|
70 |
|
71 nsRefPtr<IDBRequest> mRequest; |
|
72 }; |
|
73 |
|
74 /** |
|
75 * Must be subclassed. The subclass must implement DoDatabaseWork. It may then |
|
76 * choose to implement OnSuccess and OnError depending on the needs of the |
|
77 * subclass. If the default implementation of OnSuccess is desired then the |
|
78 * subclass can implement GetSuccessResult to properly set the result of the |
|
79 * success event. Call Dispatch to start the database operation. Must be created |
|
80 * and Dispatched from the main thread only. Target thread may not be the main |
|
81 * thread. |
|
82 */ |
|
83 class AsyncConnectionHelper : public HelperBase, |
|
84 public mozIStorageProgressHandler |
|
85 { |
|
86 friend class AutoSetCurrentTransaction; |
|
87 |
|
88 public: |
|
89 typedef ipc::ResponseValue ResponseValue; |
|
90 |
|
91 NS_DECL_THREADSAFE_ISUPPORTS |
|
92 NS_DECL_NSIRUNNABLE |
|
93 NS_DECL_MOZISTORAGEPROGRESSHANDLER |
|
94 |
|
95 virtual nsresult Dispatch(nsIEventTarget* aDatabaseThread); |
|
96 |
|
97 // Only for transactions! |
|
98 nsresult DispatchToTransactionPool(); |
|
99 |
|
100 void SetError(nsresult aErrorCode) |
|
101 { |
|
102 NS_ASSERTION(NS_FAILED(aErrorCode), "Not a failure code!"); |
|
103 mResultCode = aErrorCode; |
|
104 } |
|
105 |
|
106 static IDBTransaction* GetCurrentTransaction(); |
|
107 |
|
108 bool HasTransaction() const |
|
109 { |
|
110 return !!mTransaction; |
|
111 } |
|
112 |
|
113 IDBTransaction* GetTransaction() const |
|
114 { |
|
115 return mTransaction; |
|
116 } |
|
117 |
|
118 virtual nsresult GetResultCode() MOZ_OVERRIDE |
|
119 { |
|
120 return mResultCode; |
|
121 } |
|
122 |
|
123 enum ChildProcessSendResult |
|
124 { |
|
125 // The result was successfully sent to the child process |
|
126 Success_Sent = 0, |
|
127 |
|
128 // The result was not sent, because this is not an out-of-process request. |
|
129 Success_NotSent, |
|
130 |
|
131 // The result was not sent, because the actor has been disconnected |
|
132 // (if the child process has shut down or crashed). |
|
133 Success_ActorDisconnected, |
|
134 |
|
135 // An error occurred. |
|
136 Error |
|
137 }; |
|
138 |
|
139 ChildProcessSendResult |
|
140 MaybeSendResponseToChildProcess(nsresult aResultCode); |
|
141 |
|
142 virtual nsresult OnParentProcessRequestComplete( |
|
143 const ResponseValue& aResponseValue); |
|
144 |
|
145 virtual nsresult |
|
146 UnpackResponseFromParentProcess(const ResponseValue& aResponseValue) = 0; |
|
147 |
|
148 protected: |
|
149 AsyncConnectionHelper(IDBDatabase* aDatabase, |
|
150 IDBRequest* aRequest); |
|
151 |
|
152 AsyncConnectionHelper(IDBTransaction* aTransaction, |
|
153 IDBRequest* aRequest); |
|
154 |
|
155 virtual ~AsyncConnectionHelper(); |
|
156 |
|
157 /** |
|
158 * This is called on the main thread after Dispatch is called but before the |
|
159 * runnable is actually dispatched to the database thread. Allows the subclass |
|
160 * to initialize itself. |
|
161 */ |
|
162 virtual nsresult Init(); |
|
163 |
|
164 /** |
|
165 * This callback is run on the database thread. |
|
166 */ |
|
167 virtual nsresult DoDatabaseWork(mozIStorageConnection* aConnection) = 0; |
|
168 |
|
169 /** |
|
170 * This function returns the event to be dispatched at the request when |
|
171 * OnSuccess is called. A subclass can override this to fire an event other |
|
172 * than "success" at the request. |
|
173 */ |
|
174 virtual already_AddRefed<nsIDOMEvent> CreateSuccessEvent( |
|
175 mozilla::dom::EventTarget* aOwner); |
|
176 |
|
177 /** |
|
178 * This callback is run on the main thread if DoDatabaseWork returned NS_OK. |
|
179 * The default implementation fires a "success" DOM event with its target set |
|
180 * to the request. Returning anything other than NS_OK from the OnSuccess |
|
181 * callback will trigger the OnError callback. |
|
182 */ |
|
183 virtual nsresult OnSuccess(); |
|
184 |
|
185 /** |
|
186 * This callback is run on the main thread if DoDatabaseWork or OnSuccess |
|
187 * returned an error code. The default implementation fires an "error" DOM |
|
188 * event with its target set to the request. |
|
189 */ |
|
190 virtual void OnError(); |
|
191 |
|
192 /** |
|
193 * This function is called by the request on the main thread when script |
|
194 * accesses the result property of the request. |
|
195 */ |
|
196 virtual nsresult GetSuccessResult(JSContext* aCx, |
|
197 JS::MutableHandle<JS::Value> aVal) MOZ_OVERRIDE; |
|
198 |
|
199 /** |
|
200 * Gives the subclass a chance to release any objects that must be released |
|
201 * on the main thread, regardless of success or failure. Subclasses that |
|
202 * implement this method *MUST* call the base class implementation as well. |
|
203 */ |
|
204 virtual void ReleaseMainThreadObjects() MOZ_OVERRIDE; |
|
205 |
|
206 /** |
|
207 * Helper to make a JS array object out of an array of clone buffers. |
|
208 */ |
|
209 static nsresult ConvertToArrayAndCleanup( |
|
210 JSContext* aCx, |
|
211 nsTArray<StructuredCloneReadInfo>& aReadInfos, |
|
212 JS::MutableHandle<JS::Value> aResult); |
|
213 |
|
214 /** |
|
215 * This should only be called by AutoSetCurrentTransaction. |
|
216 */ |
|
217 static void SetCurrentTransaction(IDBTransaction* aTransaction); |
|
218 |
|
219 /** |
|
220 * Allows the subclass to send its results to the child process. Will only |
|
221 * be called if all of the IPC infrastructure is available (there is an |
|
222 * actor, the child is stil alive and hasn't begun shutting down). |
|
223 */ |
|
224 virtual ChildProcessSendResult |
|
225 SendResponseToChildProcess(nsresult aResultCode) = 0; |
|
226 |
|
227 protected: |
|
228 nsRefPtr<IDBDatabase> mDatabase; |
|
229 nsRefPtr<IDBTransaction> mTransaction; |
|
230 |
|
231 private: |
|
232 nsCOMPtr<mozIStorageProgressHandler> mOldProgressHandler; |
|
233 nsresult mResultCode; |
|
234 bool mDispatched; |
|
235 }; |
|
236 |
|
237 class MOZ_STACK_CLASS StackBasedEventTarget : public nsIEventTarget |
|
238 { |
|
239 public: |
|
240 NS_DECL_ISUPPORTS_INHERITED |
|
241 }; |
|
242 |
|
243 class MOZ_STACK_CLASS ImmediateRunEventTarget : public StackBasedEventTarget |
|
244 { |
|
245 public: |
|
246 NS_DECL_NSIEVENTTARGET |
|
247 }; |
|
248 |
|
249 class MOZ_STACK_CLASS NoDispatchEventTarget : public StackBasedEventTarget |
|
250 { |
|
251 public: |
|
252 NS_DECL_NSIEVENTTARGET |
|
253 }; |
|
254 |
|
255 END_INDEXEDDB_NAMESPACE |
|
256 |
|
257 #endif // mozilla_dom_indexeddb_asyncconnectionhelper_h__ |