Bug 1109954 - Make resolve/reject values optional in callback signatures. r=cpearce, a=sledru
authorBobby Holley <bobbyholley@gmail.com>
Fri, 12 Dec 2014 14:22:23 -0800
changeset 242722 a024fc4f0bd28a9c0b7d78e965ec199769247753
parent 242721 e39c7a02ccd1a26f518bf57856fc0554ced33357
child 242723 9eb09ba7451a443fdc5763b879f4f11b4a855895
push id4311
push userraliiev@mozilla.com
push dateMon, 12 Jan 2015 19:37:41 +0000
treeherdermozilla-beta@150c9fed433b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce, sledru
bugs1109954
milestone36.0a2
Bug 1109954 - Make resolve/reject values optional in callback signatures. r=cpearce, a=sledru
dom/media/MediaDecoderStateMachine.cpp
dom/media/MediaDecoderStateMachine.h
dom/media/MediaPromise.h
dom/media/mediasource/MediaSourceReader.cpp
dom/media/mediasource/MediaSourceReader.h
dom/media/mediasource/TrackBuffer.cpp
dom/media/mediasource/TrackBuffer.h
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -2477,20 +2477,19 @@ MediaDecoderStateMachine::ShutdownReader
 {
   MOZ_ASSERT(OnDecodeThread());
   mReader->Shutdown()->Then(GetStateMachineThread(), __func__, this,
                             &MediaDecoderStateMachine::FinishShutdown,
                             &MediaDecoderStateMachine::FinishShutdown);
 }
 
 void
-MediaDecoderStateMachine::FinishShutdown(bool aSuccess)
+MediaDecoderStateMachine::FinishShutdown()
 {
   MOZ_ASSERT(OnStateMachineThread());
-  MOZ_ASSERT(aSuccess);
   ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
 
   // The reader's listeners hold references to the state machine,
   // creating a cycle which keeps the state machine and its shared
   // thread pools alive. So break it here.
   AudioQueue().ClearListeners();
   VideoQueue().ClearListeners();
 
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -158,17 +158,17 @@ public:
   void SetAudioCaptured(bool aCapture);
 
   // Check if the decoder needs to become dormant state.
   bool IsDormantNeeded();
   // Set/Unset dormant state.
   void SetDormant(bool aDormant);
   void Shutdown();
   void ShutdownReader();
-  void FinishShutdown(bool aSuccess);
+  void FinishShutdown();
 
   // Called from the main thread to get the duration. The decoder monitor
   // must be obtained before calling this. It is in units of microseconds.
   int64_t GetDuration();
 
   // Called from the main thread to set the duration of the media resource
   // if it is able to be obtained via HTTP headers. Called from the
   // state machine thread to set the duration if it is obtained from the
--- a/dom/media/MediaPromise.h
+++ b/dom/media/MediaPromise.h
@@ -150,16 +150,42 @@ protected:
     virtual ~ThenValueBase() { MOZ_COUNT_DTOR(ThenValueBase); }
 
     virtual void DoResolve(ResolveValueType aResolveValue) = 0;
     virtual void DoReject(RejectValueType aRejectValue) = 0;
 
     const char* mCallSite;
   };
 
+  /*
+   * We create two overloads for invoking Resolve/Reject Methods so as to
+   * make the resolve/reject value argument "optional".
+   */
+
+  // Avoid confusing the compiler when the callback accepts T* but the ValueType
+  // is nsRefPtr<T>. See bug 1109954 comment 6.
+  template <typename T>
+  struct NonDeduced
+  {
+    typedef T type;
+  };
+
+  template<typename ThisType, typename ValueType>
+  static void InvokeCallbackMethod(ThisType* aThisVal, void(ThisType::*aMethod)(ValueType),
+                                   typename NonDeduced<ValueType>::type aValue)
+  {
+      ((*aThisVal).*aMethod)(aValue);
+  }
+
+  template<typename ThisType, typename ValueType>
+  static void InvokeCallbackMethod(ThisType* aThisVal, void(ThisType::*aMethod)(), ValueType aValue)
+  {
+      ((*aThisVal).*aMethod)();
+  }
+
   template<typename TargetType, typename ThisType,
            typename ResolveMethodType, typename RejectMethodType>
   class ThenValue : public ThenValueBase
   {
   public:
     ThenValue(TargetType* aResponseTarget, ThisType* aThisVal,
               ResolveMethodType aResolveMethod, RejectMethodType aRejectMethod,
               const char* aCallSite)
@@ -182,22 +208,22 @@ protected:
                   runnable.get(), aPromise, this);
       DebugOnly<nsresult> rv = detail::DispatchMediaPromiseRunnable(mResponseTarget, runnable);
       MOZ_ASSERT(NS_SUCCEEDED(rv));
     }
 
   protected:
     virtual void DoResolve(ResolveValueType aResolveValue)
     {
-      ((*mThisVal).*mResolveMethod)(aResolveValue);
+      InvokeCallbackMethod(mThisVal.get(), mResolveMethod, aResolveValue);
     }
 
     virtual void DoReject(RejectValueType aRejectValue)
     {
-      ((*mThisVal).*mRejectMethod)(aRejectValue);
+      InvokeCallbackMethod(mThisVal.get(), mRejectMethod, aRejectValue);
     }
 
     virtual ~ThenValue() {}
 
   private:
     nsRefPtr<TargetType> mResponseTarget;
     nsRefPtr<ThisType> mThisVal;
     ResolveMethodType mResolveMethod;
--- a/dom/media/mediasource/MediaSourceReader.cpp
+++ b/dom/media/mediasource/MediaSourceReader.cpp
@@ -294,24 +294,23 @@ MediaSourceReader::OnVideoNotDecoded(Not
 }
 
 nsRefPtr<ShutdownPromise>
 MediaSourceReader::Shutdown()
 {
   MOZ_ASSERT(mMediaSourceShutdownPromise.IsEmpty());
   nsRefPtr<ShutdownPromise> p = mMediaSourceShutdownPromise.Ensure(__func__);
 
-  ContinueShutdown(true);
+  ContinueShutdown();
   return p;
 }
 
 void
-MediaSourceReader::ContinueShutdown(bool aSuccess)
+MediaSourceReader::ContinueShutdown()
 {
-  MOZ_ASSERT(aSuccess);
   if (mTrackBuffers.Length()) {
     mTrackBuffers[0]->Shutdown()->Then(GetTaskQueue(), __func__, this,
                                        &MediaSourceReader::ContinueShutdown,
                                        &MediaSourceReader::ContinueShutdown);
     mShutdownTrackBuffers.AppendElement(mTrackBuffers[0]);
     mTrackBuffers.RemoveElementAt(0);
     return;
   }
--- a/dom/media/mediasource/MediaSourceReader.h
+++ b/dom/media/mediasource/MediaSourceReader.h
@@ -175,17 +175,17 @@ private:
   // first decoded sample. These flags are set during seeking
   // so we can detect when we have the first decoded sample
   // after a seek.
   bool mAudioIsSeeking;
   bool mVideoIsSeeking;
 
   bool mHasEssentialTrackBuffers;
 
-  void ContinueShutdown(bool aSuccess);
+  void ContinueShutdown();
   MediaPromiseHolder<ShutdownPromise> mMediaSourceShutdownPromise;
 #ifdef MOZ_FMP4
   nsRefPtr<SharedDecoderManager> mSharedDecoderManager;
 #endif
 };
 
 } // namespace mozilla
 
--- a/dom/media/mediasource/TrackBuffer.cpp
+++ b/dom/media/mediasource/TrackBuffer.cpp
@@ -107,19 +107,18 @@ TrackBuffer::Shutdown()
   queue->BeginShutdown()
        ->Then(mParentDecoder->GetReader()->GetTaskQueue(), __func__, this,
               &TrackBuffer::ContinueShutdown, &TrackBuffer::ContinueShutdown);
 
   return p;
 }
 
 void
-TrackBuffer::ContinueShutdown(bool aSuccess)
+TrackBuffer::ContinueShutdown()
 {
-  MOZ_ASSERT(aSuccess);
   ReentrantMonitorAutoEnter mon(mParentDecoder->GetReentrantMonitor());
   if (mDecoders.Length()) {
     mDecoders[0]->GetReader()->Shutdown()
                 ->Then(mParentDecoder->GetReader()->GetTaskQueue(), __func__, this,
                        &TrackBuffer::ContinueShutdown, &TrackBuffer::ContinueShutdown);
     mShutdownDecoders.AppendElement(mDecoders[0]);
     mDecoders.RemoveElementAt(0);
     return;
--- a/dom/media/mediasource/TrackBuffer.h
+++ b/dom/media/mediasource/TrackBuffer.h
@@ -155,14 +155,14 @@ private:
   // AppendData.  Accessed on the main thread only.
   int64_t mLastStartTimestamp;
   Maybe<int64_t> mLastEndTimestamp;
 
   // Set when the first decoder used by this TrackBuffer is initialized.
   // Protected by mParentDecoder's monitor.
   MediaInfo mInfo;
 
-  void ContinueShutdown(bool aSuccess);
+  void ContinueShutdown();
   MediaPromiseHolder<ShutdownPromise> mShutdownPromise;
 };
 
 } // namespace mozilla
 #endif /* MOZILLA_TRACKBUFFER_H_ */