Bug 1157803 - Loosen dispatch requirements for state mirroring. r=jww
authorBobby Holley <bobbyholley@gmail.com>
Tue, 28 Apr 2015 15:16:15 -0700
changeset 241504 4a2c2ef2e24a0d687ce8fb400b1315bc41db3845
parent 241503 4d0265c15acca5514b3345868d637e3b67739c0d
child 241505 219435f463d2ea6d74b3ae57f04de23010c301f9
push id59139
push userbobbyholley@gmail.com
push dateWed, 29 Apr 2015 04:56:35 +0000
treeherdermozilla-inbound@5b8e33d6ad71 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjww
bugs1157803
milestone40.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 1157803 - Loosen dispatch requirements for state mirroring. r=jww
dom/media/StateMirroring.h
--- a/dom/media/StateMirroring.h
+++ b/dom/media/StateMirroring.h
@@ -28,16 +28,22 @@
  * One problem with the naive implementation of such a system is that some pieces
  * of state need to be updated atomically, and certain other operations need to
  * wait for these atomic updates to complete before executing. The state-mirroring
  * machinery solves this problem by requiring that its owner thread uses tail
  * dispatch, and posting state update events (which should always be run first by
  * TaskDispatcher implementations) to that tail dispatcher. This ensures that
  * state changes are always atomic from the perspective of observing threads.
  *
+ * Given that state-mirroring is an automatic background process, we try to avoid
+ * burdening the caller with worrying too much about teardown. To that end, we
+ * don't assert dispatch success for any of the notifications, and assume that
+ * any canonical or mirror owned by a thread for whom dispatch fails will soon
+ * be disconnected by its holder anyway.
+ *
  * Given that semantics may change and comments tend to go out of date, we
  * deliberately don't provide usage examples here. Grep around to find them.
  */
 
 namespace mozilla {
 
 // Mirror<T> and Canonical<T> inherit WatchTarget, so we piggy-back on the
 // logging that WatchTarget already does. Given that, it makes sense to share
@@ -116,34 +122,34 @@ public:
   }
 
   void AddMirror(AbstractMirror<T>* aMirror) override
   {
     MIRROR_LOG("%s [%p] adding mirror %p", mName, this, aMirror);
     MOZ_ASSERT(OwnerThread()->IsCurrentThreadIn());
     MOZ_ASSERT(!mMirrors.Contains(aMirror));
     mMirrors.AppendElement(aMirror);
-    aMirror->OwnerThread()->Dispatch(MakeNotifier(aMirror));
+    aMirror->OwnerThread()->Dispatch(MakeNotifier(aMirror), AbstractThread::DontAssertDispatchSuccess);
   }
 
   void RemoveMirror(AbstractMirror<T>* aMirror) override
   {
     MIRROR_LOG("%s [%p] removing mirror %p", mName, this, aMirror);
     MOZ_ASSERT(OwnerThread()->IsCurrentThreadIn());
     MOZ_ASSERT(mMirrors.Contains(aMirror));
     mMirrors.RemoveElement(aMirror);
   }
 
   void DisconnectAll()
   {
     MIRROR_LOG("%s [%p] Disconnecting all mirrors", mName, this);
     for (size_t i = 0; i < mMirrors.Length(); ++i) {
       nsCOMPtr<nsIRunnable> r =
         NS_NewRunnableMethod(mMirrors[i], &AbstractMirror<T>::NotifyDisconnected);
-      mMirrors[i]->OwnerThread()->Dispatch(r.forget());
+      mMirrors[i]->OwnerThread()->Dispatch(r.forget(), AbstractThread::DontAssertDispatchSuccess);
     }
     mMirrors.Clear();
   }
 
   operator const T&()
   {
     MOZ_ASSERT(OwnerThread()->IsCurrentThreadIn());
     return mValue;
@@ -295,31 +301,31 @@ public:
   void Connect(AbstractCanonical<T>* aCanonical)
   {
     MIRROR_LOG("%s [%p] Connecting to %p", mName, this, aCanonical);
     MOZ_ASSERT(OwnerThread()->IsCurrentThreadIn());
     MOZ_ASSERT(!IsConnected());
 
     nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethodWithArg<StorensRefPtrPassByPtr<AbstractMirror<T>>>
                                 (aCanonical, &AbstractCanonical<T>::AddMirror, this);
-    aCanonical->OwnerThread()->Dispatch(r.forget());
+    aCanonical->OwnerThread()->Dispatch(r.forget(), AbstractThread::DontAssertDispatchSuccess);
     mCanonical = aCanonical;
   }
 
   void DisconnectIfConnected()
   {
     MOZ_ASSERT(OwnerThread()->IsCurrentThreadIn());
     if (!IsConnected()) {
       return;
     }
 
     MIRROR_LOG("%s [%p] Disconnecting from %p", mName, this, mCanonical.get());
     nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethodWithArg<StorensRefPtrPassByPtr<AbstractMirror<T>>>
                                 (mCanonical, &AbstractCanonical<T>::RemoveMirror, this);
-    mCanonical->OwnerThread()->Dispatch(r.forget());
+    mCanonical->OwnerThread()->Dispatch(r.forget(), AbstractThread::DontAssertDispatchSuccess);
     mCanonical = nullptr;
   }
 
   class Holder
   {
   public:
     Holder() {}
     ~Holder()