1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/indexedDB/AsyncConnectionHelper.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,257 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set ts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef mozilla_dom_indexeddb_asyncconnectionhelper_h__ 1.11 +#define mozilla_dom_indexeddb_asyncconnectionhelper_h__ 1.12 + 1.13 +// Only meant to be included in IndexedDB source files, not exported. 1.14 +#include "DatabaseInfo.h" 1.15 +#include "IndexedDatabase.h" 1.16 +#include "IDBDatabase.h" 1.17 +#include "IDBRequest.h" 1.18 + 1.19 +#include "mozIStorageProgressHandler.h" 1.20 +#include "nsIEventTarget.h" 1.21 +#include "nsIRunnable.h" 1.22 + 1.23 +class mozIStorageConnection; 1.24 + 1.25 +BEGIN_INDEXEDDB_NAMESPACE 1.26 + 1.27 +class AutoSetCurrentTransaction; 1.28 +class IDBTransaction; 1.29 + 1.30 +namespace ipc { 1.31 +class ResponseValue; 1.32 +} 1.33 + 1.34 +// A common base class for AsyncConnectionHelper and OpenDatabaseHelper that 1.35 +// IDBRequest can use. 1.36 +class HelperBase : public nsIRunnable 1.37 +{ 1.38 + friend class IDBRequest; 1.39 + 1.40 +public: 1.41 + 1.42 + virtual nsresult GetResultCode() = 0; 1.43 + 1.44 + virtual nsresult GetSuccessResult(JSContext* aCx, 1.45 + JS::MutableHandle<JS::Value> aVal) = 0; 1.46 + 1.47 + IDBRequest* GetRequest() const 1.48 + { 1.49 + return mRequest; 1.50 + } 1.51 + 1.52 +protected: 1.53 + HelperBase(IDBRequest* aRequest) 1.54 + : mRequest(aRequest) 1.55 + { } 1.56 + 1.57 + virtual ~HelperBase(); 1.58 + 1.59 + /** 1.60 + * Helper to wrap a native into a jsval. Uses the global object of the request 1.61 + * to parent the native. 1.62 + */ 1.63 + nsresult WrapNative(JSContext* aCx, 1.64 + nsISupports* aNative, 1.65 + JS::MutableHandle<JS::Value> aResult); 1.66 + 1.67 + /** 1.68 + * Gives the subclass a chance to release any objects that must be released 1.69 + * on the main thread, regardless of success or failure. Subclasses that 1.70 + * implement this method *MUST* call the base class implementation as well. 1.71 + */ 1.72 + virtual void ReleaseMainThreadObjects(); 1.73 + 1.74 + nsRefPtr<IDBRequest> mRequest; 1.75 +}; 1.76 + 1.77 +/** 1.78 + * Must be subclassed. The subclass must implement DoDatabaseWork. It may then 1.79 + * choose to implement OnSuccess and OnError depending on the needs of the 1.80 + * subclass. If the default implementation of OnSuccess is desired then the 1.81 + * subclass can implement GetSuccessResult to properly set the result of the 1.82 + * success event. Call Dispatch to start the database operation. Must be created 1.83 + * and Dispatched from the main thread only. Target thread may not be the main 1.84 + * thread. 1.85 + */ 1.86 +class AsyncConnectionHelper : public HelperBase, 1.87 + public mozIStorageProgressHandler 1.88 +{ 1.89 + friend class AutoSetCurrentTransaction; 1.90 + 1.91 +public: 1.92 + typedef ipc::ResponseValue ResponseValue; 1.93 + 1.94 + NS_DECL_THREADSAFE_ISUPPORTS 1.95 + NS_DECL_NSIRUNNABLE 1.96 + NS_DECL_MOZISTORAGEPROGRESSHANDLER 1.97 + 1.98 + virtual nsresult Dispatch(nsIEventTarget* aDatabaseThread); 1.99 + 1.100 + // Only for transactions! 1.101 + nsresult DispatchToTransactionPool(); 1.102 + 1.103 + void SetError(nsresult aErrorCode) 1.104 + { 1.105 + NS_ASSERTION(NS_FAILED(aErrorCode), "Not a failure code!"); 1.106 + mResultCode = aErrorCode; 1.107 + } 1.108 + 1.109 + static IDBTransaction* GetCurrentTransaction(); 1.110 + 1.111 + bool HasTransaction() const 1.112 + { 1.113 + return !!mTransaction; 1.114 + } 1.115 + 1.116 + IDBTransaction* GetTransaction() const 1.117 + { 1.118 + return mTransaction; 1.119 + } 1.120 + 1.121 + virtual nsresult GetResultCode() MOZ_OVERRIDE 1.122 + { 1.123 + return mResultCode; 1.124 + } 1.125 + 1.126 + enum ChildProcessSendResult 1.127 + { 1.128 + // The result was successfully sent to the child process 1.129 + Success_Sent = 0, 1.130 + 1.131 + // The result was not sent, because this is not an out-of-process request. 1.132 + Success_NotSent, 1.133 + 1.134 + // The result was not sent, because the actor has been disconnected 1.135 + // (if the child process has shut down or crashed). 1.136 + Success_ActorDisconnected, 1.137 + 1.138 + // An error occurred. 1.139 + Error 1.140 + }; 1.141 + 1.142 + ChildProcessSendResult 1.143 + MaybeSendResponseToChildProcess(nsresult aResultCode); 1.144 + 1.145 + virtual nsresult OnParentProcessRequestComplete( 1.146 + const ResponseValue& aResponseValue); 1.147 + 1.148 + virtual nsresult 1.149 + UnpackResponseFromParentProcess(const ResponseValue& aResponseValue) = 0; 1.150 + 1.151 +protected: 1.152 + AsyncConnectionHelper(IDBDatabase* aDatabase, 1.153 + IDBRequest* aRequest); 1.154 + 1.155 + AsyncConnectionHelper(IDBTransaction* aTransaction, 1.156 + IDBRequest* aRequest); 1.157 + 1.158 + virtual ~AsyncConnectionHelper(); 1.159 + 1.160 + /** 1.161 + * This is called on the main thread after Dispatch is called but before the 1.162 + * runnable is actually dispatched to the database thread. Allows the subclass 1.163 + * to initialize itself. 1.164 + */ 1.165 + virtual nsresult Init(); 1.166 + 1.167 + /** 1.168 + * This callback is run on the database thread. 1.169 + */ 1.170 + virtual nsresult DoDatabaseWork(mozIStorageConnection* aConnection) = 0; 1.171 + 1.172 + /** 1.173 + * This function returns the event to be dispatched at the request when 1.174 + * OnSuccess is called. A subclass can override this to fire an event other 1.175 + * than "success" at the request. 1.176 + */ 1.177 + virtual already_AddRefed<nsIDOMEvent> CreateSuccessEvent( 1.178 + mozilla::dom::EventTarget* aOwner); 1.179 + 1.180 + /** 1.181 + * This callback is run on the main thread if DoDatabaseWork returned NS_OK. 1.182 + * The default implementation fires a "success" DOM event with its target set 1.183 + * to the request. Returning anything other than NS_OK from the OnSuccess 1.184 + * callback will trigger the OnError callback. 1.185 + */ 1.186 + virtual nsresult OnSuccess(); 1.187 + 1.188 + /** 1.189 + * This callback is run on the main thread if DoDatabaseWork or OnSuccess 1.190 + * returned an error code. The default implementation fires an "error" DOM 1.191 + * event with its target set to the request. 1.192 + */ 1.193 + virtual void OnError(); 1.194 + 1.195 + /** 1.196 + * This function is called by the request on the main thread when script 1.197 + * accesses the result property of the request. 1.198 + */ 1.199 + virtual nsresult GetSuccessResult(JSContext* aCx, 1.200 + JS::MutableHandle<JS::Value> aVal) MOZ_OVERRIDE; 1.201 + 1.202 + /** 1.203 + * Gives the subclass a chance to release any objects that must be released 1.204 + * on the main thread, regardless of success or failure. Subclasses that 1.205 + * implement this method *MUST* call the base class implementation as well. 1.206 + */ 1.207 + virtual void ReleaseMainThreadObjects() MOZ_OVERRIDE; 1.208 + 1.209 + /** 1.210 + * Helper to make a JS array object out of an array of clone buffers. 1.211 + */ 1.212 + static nsresult ConvertToArrayAndCleanup( 1.213 + JSContext* aCx, 1.214 + nsTArray<StructuredCloneReadInfo>& aReadInfos, 1.215 + JS::MutableHandle<JS::Value> aResult); 1.216 + 1.217 + /** 1.218 + * This should only be called by AutoSetCurrentTransaction. 1.219 + */ 1.220 + static void SetCurrentTransaction(IDBTransaction* aTransaction); 1.221 + 1.222 + /** 1.223 + * Allows the subclass to send its results to the child process. Will only 1.224 + * be called if all of the IPC infrastructure is available (there is an 1.225 + * actor, the child is stil alive and hasn't begun shutting down). 1.226 + */ 1.227 + virtual ChildProcessSendResult 1.228 + SendResponseToChildProcess(nsresult aResultCode) = 0; 1.229 + 1.230 +protected: 1.231 + nsRefPtr<IDBDatabase> mDatabase; 1.232 + nsRefPtr<IDBTransaction> mTransaction; 1.233 + 1.234 +private: 1.235 + nsCOMPtr<mozIStorageProgressHandler> mOldProgressHandler; 1.236 + nsresult mResultCode; 1.237 + bool mDispatched; 1.238 +}; 1.239 + 1.240 +class MOZ_STACK_CLASS StackBasedEventTarget : public nsIEventTarget 1.241 +{ 1.242 +public: 1.243 + NS_DECL_ISUPPORTS_INHERITED 1.244 +}; 1.245 + 1.246 +class MOZ_STACK_CLASS ImmediateRunEventTarget : public StackBasedEventTarget 1.247 +{ 1.248 +public: 1.249 + NS_DECL_NSIEVENTTARGET 1.250 +}; 1.251 + 1.252 +class MOZ_STACK_CLASS NoDispatchEventTarget : public StackBasedEventTarget 1.253 +{ 1.254 +public: 1.255 + NS_DECL_NSIEVENTTARGET 1.256 +}; 1.257 + 1.258 +END_INDEXEDDB_NAMESPACE 1.259 + 1.260 +#endif // mozilla_dom_indexeddb_asyncconnectionhelper_h__