Bug 1436694 - Make a PostTask variant that returns a MozPromise. r=jib, r=jya
authorAndreas Pehrson <pehrsons@mozilla.com>
Thu, 15 Feb 2018 15:18:12 +0100
changeset 406787 59f19fc034cf7fc035710ff97e5b0a983ca920e6
parent 406786 42c6ec43f7829aa95692c83cbb8a75e77bd9dd33
child 406788 0451fe123f5b9168de34b3f927bb421c8e9864ca
push id33580
push userdluca@mozilla.com
push dateTue, 06 Mar 2018 21:54:45 +0000
treeherdermozilla-central@bccdc6842104 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjib, jya
bugs1436694
milestone60.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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.");
@@ -4009,24 +4023,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
@@ -137,16 +137,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;
   }