зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1540733 - Create a new IPCBlobInputStreamChild actor when migrating, r=baku
Differential Revision: https://phabricator.services.mozilla.com/D27970 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
e12dc53ba3
Коммит
d4f1348c4b
|
@ -915,5 +915,12 @@ void IPCBlobInputStream::LengthReady(int64_t 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
|
||||
|
|
|
@ -78,6 +78,8 @@ class IPCBlobInputStream final : public nsIAsyncInputStream,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void ActorMigrated(IPCBlobInputStreamChild* aNewActor);
|
||||
|
||||
private:
|
||||
~IPCBlobInputStream();
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "mozilla/ipc/IPCStreamUtils.h"
|
||||
#include "mozilla/dom/WorkerCommon.h"
|
||||
#include "mozilla/dom/WorkerRef.h"
|
||||
#include "mozilla/ipc/PBackgroundChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -182,7 +183,6 @@ void IPCBlobInputStreamChild::ActorDestroy(
|
|||
IPCBlobInputStreamThread::GetOrCreate();
|
||||
MOZ_ASSERT(thread, "We cannot continue without DOMFile thread.");
|
||||
|
||||
ResetManager();
|
||||
thread->MigrateActor(this);
|
||||
return;
|
||||
}
|
||||
|
@ -386,14 +386,41 @@ mozilla::ipc::IPCResult IPCBlobInputStreamChild::RecvLengthReady(
|
|||
|
||||
return IPC_OK();
|
||||
}
|
||||
void IPCBlobInputStreamChild::Migrated() {
|
||||
|
||||
void IPCBlobInputStreamChild::MigrateTo(PBackgroundChild* aManager) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
MOZ_ASSERT(mState == eInactiveMigrating);
|
||||
|
||||
mWorkerRef = nullptr;
|
||||
// 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);
|
||||
|
||||
// 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()) {
|
||||
|
@ -402,8 +429,6 @@ void IPCBlobInputStreamChild::Migrated() {
|
|||
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) {
|
||||
|
|
|
@ -64,11 +64,13 @@ class IPCBlobInputStreamChild final
|
|||
|
||||
void Shutdown();
|
||||
|
||||
void Migrated();
|
||||
void MigrateTo(PBackgroundChild* aManager);
|
||||
|
||||
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.
|
||||
|
|
|
@ -79,7 +79,7 @@ void IPCBlobInputStreamParent::ActorDestroy(
|
|||
if (mMigrating) {
|
||||
if (callback && storage) {
|
||||
// We need to assign this callback to the next parent.
|
||||
IPCBlobInputStreamStorage::Get()->StoreCallback(mID, callback);
|
||||
storage->StoreCallback(mID, callback);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -47,23 +47,13 @@ class MigrateActorRunnable final : public Runnable {
|
|||
|
||||
NS_IMETHOD
|
||||
Run() override {
|
||||
MOZ_ASSERT(mActor->State() == IPCBlobInputStreamChild::eInactiveMigrating);
|
||||
|
||||
PBackgroundChild* actorChild =
|
||||
BackgroundChild::GetOrCreateForCurrentThread();
|
||||
if (!actorChild) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
mActor->MigrateTo(actorChild);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -166,9 +166,10 @@
|
|||
* 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. 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.
|
||||
* 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.
|
||||
* 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.
|
||||
|
|
Загрузка…
Ссылка в новой задаче