Bug 1373555 - Move the Fetch consume body login in a separate class - part 1 - separate files, r=bkelly

This commit is contained in:
Andrea Marchesini 2017-06-20 17:53:21 +02:00
Родитель e768233bc4
Коммит 349f7847d7
4 изменённых файлов: 194 добавлений и 128 удалений

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

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "Fetch.h"
#include "FetchConsumer.h"
#include "nsIDocument.h"
#include "nsIGlobalObject.h"
@ -834,134 +835,6 @@ ExtractByteStreamFromBody(const fetch::BodyInit& aBodyInit,
return NS_ERROR_FAILURE;
}
template <class Derived>
class FetchBodyWrapper;
template <class Derived>
class FetchBodyWorkerHolder final : public workers::WorkerHolder
{
RefPtr<FetchBodyWrapper<Derived>> mWrapper;
bool mWasNotified;
public:
explicit FetchBodyWorkerHolder(FetchBodyWrapper<Derived>* aWrapper)
: mWrapper(aWrapper)
, mWasNotified(false)
{
MOZ_ASSERT(aWrapper);
}
~FetchBodyWorkerHolder() = default;
bool Notify(workers::Status aStatus) override;
};
// FetchBody is not thread-safe but we need to move it around threads.
// In order to keep it alive all the time, we use a WorkerHolder, if created on
// workers, plus a wrapper.
template <class Derived>
class FetchBodyWrapper final
{
public:
friend class ReleaseObjectHelper;
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FetchBodyWrapper<Derived>)
static already_AddRefed<FetchBodyWrapper<Derived>>
Create(FetchBody<Derived>* aBody)
{
MOZ_ASSERT(aBody);
RefPtr<FetchBodyWrapper<Derived>> wrapper =
new FetchBodyWrapper<Derived>(aBody);
if (!NS_IsMainThread()) {
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(workerPrivate);
if (!wrapper->RegisterWorkerHolder(workerPrivate)) {
return nullptr;
}
}
return wrapper.forget();
}
void
ReleaseObject()
{
AssertIsOnTargetThread();
mWorkerHolder = nullptr;
mBody = nullptr;
}
FetchBody<Derived>*
Body() const
{
return mBody;
}
private:
explicit FetchBodyWrapper(FetchBody<Derived>* aBody)
: mTargetThread(NS_GetCurrentThread())
, mBody(aBody)
{}
~FetchBodyWrapper()
{
NS_ProxyRelease(mTargetThread, mBody.forget());
}
void
AssertIsOnTargetThread()
{
MOZ_ASSERT(NS_GetCurrentThread() == mTargetThread);
}
bool
RegisterWorkerHolder(WorkerPrivate* aWorkerPrivate)
{
MOZ_ASSERT(aWorkerPrivate);
aWorkerPrivate->AssertIsOnWorkerThread();
MOZ_ASSERT(!mWorkerHolder);
mWorkerHolder.reset(new FetchBodyWorkerHolder<Derived>(this));
if (!mWorkerHolder->HoldWorker(aWorkerPrivate, Closing)) {
NS_WARNING("Failed to add workerHolder");
mWorkerHolder = nullptr;
return false;
}
return true;
}
nsCOMPtr<nsIThread> mTargetThread;
RefPtr<FetchBody<Derived>> mBody;
// Set when consuming the body is attempted on a worker.
// Unset when consumption is done/aborted.
// This WorkerHolder keeps alive the wrapper via a cycle.
UniquePtr<workers::WorkerHolder> mWorkerHolder;
};
template <class Derived>
bool
FetchBodyWorkerHolder<Derived>::Notify(workers::Status aStatus)
{
MOZ_ASSERT(aStatus > workers::Running);
if (!mWasNotified) {
mWasNotified = true;
// This will probably cause the releasing of the wrapper.
// The WorkerHolder will be released as well.
mWrapper->Body()->ContinueConsumeBody(mWrapper, NS_BINDING_ABORTED, 0,
nullptr);
}
return true;
}
namespace {
/*
* Called on successfully reading the complete stream.

126
dom/fetch/FetchConsumer.cpp Normal file
Просмотреть файл

@ -0,0 +1,126 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "Fetch.h"
#include "FetchConsumer.h"
#include "nsProxyRelease.h"
#include "WorkerPrivate.h"
#include "WorkerRunnable.h"
#include "WorkerScope.h"
#include "Workers.h"
namespace mozilla {
namespace dom {
using namespace workers;
namespace {
template <class Derived>
class FetchBodyWorkerHolder final : public workers::WorkerHolder
{
RefPtr<FetchBodyWrapper<Derived>> mWrapper;
bool mWasNotified;
public:
explicit FetchBodyWorkerHolder(FetchBodyWrapper<Derived>* aWrapper)
: mWrapper(aWrapper)
, mWasNotified(false)
{
MOZ_ASSERT(aWrapper);
}
~FetchBodyWorkerHolder() = default;
bool Notify(workers::Status aStatus) override
{
MOZ_ASSERT(aStatus > workers::Running);
if (!mWasNotified) {
mWasNotified = true;
// This will probably cause the releasing of the wrapper.
// The WorkerHolder will be released as well.
mWrapper->Body()->ContinueConsumeBody(mWrapper, NS_BINDING_ABORTED, 0,
nullptr);
}
return true;
}
};
} // anonymous
template <class Derived>
/* static */ already_AddRefed<FetchBodyWrapper<Derived>>
FetchBodyWrapper<Derived>::Create(FetchBody<Derived>* aBody)
{
MOZ_ASSERT(aBody);
RefPtr<FetchBodyWrapper<Derived>> wrapper =
new FetchBodyWrapper<Derived>(aBody);
if (!NS_IsMainThread()) {
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(workerPrivate);
if (!wrapper->RegisterWorkerHolder(workerPrivate)) {
return nullptr;
}
}
return wrapper.forget();
}
template <class Derived>
void
FetchBodyWrapper<Derived>::ReleaseObject()
{
AssertIsOnTargetThread();
mWorkerHolder = nullptr;
mBody = nullptr;
}
template <class Derived>
FetchBodyWrapper<Derived>::FetchBodyWrapper(FetchBody<Derived>* aBody)
: mTargetThread(NS_GetCurrentThread())
, mBody(aBody)
{}
template <class Derived>
FetchBodyWrapper<Derived>::~FetchBodyWrapper()
{
NS_ProxyRelease(mTargetThread, mBody.forget());
}
template <class Derived>
void
FetchBodyWrapper<Derived>::AssertIsOnTargetThread() const
{
MOZ_ASSERT(NS_GetCurrentThread() == mTargetThread);
}
template <class Derived>
bool
FetchBodyWrapper<Derived>::RegisterWorkerHolder(WorkerPrivate* aWorkerPrivate)
{
MOZ_ASSERT(aWorkerPrivate);
aWorkerPrivate->AssertIsOnWorkerThread();
MOZ_ASSERT(!mWorkerHolder);
mWorkerHolder.reset(new FetchBodyWorkerHolder<Derived>(this));
if (!mWorkerHolder->HoldWorker(aWorkerPrivate, Closing)) {
NS_WARNING("Failed to add workerHolder");
mWorkerHolder = nullptr;
return false;
}
return true;
}
} // namespace dom
} // namespace mozilla

66
dom/fetch/FetchConsumer.h Normal file
Просмотреть файл

@ -0,0 +1,66 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_FetchConsumer_h
#define mozilla_dom_FetchConsumer_h
class nsIThread;
namespace mozilla {
namespace dom {
namespace workers {
class WorkerPrivate;
class WorkerHolder;
}
template <class Derived> class FetchBody;
// FetchBody is not thread-safe but we need to move it around threads.
// In order to keep it alive all the time, we use a WorkerHolder, if created on
// workers, plus a wrapper.
template <class Derived>
class FetchBodyWrapper final
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FetchBodyWrapper<Derived>)
static already_AddRefed<FetchBodyWrapper<Derived>>
Create(FetchBody<Derived>* aBody);
void
ReleaseObject();
FetchBody<Derived>*
Body() const
{
return mBody;
}
private:
explicit FetchBodyWrapper(FetchBody<Derived>* aBody);
~FetchBodyWrapper();
void
AssertIsOnTargetThread() const;
bool
RegisterWorkerHolder(workers::WorkerPrivate* aWorkerPrivate);
nsCOMPtr<nsIThread> mTargetThread;
RefPtr<FetchBody<Derived>> mBody;
// Set when consuming the body is attempted on a worker.
// Unset when consumption is done/aborted.
// This WorkerHolder keeps alive the wrapper via a cycle.
UniquePtr<workers::WorkerHolder> mWorkerHolder;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_FetchConsumer_h

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

@ -29,6 +29,7 @@ UNIFIED_SOURCES += [
'BodyExtractor.cpp',
'ChannelInfo.cpp',
'Fetch.cpp',
'FetchConsumer.cpp',
'FetchController.cpp',
'FetchDriver.cpp',
'FetchObserver.cpp',