Bug 1436694 - Make a PostTask variant that returns a MozPromise. r?jib, r?jya draft
authorAndreas Pehrson <pehrsons@mozilla.com>
Thu, 15 Feb 2018 15:18:12 +0100
changeset 759627 5301f1dcb16f89ba6e9a5815cc66645c3309e756
parent 754870 e293877d13a5236119adb706c97c55ea9e11868b
child 759628 fe3142d0574912517e42c720c9e6e251a600249c
push id100413
push userbmo:apehrson@mozilla.com
push dateMon, 26 Feb 2018 08:00:04 +0000
reviewersjib, jya
bugs1436694
milestone60.0a1
Bug 1436694 - Make a PostTask variant that returns a MozPromise. r?jib, r?jya MozReview-Commit-ID: 76mLpntaU5v
dom/media/MediaManager.cpp
dom/media/MediaManager.h
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -2144,16 +2144,30 @@ MediaManager::PostTask(already_AddRefed<
     MOZ_CRASH();
     return;
   }
   NS_ASSERTION(Get(), "MediaManager singleton?");
   NS_ASSERTION(Get()->mMediaThread, "No thread yet");
   Get()->mMediaThread->message_loop()->PostTask(Move(task));
 }
 
+template<typename MozPromiseType, typename FunctionType>
+/* static */ RefPtr<MozPromiseType>
+MediaManager::PostTask(const char* aName, FunctionType&& aFunction)
+{
+  MozPromiseHolder<MozPromiseType> holder;
+  RefPtr<MozPromiseType> promise = holder.Ensure(aName);
+  MediaManager::PostTask(NS_NewRunnableFunction(aName,
+        [h = Move(holder), func = Forward<FunctionType>(aFunction)]() mutable
+        {
+          func(h);
+        }));
+  return promise;
+}
+
 /* static */ nsresult
 MediaManager::NotifyRecordingStatusChange(nsPIDOMWindowInner* aWindow)
 {
   NS_ENSURE_ARG(aWindow);
 
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   if (!obs) {
     NS_WARNING("Could not get the Observer service for GetUserMedia recording notification.");
@@ -4045,24 +4059,21 @@ SourceListener::SetEnabledFor(TrackID aT
 
       if (!state.mOffWhileDisabled) {
         // If the feature to turn a device off while disabled is itself disabled
         // we shortcut the device operation and tell the ux-updating code
         // that everything went fine.
         return DeviceOperationPromise::CreateAndResolve(NS_OK, __func__);
       }
 
-      RefPtr<DeviceOperationPromise::Private> promise =
-        new DeviceOperationPromise::Private(__func__);
-      MediaManager::PostTask(NewTaskFrom([self, device = state.mDevice,
-                                          aEnable, promise]() mutable {
-        promise->Resolve(aEnable ? device->Start() : device->Stop(), __func__);
-      }));
-      RefPtr<DeviceOperationPromise> result = promise.get();
-      return result;
+      return MediaManager::PostTask<DeviceOperationPromise>(__func__,
+          [self, device = state.mDevice, aEnable]
+          (MozPromiseHolder<DeviceOperationPromise>& h) {
+            h.Resolve(aEnable ? device->Start() : device->Stop(), __func__);
+          });
     }, [](bool aDummy) {
       // Timer was canceled by us. We signal this with NS_ERROR_ABORT.
       return DeviceOperationPromise::CreateAndResolve(NS_ERROR_ABORT, __func__);
     })->Then(GetMainThreadSerialEventTarget(), __func__,
     [self, this, &state, aTrackID, aEnable](nsresult aResult) mutable {
       MOZ_ASSERT(state.mOperationInProgress);
       state.mOperationInProgress = false;
 
--- a/dom/media/MediaManager.h
+++ b/dom/media/MediaManager.h
@@ -143,16 +143,28 @@ public:
 
   // NOTE: never Dispatch(....,NS_DISPATCH_SYNC) to the MediaManager
   // thread from the MainThread, as we NS_DISPATCH_SYNC to MainThread
   // from MediaManager thread.
   static MediaManager* Get();
   static MediaManager* GetIfExists();
   static void StartupInit();
   static void PostTask(already_AddRefed<Runnable> task);
+
+  /**
+   * Posts an async operation to the media manager thread.
+   * FunctionType must be a function that takes a `MozPromiseHolder&`.
+   *
+   * The returned promise is resolved or rejected by aFunction on the media
+   * manager thread.
+   */
+  template<typename MozPromiseType, typename FunctionType>
+  static RefPtr<MozPromiseType>
+  PostTask(const char* aName, FunctionType&& aFunction);
+
 #ifdef DEBUG
   static bool IsInMediaThread();
 #endif
 
   static bool Exists()
   {
     return !!sSingleton;
   }