Bug 783426: Patch 1 - Async DOMRequest Firing; r=sicking
☠☠ backed out by 946c68705ac9 ☠ ☠
authorKyle Machulis <kyle@nonpolynomial.com>
Thu, 23 Aug 2012 09:52:29 -0700
changeset 105224 f98bea38e654fc7a14d166f3582e0988a32da807
parent 105223 f4e742d57ce7a24f38bbcd450d156d263955de9f
child 105225 c129811b87ef38c26d4fa80b1df7fbcee033a72e
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(cx, &mResult);
+  }
+
+  nsresult
+  Run()
+  {
+    static_cast<DOMRequest*>(mReq)->FireSuccess(mResult);
+    return NS_OK;
+  }
+
+  ~FireSuccessAsyncTask()
+  {
+    JSContext* cx = mReq->GetJSContextForEventHandlers();
+    JS_RemoveValueRoot(cx, &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);
 };