Bug 1359357 - IPCBlobInputStreamChild should be protected by a WorkerHolder, r=smaug

This commit is contained in:
Andrea Marchesini 2017-05-22 13:33:00 +02:00
Родитель d7c81386bd
Коммит cf22d699db
2 изменённых файлов: 46 добавлений и 3 удалений

Просмотреть файл

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "IPCBlobInputStreamChild.h"
#include "WorkerHolder.h"
namespace mozilla {
namespace dom {
@ -13,7 +14,7 @@ namespace {
// This runnable is used in case the last stream is forgotten on the 'wrong'
// thread.
class ShutdownRunnable final : public Runnable
class ShutdownRunnable final : public CancelableRunnable
{
public:
explicit ShutdownRunnable(IPCBlobInputStreamChild* aActor)
@ -33,7 +34,7 @@ private:
// This runnable is used in case StreamNeeded() has been called on a non-owning
// thread.
class StreamNeededRunnable final : public Runnable
class StreamNeededRunnable final : public CancelableRunnable
{
public:
explicit StreamNeededRunnable(IPCBlobInputStreamChild* aActor)
@ -79,6 +80,26 @@ private:
nsCOMPtr<nsIInputStream> mCreatedStream;
};
class IPCBlobInputStreamWorkerHolder final : public WorkerHolder
{
public:
explicit IPCBlobInputStreamWorkerHolder(IPCBlobInputStreamChild* aActor)
: mActor(aActor)
{}
bool Notify(Status aStatus) override
{
if (aStatus > Running) {
mActor->Shutdown();
// After this the WorkerHolder is gone.
}
return true;
}
private:
RefPtr<IPCBlobInputStreamChild> mActor;
};
} // anonymous
IPCBlobInputStreamChild::IPCBlobInputStreamChild(const nsID& aID,
@ -88,7 +109,20 @@ IPCBlobInputStreamChild::IPCBlobInputStreamChild(const nsID& aID,
, mSize(aSize)
, mActorAlive(true)
, mOwningThread(NS_GetCurrentThread())
{}
{
// If we are running in a worker, we need to send a Close() to the parent side
// before the thread is released.
if (!NS_IsMainThread()) {
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
if (workerPrivate) {
UniquePtr<WorkerHolder> workerHolder(
new IPCBlobInputStreamWorkerHolder(this));
if (workerHolder->HoldWorker(workerPrivate, Canceling)) {
mWorkerHolder.swap(workerHolder);
}
}
}
}
IPCBlobInputStreamChild::~IPCBlobInputStreamChild()
{}
@ -100,6 +134,7 @@ IPCBlobInputStreamChild::Shutdown()
RefPtr<IPCBlobInputStreamChild> kungFuDeathGrip = this;
mWorkerHolder = nullptr;
mPendingOperations.Clear();
if (mActorAlive) {
@ -116,6 +151,7 @@ IPCBlobInputStreamChild::ActorDestroy(IProtocol::ActorDestroyReason aReason)
mActorAlive = false;
}
// Let's cleanup the workerHolder and the pending operation queue.
Shutdown();
}

Просмотреть файл

@ -9,12 +9,17 @@
#include "mozilla/ipc/PIPCBlobInputStreamChild.h"
#include "mozilla/Mutex.h"
#include "mozilla/UniquePtr.h"
#include "nsIThread.h"
#include "nsTArray.h"
namespace mozilla {
namespace dom {
namespace workers {
class WorkerHolder;
}
class IPCBlobInputStream;
class IPCBlobInputStreamChild final
@ -85,6 +90,8 @@ private:
nsTArray<PendingOperation> mPendingOperations;
nsCOMPtr<nsIThread> mOwningThread;
UniquePtr<workers::WorkerHolder> mWorkerHolder;
};
} // namespace dom