Bug 783426: Patch 1 - Async DOMRequest Firing; r=sicking
☠☠ backed out by 4d4e97519d50 ☠ ☠
authorKyle Machulis <kyle@nonpolynomial.com>
Wed, 22 Aug 2012 18:03:43 -0700
changeset 105129 81fc1a3fc92030cc49a69841422cebc86b07f281
parent 105128 38535165c87b112e95b8f7e95845ded6cf643647
child 105130 be6da7f8989cfe0e03929c85c6003cf938ac2cb4
push id55
push usershu@rfrn.org
push dateThu, 30 Aug 2012 01:33:09 +0000
reviewerssicking
bugs783426
milestone17.0a1
Bug 783426: Patch 1 - Async DOMRequest Firing; r=sicking
dom/base/DOMRequest.cpp
dom/base/nsIDOMDOMRequest.idl
--- a/dom/base/DOMRequest.cpp
+++ b/dom/base/DOMRequest.cpp
@@ -7,16 +7,17 @@
 #include "DOMRequest.h"
 
 #include "mozilla/Util.h"
 #include "nsDOMClassInfo.h"
 #include "DOMError.h"
 #include "nsEventDispatcher.h"
 #include "nsDOMEvent.h"
 #include "nsContentUtils.h"
+#include "nsThreadUtils.h"
 
 using mozilla::dom::DOMRequest;
 using mozilla::dom::DOMRequestService;
 
 DOMRequest::DOMRequest(nsIDOMWindow* aWindow)
   : mResult(JSVAL_VOID)
   , mDone(false)
   , mRooted(false)
@@ -217,8 +218,84 @@ NS_IMETHODIMP
 DOMRequestService::FireError(nsIDOMDOMRequest* aRequest,
                              const nsAString& aError)
 {
   NS_ENSURE_STATE(aRequest);
   static_cast<DOMRequest*>(aRequest)->FireError(aError);
 
   return NS_OK;
 }
+
+class FireSuccessAsyncTask : public nsRunnable
+{
+public:
+  FireSuccessAsyncTask(nsIDOMDOMRequest* aRequest,
+                       const jsval& aResult) :
+    mReq(aRequest),
+    mResult(aResult)
+  {
+    JSContext* cx = mReq->GetJSContextForEventHandlers();
+    JS_AddValueRoot(jsc, &mResult);
+  }
+
+  nsresult
+  Run()
+  {
+    static_cast<DOMRequest*>(mReq)->FireSuccess(mResult);
+    return NS_OK;
+  }
+
+  ~FireSuccessAsyncTask()
+  {
+    JSContext* cx = mReq->GetJSContextForEventHandlers();
+    JS_RemoveValueRoot(jsc, &mResult);
+  }
+private:
+  nsIDOMDOMRequest* mReq;
+  jsval mResult;
+};
+
+class FireErrorAsyncTask : public nsRunnable
+{
+public:
+  FireErrorAsyncTask(nsIDOMDOMRequest* aRequest,
+                     const nsAString& aError) :
+    mReq(aRequest),
+    mError(aError)
+  {
+  }
+
+  nsresult
+  Run()
+  {
+    static_cast<DOMRequest*>(mReq)->FireError(mError);
+    return NS_OK;
+  }
+private:
+  nsIDOMDOMRequest* mReq;
+  nsString mError;
+};
+
+NS_IMETHODIMP
+DOMRequestService::FireSuccessAsync(nsIDOMDOMRequest* aRequest,
+                                    const jsval& aResult)
+{
+  NS_ENSURE_STATE(aRequest);
+  nsCOMPtr<nsIRunnable> asyncTask = new FireSuccessAsyncTask(aRequest, aResult);
+  if (NS_FAILED(NS_DispatchToMainThread(asyncTask))) {
+    NS_WARNING("Failed to dispatch to main thread!");
+    return NS_ERROR_FAILURE;
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+DOMRequestService::FireErrorAsync(nsIDOMDOMRequest* aRequest,
+                                  const nsAString& aError)
+{
+  NS_ENSURE_STATE(aRequest);
+  nsCOMPtr<nsIRunnable> asyncTask = new FireErrorAsyncTask(aRequest, aError);
+  if (NS_FAILED(NS_DispatchToMainThread(asyncTask))) {
+    NS_WARNING("Failed to dispatch to main thread!");
+    return NS_ERROR_FAILURE;
+  }
+  return NS_OK;
+}
--- a/dom/base/nsIDOMDOMRequest.idl
+++ b/dom/base/nsIDOMDOMRequest.idl
@@ -16,16 +16,18 @@ interface nsIDOMDOMRequest : nsIDOMEvent
 
   readonly attribute jsval result;
   readonly attribute nsIDOMDOMError error;
 
   attribute nsIDOMEventListener onsuccess;
   attribute nsIDOMEventListener onerror;
 };
 
-[scriptable, builtinclass, uuid(eebcdf29-f8fa-4c36-bbc7-2146b1cbaf7b)]
+[scriptable, builtinclass, uuid(10996de9-e6f6-4058-97bd-45f1fe065eb5)]
 interface nsIDOMRequestService : nsISupports
 {
   nsIDOMDOMRequest createRequest(in nsIDOMWindow window);
 
   void fireSuccess(in nsIDOMDOMRequest request, in jsval result);
   void fireError(in nsIDOMDOMRequest request, in DOMString error);
+  void fireSuccessAsync(in nsIDOMDOMRequest request, in jsval result);
+  void fireErrorAsync(in nsIDOMDOMRequest request, in DOMString error);
 };