Backed out changeset a7cbe0438433 (bug 1540733) for causing browser_ipcBlob_temporary.js and test_wasm_recompile.js to perma fail CLOSED TREE
authorCiure Andrei <aciure@mozilla.com>
Fri, 19 Apr 2019 00:58:10 +0300
changeset 470115 e3308b44faa7ea386242cc98ed4603435d40713b
parent 470114 e6eaf8ab500a17c4ed1bb2ea84e525d9e825ce3a
child 470116 63f2f8138861f1df35d280c4a1f3f5591ef9a4a4
push id35888
push useraiakab@mozilla.com
push dateFri, 19 Apr 2019 09:47:45 +0000
treeherdermozilla-central@0160424142d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1540733
milestone68.0a1
backs outa7cbe043843340945476d44fd59d8b015b98480d
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
Backed out changeset a7cbe0438433 (bug 1540733) for causing browser_ipcBlob_temporary.js and test_wasm_recompile.js to perma fail CLOSED TREE
dom/file/ipc/IPCBlobInputStream.cpp
dom/file/ipc/IPCBlobInputStream.h
dom/file/ipc/IPCBlobInputStreamChild.cpp
dom/file/ipc/IPCBlobInputStreamChild.h
dom/file/ipc/IPCBlobInputStreamParent.cpp
dom/file/ipc/IPCBlobInputStreamThread.cpp
dom/file/ipc/IPCBlobUtils.h
--- a/dom/file/ipc/IPCBlobInputStream.cpp
+++ b/dom/file/ipc/IPCBlobInputStream.cpp
@@ -910,17 +910,10 @@ void IPCBlobInputStream::LengthReady(int
   }
 
   if (lengthCallback) {
     InputStreamLengthCallbackRunnable::Execute(
         lengthCallback, lengthCallbackEventTarget, this, aLength);
   }
 }
 
-void IPCBlobInputStream::ActorMigrated(IPCBlobInputStreamChild* aNewActor) {
-  MutexAutoLock lock(mMutex);
-  MOZ_ASSERT(mActor->Size() == aNewActor->Size());
-  MOZ_ASSERT(mActor->ID() == aNewActor->ID());
-  mActor = aNewActor;
-}
-
 }  // namespace dom
 }  // namespace mozilla
--- a/dom/file/ipc/IPCBlobInputStream.h
+++ b/dom/file/ipc/IPCBlobInputStream.h
@@ -73,18 +73,16 @@ class IPCBlobInputStream final : public 
 
     if (mAsyncRemoteStream) {
       return mAsyncRemoteStream;
     }
 
     return nullptr;
   }
 
-  void ActorMigrated(IPCBlobInputStreamChild* aNewActor);
-
  private:
   ~IPCBlobInputStream();
 
   nsresult EnsureAsyncRemoteStream(const MutexAutoLock& aProofOfLock);
 
   void InitWithExistingRange(uint64_t aStart, uint64_t aLength,
                              const MutexAutoLock& aProofOfLock);
 
--- a/dom/file/ipc/IPCBlobInputStreamChild.cpp
+++ b/dom/file/ipc/IPCBlobInputStreamChild.cpp
@@ -5,17 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "IPCBlobInputStreamChild.h"
 #include "IPCBlobInputStreamThread.h"
 
 #include "mozilla/ipc/IPCStreamUtils.h"
 #include "mozilla/dom/WorkerCommon.h"
 #include "mozilla/dom/WorkerRef.h"
-#include "mozilla/ipc/PBackgroundChild.h"
 
 namespace mozilla {
 namespace dom {
 
 namespace {
 
 // This runnable is used in case the last stream is forgotten on the 'wrong'
 // thread.
@@ -178,16 +177,17 @@ void IPCBlobInputStreamChild::ActorDestr
 
   if (migrating) {
     // We were waiting for this! Now we can migrate the actor in the correct
     // thread.
     RefPtr<IPCBlobInputStreamThread> thread =
         IPCBlobInputStreamThread::GetOrCreate();
     MOZ_ASSERT(thread, "We cannot continue without DOMFile thread.");
 
+    ResetManager();
     thread->MigrateActor(this);
     return;
   }
 
   // Let's cleanup the workerRef and the pending operation queue.
   Shutdown();
 }
 
@@ -381,59 +381,34 @@ mozilla::ipc::IPCResult IPCBlobInputStre
   RefPtr<LengthReadyRunnable> runnable =
       new LengthReadyRunnable(pendingStream, aLength);
 
   MOZ_ASSERT(eventTarget);
   eventTarget->Dispatch(runnable, NS_DISPATCH_NORMAL);
 
   return IPC_OK();
 }
-
-void IPCBlobInputStreamChild::MigrateTo(PBackgroundChild* aManager) {
+void IPCBlobInputStreamChild::Migrated() {
   MutexAutoLock lock(mMutex);
   MOZ_ASSERT(mState == eInactiveMigrating);
 
-  // Construct the replacement actor, sending the IPC constructor. The reference
-  // taken will be freed by DeallocPIPCBlobInputStreamConstructor.
-  RefPtr<IPCBlobInputStreamChild> actor =
-      new IPCBlobInputStreamChild(mID, mSize);
-  if (!aManager->SendPIPCBlobInputStreamConstructor(do_AddRef(actor).take(),
-                                                    mID, mSize)) {
-    return;
-  }
-
-  actor->MigratedFrom(this);
+  mWorkerRef = nullptr;
 
-  // Finally, complete teardown of the old actor.
-  MOZ_ASSERT(mStreams.IsEmpty() && mPendingOperations.IsEmpty());
-  mWorkerRef = nullptr;
-  mState = eInactive;
-}
-
-void IPCBlobInputStreamChild::MigratedFrom(IPCBlobInputStreamChild* aOldActor) {
-  MutexAutoLock lock(mMutex);
-  aOldActor->mMutex.AssertCurrentThreadOwns();
-
+  mOwningEventTarget = GetCurrentThreadSerialEventTarget();
   MOZ_ASSERT(IPCBlobInputStreamThread::IsOnFileEventTarget(mOwningEventTarget));
-  MOZ_ASSERT(mState == eActive);
-
-  // Take streams & pending operations from |aOldActor|.
-  mStreams.SwapElements(aOldActor->mStreams);
-  mPendingOperations.SwapElements(aOldActor->mPendingOperations);
-  for (auto* stream : mStreams) {
-    stream->ActorMigrated(this);
-  }
 
   // Maybe we have no reasons to keep this actor alive.
   if (mStreams.IsEmpty()) {
     mState = eInactive;
     SendClose();
     return;
   }
 
+  mState = eActive;
+
   // Let's processing the pending operations. We need a stream for each pending
   // operation.
   for (uint32_t i = 0; i < mPendingOperations.Length(); ++i) {
     if (mPendingOperations[i].mOp == PendingOperation::eStreamNeeded) {
       SendStreamNeeded();
     } else {
       MOZ_ASSERT(mPendingOperations[i].mOp == PendingOperation::eLengthNeeded);
       SendLengthNeeded();
--- a/dom/file/ipc/IPCBlobInputStreamChild.h
+++ b/dom/file/ipc/IPCBlobInputStreamChild.h
@@ -59,23 +59,21 @@ class IPCBlobInputStreamChild final
   mozilla::ipc::IPCResult RecvStreamReady(const Maybe<IPCStream>& aStream);
 
   void LengthNeeded(IPCBlobInputStream* aStream, nsIEventTarget* aEventTarget);
 
   mozilla::ipc::IPCResult RecvLengthReady(const int64_t& aLength);
 
   void Shutdown();
 
-  void MigrateTo(PBackgroundChild* aManager);
+  void Migrated();
 
  private:
   ~IPCBlobInputStreamChild();
 
-  void MigratedFrom(IPCBlobInputStreamChild* aOldActor);
-
   // Raw pointers because these streams keep this actor alive. When the last
   // stream is unregister, the actor will be deleted. This list is protected by
   // mutex.
   nsTArray<IPCBlobInputStream*> mStreams;
 
   // This mutex protects mStreams because that can be touched in any thread.
   Mutex mMutex;
 
--- a/dom/file/ipc/IPCBlobInputStreamParent.cpp
+++ b/dom/file/ipc/IPCBlobInputStreamParent.cpp
@@ -74,17 +74,17 @@ void IPCBlobInputStreamParent::ActorDest
   RefPtr<IPCBlobInputStreamParentCallback> callback;
   mCallback.swap(callback);
 
   RefPtr<IPCBlobInputStreamStorage> storage = IPCBlobInputStreamStorage::Get();
 
   if (mMigrating) {
     if (callback && storage) {
       // We need to assign this callback to the next parent.
-      storage->StoreCallback(mID, callback);
+      IPCBlobInputStreamStorage::Get()->StoreCallback(mID, callback);
     }
     return;
   }
 
   if (storage) {
     storage->ForgetStream(mID);
   }
 
--- a/dom/file/ipc/IPCBlobInputStreamThread.cpp
+++ b/dom/file/ipc/IPCBlobInputStreamThread.cpp
@@ -42,23 +42,33 @@ class MigrateActorRunnable final : publi
  public:
   explicit MigrateActorRunnable(IPCBlobInputStreamChild* aActor)
       : Runnable("dom::MigrateActorRunnable"), mActor(aActor) {
     MOZ_ASSERT(mActor);
   }
 
   NS_IMETHOD
   Run() override {
+    MOZ_ASSERT(mActor->State() == IPCBlobInputStreamChild::eInactiveMigrating);
+
     PBackgroundChild* actorChild =
         BackgroundChild::GetOrCreateForCurrentThread();
     if (!actorChild) {
       return NS_OK;
     }
 
-    mActor->MigrateTo(actorChild);
+    if (actorChild->SendPIPCBlobInputStreamConstructor(mActor, mActor->ID(),
+                                                       mActor->Size())) {
+      // We need manually to increase the reference for this actor because the
+      // IPC allocator method is not triggered. The Release() is called by IPDL
+      // when the actor is deleted.
+      mActor.get()->AddRef();
+      mActor->Migrated();
+    }
+
     return NS_OK;
   }
 
  private:
   ~MigrateActorRunnable() = default;
 
   RefPtr<IPCBlobInputStreamChild> mActor;
 };
--- a/dom/file/ipc/IPCBlobUtils.h
+++ b/dom/file/ipc/IPCBlobUtils.h
@@ -161,20 +161,19 @@
  * 3. IPCBlobInputStreamParent::Recv__delete__ is called on the parent side and
  *    the parent actor is deleted. Doing this we don't remove the UUID from
  *    IPCBlobInputStreamStorage.
  * 4. When IPCBlobInputStreamChild::ActorDestroy() is called, we are sure that
  *    the IPC channel is completely released. IPCBlobInputStreamThread is be
  *    used to assign IPCBlobInputStreamChild actor to the DOM-File thread.
  *    IPCBlobInputStreamThread::GetOrCreate() creates the DOM-File thread if it
  *    doesn't exist yet and it initializes PBackground on it if needed.
- * 5. A new IPCBlobInputStreamChild is created on the DOM-File thread for the
- *    creation of a new IPCBlobInputStreamParent actor on the parent side.
- *    Pending operations and IPCBlobInputStreams are moved onto the new actor,
- *    and back references are updated.
+ * 5. IPCBlobInputStreamChild is reused on the DOM-File thread for the creation
+ *    of a new IPCBlobInputStreamParent actor on the parent side. Doing this,
+ *    IPCBlobInputStreamChild will now be owned by the DOM-File thread.
  * 6. When the new IPCBlobInputStreamParent actor is created, it will receive
  *    the same UUID of the previous parent actor. The nsIInputStream will be
  *    retrieved from IPCBlobInputStreamStorage.
  * 7. In order to avoid leaks, IPCBlobInputStreamStorage will monitor child
  *    processes and in case one of them dies, it will release the
  *    nsIInputStream objects belonging to that process.
  *
  * If any API wants to retrieve a 'real inputStream when the migration is in