зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1373555 - Move the Fetch consume body login in a separate class - part 1 - separate files, r=bkelly
This commit is contained in:
Родитель
e768233bc4
Коммит
349f7847d7
|
@ -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.
|
||||
|
|
|
@ -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
|
|
@ -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',
|
||||
|
|
Загрузка…
Ссылка в новой задаче