forked from mirrors/gecko-dev
Backed out 22 changesets (bug 1231213) for build bustages on RemoteWorkerChild.cpp . CLOSED TREE
Backed out changeset 6f25a7e73fe2 (bug 1231213) Backed out changeset 5e88c3855fb6 (bug 1231213) Backed out changeset a78d7b3e44af (bug 1231213) Backed out changeset eb7f3a9b0a42 (bug 1231213) Backed out changeset 87575a180ad5 (bug 1231213) Backed out changeset 4e8369314e87 (bug 1231213) Backed out changeset 039c34bc043c (bug 1231213) Backed out changeset 0528ab68d94e (bug 1231213) Backed out changeset 670e7d61d95c (bug 1231213) Backed out changeset d61b9d65bd0a (bug 1231213) Backed out changeset 9042ea694d40 (bug 1231213) Backed out changeset bc0607e0d50b (bug 1231213) Backed out changeset 196ee18781cb (bug 1231213) Backed out changeset 4b588dec466b (bug 1231213) Backed out changeset be6031a6fca7 (bug 1231213) Backed out changeset 12e04c22f52f (bug 1231213) Backed out changeset fd146f327f2d (bug 1231213) Backed out changeset f2af7b66f50d (bug 1231213) Backed out changeset 71d93fc98d3f (bug 1231213) Backed out changeset 280271806864 (bug 1231213) Backed out changeset ca4e828345a2 (bug 1231213) Backed out changeset e41b984510ad (bug 1231213)
This commit is contained in:
parent
9f7e12ee62
commit
f53affe1cb
79 changed files with 706 additions and 7646 deletions
|
|
@ -19,6 +19,4 @@ UNIFIED_SOURCES += [
|
|||
'AbortSignal.cpp',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
|
|
|||
|
|
@ -52,6 +52,4 @@ MOCHITEST_MANIFESTS += [ 'tests/mochitest.ini' ]
|
|||
MOCHITEST_CHROME_MANIFESTS += [ 'tests/chrome.ini' ]
|
||||
XPCSHELL_TESTS_MANIFESTS += ['tests/xpcshell/xpcshell.ini']
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
|
|
|||
|
|
@ -7,57 +7,15 @@ include ChannelInfo;
|
|||
include PBackgroundSharedTypes;
|
||||
|
||||
using HeadersGuardEnum from "mozilla/dom/FetchIPCTypes.h";
|
||||
using ReferrerPolicy from "mozilla/dom/FetchIPCTypes.h";
|
||||
using RequestCache from "mozilla/dom/FetchIPCTypes.h";
|
||||
using RequestCredentials from "mozilla/dom/FetchIPCTypes.h";
|
||||
using RequestMode from "mozilla/dom/FetchIPCTypes.h";
|
||||
using RequestRedirect from "mozilla/dom/FetchIPCTypes.h";
|
||||
using ResponseType from "mozilla/dom/FetchIPCTypes.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
struct HeadersEntry {
|
||||
struct HeadersEntry
|
||||
{
|
||||
nsCString name;
|
||||
nsCString value;
|
||||
};
|
||||
|
||||
struct IPCInternalRequest {
|
||||
nsCString method;
|
||||
nsCString[] urlList;
|
||||
HeadersGuardEnum headersGuard;
|
||||
HeadersEntry[] headers;
|
||||
IPCStream? body;
|
||||
int64_t bodySize;
|
||||
nsCString preferredAlternativeDataType;
|
||||
uint32_t contentPolicyType;
|
||||
nsString referrer;
|
||||
ReferrerPolicy referrerPolicy;
|
||||
RequestMode requestMode;
|
||||
RequestCredentials requestCredentials;
|
||||
RequestCache cacheMode;
|
||||
RequestRedirect requestRedirect;
|
||||
nsString integrity;
|
||||
nsCString fragment;
|
||||
bool createdByFetchEvent;
|
||||
PrincipalInfo? principalInfo;
|
||||
};
|
||||
|
||||
struct IPCInternalResponse {
|
||||
ResponseType type;
|
||||
nsCString[] urlList;
|
||||
uint16_t status;
|
||||
nsCString statusText;
|
||||
HeadersGuardEnum headersGuard;
|
||||
HeadersEntry[] headers;
|
||||
IPCStream? body;
|
||||
int64_t bodySize;
|
||||
nsresult errorCode;
|
||||
nsCString alternativeDataType;
|
||||
IPCStream? alternativeBody;
|
||||
IPCChannelInfo channelInfo;
|
||||
PrincipalInfo? principalInfo;
|
||||
};
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace mozilla
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@
|
|||
|
||||
#include "mozilla/dom/WorkerCommon.h"
|
||||
#include "mozilla/dom/WorkerPrivate.h"
|
||||
#include "mozilla/ipc/IPCStreamUtils.h"
|
||||
#include "mozilla/ipc/PBackgroundChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
|
@ -173,73 +171,8 @@ InternalRequest::InternalRequest(const InternalRequest& aOther)
|
|||
// NOTE: does not copy body stream... use the fallible Clone() for that
|
||||
}
|
||||
|
||||
InternalRequest::InternalRequest(const IPCInternalRequest& aIPCRequest)
|
||||
: mMethod(aIPCRequest.method()),
|
||||
mURLList(aIPCRequest.urlList()),
|
||||
mHeaders(new InternalHeaders(aIPCRequest.headers(),
|
||||
aIPCRequest.headersGuard())),
|
||||
mBodyStream(mozilla::ipc::DeserializeIPCStream(aIPCRequest.body())),
|
||||
mBodyLength(aIPCRequest.bodySize()),
|
||||
mPreferredAlternativeDataType(aIPCRequest.preferredAlternativeDataType()),
|
||||
mContentPolicyType(
|
||||
static_cast<nsContentPolicyType>(aIPCRequest.contentPolicyType())),
|
||||
mReferrer(aIPCRequest.referrer()),
|
||||
mReferrerPolicy(aIPCRequest.referrerPolicy()),
|
||||
mMode(aIPCRequest.requestMode()),
|
||||
mCredentialsMode(aIPCRequest.requestCredentials()),
|
||||
mCacheMode(aIPCRequest.cacheMode()),
|
||||
mRedirectMode(aIPCRequest.requestRedirect()),
|
||||
mIntegrity(aIPCRequest.integrity()),
|
||||
mFragment(aIPCRequest.fragment()),
|
||||
mCreatedByFetchEvent(aIPCRequest.createdByFetchEvent()) {
|
||||
if (aIPCRequest.principalInfo()) {
|
||||
mPrincipalInfo = MakeUnique<mozilla::ipc::PrincipalInfo>(
|
||||
aIPCRequest.principalInfo().ref());
|
||||
}
|
||||
}
|
||||
|
||||
InternalRequest::~InternalRequest() {}
|
||||
|
||||
template void InternalRequest::ToIPC<mozilla::ipc::PBackgroundChild>(
|
||||
IPCInternalRequest* aIPCRequest, mozilla::ipc::PBackgroundChild* aManager,
|
||||
UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoStream);
|
||||
|
||||
template <typename M>
|
||||
void InternalRequest::ToIPC(
|
||||
IPCInternalRequest* aIPCRequest, M* aManager,
|
||||
UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoStream) {
|
||||
MOZ_ASSERT(aIPCRequest);
|
||||
MOZ_ASSERT(aManager);
|
||||
MOZ_ASSERT(!mURLList.IsEmpty());
|
||||
|
||||
aIPCRequest->method() = mMethod;
|
||||
aIPCRequest->urlList() = mURLList;
|
||||
mHeaders->ToIPC(aIPCRequest->headers(), aIPCRequest->headersGuard());
|
||||
|
||||
if (mBodyStream) {
|
||||
aAutoStream.reset(new mozilla::ipc::AutoIPCStream(aIPCRequest->body()));
|
||||
DebugOnly<bool> ok = aAutoStream->Serialize(mBodyStream, aManager);
|
||||
MOZ_ASSERT(ok);
|
||||
}
|
||||
|
||||
aIPCRequest->bodySize() = mBodyLength;
|
||||
aIPCRequest->preferredAlternativeDataType() = mPreferredAlternativeDataType;
|
||||
aIPCRequest->contentPolicyType() = static_cast<uint32_t>(mContentPolicyType);
|
||||
aIPCRequest->referrer() = mReferrer;
|
||||
aIPCRequest->referrerPolicy() = mReferrerPolicy;
|
||||
aIPCRequest->requestMode() = mMode;
|
||||
aIPCRequest->requestCredentials() = mCredentialsMode;
|
||||
aIPCRequest->cacheMode() = mCacheMode;
|
||||
aIPCRequest->requestRedirect() = mRedirectMode;
|
||||
aIPCRequest->integrity() = mIntegrity;
|
||||
aIPCRequest->fragment() = mFragment;
|
||||
aIPCRequest->createdByFetchEvent() = mCreatedByFetchEvent;
|
||||
|
||||
if (mPrincipalInfo) {
|
||||
aIPCRequest->principalInfo().emplace(*mPrincipalInfo);
|
||||
}
|
||||
}
|
||||
|
||||
void InternalRequest::SetContentPolicyType(
|
||||
nsContentPolicyType aContentPolicyType) {
|
||||
mContentPolicyType = aContentPolicyType;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@
|
|||
#include "mozilla/dom/RequestBinding.h"
|
||||
#include "mozilla/LoadTainting.h"
|
||||
#include "mozilla/net/ReferrerPolicy.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
#include "nsIContentPolicy.h"
|
||||
#include "nsIInputStream.h"
|
||||
|
|
@ -27,7 +26,6 @@ namespace mozilla {
|
|||
|
||||
namespace ipc {
|
||||
class PrincipalInfo;
|
||||
class AutoIPCStream;
|
||||
} // namespace ipc
|
||||
|
||||
namespace dom {
|
||||
|
|
@ -70,7 +68,6 @@ namespace dom {
|
|||
*
|
||||
*/
|
||||
|
||||
class IPCInternalRequest;
|
||||
class Request;
|
||||
|
||||
#define kFETCH_CLIENT_REFERRER_STR "about:client"
|
||||
|
|
@ -90,12 +87,6 @@ class InternalRequest final {
|
|||
nsContentPolicyType aContentPolicyType,
|
||||
const nsAString& aIntegrity);
|
||||
|
||||
explicit InternalRequest(const IPCInternalRequest& aIPCRequest);
|
||||
|
||||
template <typename M>
|
||||
void ToIPC(IPCInternalRequest* aIPCRequest, M* aManager,
|
||||
UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoStream);
|
||||
|
||||
already_AddRefed<InternalRequest> Clone();
|
||||
|
||||
void GetMethod(nsCString& aMethod) const { aMethod.Assign(mMethod); }
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@
|
|||
#include "InternalResponse.h"
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/dom/FetchTypes.h"
|
||||
#include "mozilla/dom/InternalHeaders.h"
|
||||
#include "mozilla/dom/cache/CacheTypes.h"
|
||||
#include "mozilla/ipc/PBackgroundSharedTypes.h"
|
||||
|
|
@ -41,112 +39,8 @@ InternalResponse::InternalResponse(uint16_t aStatus,
|
|||
mErrorCode(NS_OK),
|
||||
mCredentialsMode(aCredentialsMode) {}
|
||||
|
||||
/* static */ RefPtr<InternalResponse> InternalResponse::FromIPC(
|
||||
const IPCInternalResponse& aIPCResponse) {
|
||||
if (aIPCResponse.type() == ResponseType::Error) {
|
||||
return InternalResponse::NetworkError(aIPCResponse.errorCode());
|
||||
}
|
||||
|
||||
RefPtr<InternalResponse> response =
|
||||
new InternalResponse(aIPCResponse.status(), aIPCResponse.statusText());
|
||||
|
||||
response->SetURLList(aIPCResponse.urlList());
|
||||
response->mHeaders =
|
||||
new InternalHeaders(aIPCResponse.headers(), aIPCResponse.headersGuard());
|
||||
|
||||
nsCOMPtr<nsIInputStream> body =
|
||||
mozilla::ipc::DeserializeIPCStream(aIPCResponse.body());
|
||||
response->SetBody(body, aIPCResponse.bodySize());
|
||||
|
||||
response->SetAlternativeDataType(aIPCResponse.alternativeDataType());
|
||||
|
||||
nsCOMPtr<nsIInputStream> alternativeBody =
|
||||
mozilla::ipc::DeserializeIPCStream(aIPCResponse.alternativeBody());
|
||||
response->SetAlternativeBody(alternativeBody);
|
||||
|
||||
response->InitChannelInfo(aIPCResponse.channelInfo());
|
||||
|
||||
if (aIPCResponse.principalInfo()) {
|
||||
response->SetPrincipalInfo(MakeUnique<mozilla::ipc::PrincipalInfo>(
|
||||
aIPCResponse.principalInfo().ref()));
|
||||
}
|
||||
|
||||
switch (aIPCResponse.type()) {
|
||||
case ResponseType::Basic:
|
||||
response = response->BasicResponse();
|
||||
break;
|
||||
case ResponseType::Cors:
|
||||
response = response->CORSResponse();
|
||||
break;
|
||||
case ResponseType::Default:
|
||||
break;
|
||||
case ResponseType::Opaque:
|
||||
response = response->OpaqueResponse();
|
||||
break;
|
||||
case ResponseType::Opaqueredirect:
|
||||
response = response->OpaqueRedirectResponse();
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Unexpected ResponseType!");
|
||||
}
|
||||
|
||||
MOZ_ASSERT(response);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
InternalResponse::~InternalResponse() {}
|
||||
|
||||
template void InternalResponse::ToIPC<mozilla::ipc::PBackgroundChild>(
|
||||
IPCInternalResponse* aIPCResponse, mozilla::ipc::PBackgroundChild* aManager,
|
||||
UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoBodyStream,
|
||||
UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoAlternativeBodyStream);
|
||||
|
||||
template <typename M>
|
||||
void InternalResponse::ToIPC(
|
||||
IPCInternalResponse* aIPCResponse, M* aManager,
|
||||
UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoBodyStream,
|
||||
UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoAlternativeBodyStream) {
|
||||
MOZ_ASSERT(aIPCResponse);
|
||||
|
||||
aIPCResponse->type() = mType;
|
||||
GetUnfilteredURLList(aIPCResponse->urlList());
|
||||
aIPCResponse->status() = GetUnfilteredStatus();
|
||||
aIPCResponse->statusText() = GetUnfilteredStatusText();
|
||||
UnfilteredHeaders()->ToIPC(aIPCResponse->headers(),
|
||||
aIPCResponse->headersGuard());
|
||||
|
||||
nsCOMPtr<nsIInputStream> body;
|
||||
int64_t bodySize;
|
||||
GetUnfilteredBody(getter_AddRefs(body), &bodySize);
|
||||
|
||||
if (body) {
|
||||
aAutoBodyStream.reset(
|
||||
new mozilla::ipc::AutoIPCStream(aIPCResponse->body()));
|
||||
DebugOnly<bool> ok = aAutoBodyStream->Serialize(body, aManager);
|
||||
MOZ_ASSERT(ok);
|
||||
}
|
||||
|
||||
aIPCResponse->bodySize() = bodySize;
|
||||
aIPCResponse->errorCode() = mErrorCode;
|
||||
aIPCResponse->alternativeDataType() = GetAlternativeDataType();
|
||||
|
||||
nsCOMPtr<nsIInputStream> alternativeBody = TakeAlternativeBody();
|
||||
if (alternativeBody) {
|
||||
aAutoAlternativeBodyStream.reset(
|
||||
new mozilla::ipc::AutoIPCStream(aIPCResponse->alternativeBody()));
|
||||
DebugOnly<bool> ok =
|
||||
aAutoAlternativeBodyStream->Serialize(alternativeBody, aManager);
|
||||
MOZ_ASSERT(ok);
|
||||
}
|
||||
|
||||
aIPCResponse->channelInfo() = mChannelInfo.AsIPCChannelInfo();
|
||||
|
||||
if (mPrincipalInfo) {
|
||||
aIPCResponse->principalInfo().emplace(*mPrincipalInfo);
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<InternalResponse> InternalResponse::Clone(
|
||||
CloneType aCloneType) {
|
||||
RefPtr<InternalResponse> clone = CreateIncompleteCopy();
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ class AutoIPCStream;
|
|||
|
||||
namespace dom {
|
||||
|
||||
class IPCInternalResponse;
|
||||
class InternalHeaders;
|
||||
|
||||
class InternalResponse final {
|
||||
|
|
@ -39,15 +38,6 @@ class InternalResponse final {
|
|||
uint16_t aStatus, const nsACString& aStatusText,
|
||||
RequestCredentials aCredentialsMode = RequestCredentials::Omit);
|
||||
|
||||
static RefPtr<InternalResponse> FromIPC(
|
||||
const IPCInternalResponse& aIPCResponse);
|
||||
|
||||
template <typename M>
|
||||
void ToIPC(
|
||||
IPCInternalResponse* aIPCResponse, M* aManager,
|
||||
UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoBodyStream,
|
||||
UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoAlternativeBodyStream);
|
||||
|
||||
enum CloneType {
|
||||
eCloneInputStream,
|
||||
eDontCloneInputStream,
|
||||
|
|
@ -221,24 +211,6 @@ class InternalResponse final {
|
|||
|
||||
void SetPaddingSize(int64_t aPaddingSize);
|
||||
|
||||
void SetAlternativeDataType(const nsACString& aAltDataType) {
|
||||
if (mWrappedResponse) {
|
||||
return mWrappedResponse->SetAlternativeDataType(aAltDataType);
|
||||
}
|
||||
|
||||
MOZ_DIAGNOSTIC_ASSERT(mAlternativeDataType.IsEmpty());
|
||||
|
||||
mAlternativeDataType.Assign(aAltDataType);
|
||||
}
|
||||
|
||||
const nsCString& GetAlternativeDataType() {
|
||||
if (mWrappedResponse) {
|
||||
return mWrappedResponse->GetAlternativeDataType();
|
||||
}
|
||||
|
||||
return mAlternativeDataType;
|
||||
}
|
||||
|
||||
void SetAlternativeBody(nsIInputStream* aAlternativeBody) {
|
||||
if (mWrappedResponse) {
|
||||
return mWrappedResponse->SetAlternativeBody(aAlternativeBody);
|
||||
|
|
@ -351,7 +323,6 @@ class InternalResponse final {
|
|||
RequestCredentials mCredentialsMode;
|
||||
|
||||
// For alternative data such as JS Bytecode cached in the HTTP cache.
|
||||
nsCString mAlternativeDataType;
|
||||
nsCOMPtr<nsIInputStream> mAlternativeBody;
|
||||
nsMainThreadPtrHandle<nsICacheInfoChannel> mCacheInfoChannel;
|
||||
|
||||
|
|
|
|||
|
|
@ -1382,32 +1382,6 @@ RemoteWindowContext::GetUsePrivateBrowsing(bool* aUsePrivateBrowsing) {
|
|||
|
||||
} // namespace
|
||||
|
||||
void ContentParent::MaybeAsyncSendShutDownMessage() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!TryToRecycle());
|
||||
|
||||
#ifdef DEBUG
|
||||
// Calling this below while the lock is acquired will deadlock.
|
||||
bool shouldKeepProcessAlive = ShouldKeepProcessAlive();
|
||||
#endif
|
||||
|
||||
auto lock = mRemoteWorkerActorData.Lock();
|
||||
MOZ_ASSERT_IF(!lock->mCount, !shouldKeepProcessAlive);
|
||||
|
||||
if (lock->mCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!lock->mShutdownStarted);
|
||||
lock->mShutdownStarted = true;
|
||||
|
||||
// In the case of normal shutdown, send a shutdown message to child to
|
||||
// allow it to perform shutdown tasks.
|
||||
MessageLoop::current()->PostTask(NewRunnableMethod<ShutDownMethod>(
|
||||
"dom::ContentParent::ShutDownProcess", this,
|
||||
&ContentParent::ShutDownProcess, SEND_SHUTDOWN_MESSAGE));
|
||||
}
|
||||
|
||||
void ContentParent::ShutDownProcess(ShutDownMethod aMethod) {
|
||||
if (mScriptableHelper) {
|
||||
static_cast<ScriptableCPInfo*>(mScriptableHelper.get())->ProcessDied();
|
||||
|
|
@ -1752,18 +1726,15 @@ bool ContentParent::TryToRecycle() {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ContentParent::ShouldKeepProcessAlive() {
|
||||
bool ContentParent::ShouldKeepProcessAlive() const {
|
||||
if (IsForJSPlugin()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we have active workers, we need to stay alive.
|
||||
{
|
||||
const auto lock = mRemoteWorkerActorData.Lock();
|
||||
if (lock->mCount) {
|
||||
if (mRemoteWorkerActors) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sBrowserContentParents) {
|
||||
return false;
|
||||
|
|
@ -1874,7 +1845,11 @@ void ContentParent::NotifyTabDestroyed(const TabId& aTabId,
|
|||
// us down.
|
||||
if (ManagedPBrowserParent().Count() == 1 && !ShouldKeepProcessAlive() &&
|
||||
!TryToRecycle()) {
|
||||
MaybeAsyncSendShutDownMessage();
|
||||
// In the case of normal shutdown, send a shutdown message to child to
|
||||
// allow it to perform shutdown tasks.
|
||||
MessageLoop::current()->PostTask(NewRunnableMethod<ShutDownMethod>(
|
||||
"dom::ContentParent::ShutDownProcess", this,
|
||||
&ContentParent::ShutDownProcess, SEND_SHUTDOWN_MESSAGE));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2299,7 +2274,7 @@ ContentParent::ContentParent(ContentParent* aOpener,
|
|||
mChildID(gContentChildID++),
|
||||
mGeolocationWatchID(-1),
|
||||
mJSPluginID(aJSPluginID),
|
||||
mRemoteWorkerActorData("ContentParent::mRemoteWorkerActorData"),
|
||||
mRemoteWorkerActors(0),
|
||||
mNumDestroyingTabs(0),
|
||||
mLifecycleState(LifecycleState::LAUNCHING),
|
||||
mIsForBrowser(!mRemoteType.IsEmpty()),
|
||||
|
|
@ -5934,25 +5909,23 @@ mozilla::ipc::IPCResult ContentParent::RecvRestoreBrowsingContextChildren(
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
void ContentParent::RegisterRemoteWorkerActor() {
|
||||
auto lock = mRemoteWorkerActorData.Lock();
|
||||
++lock->mCount;
|
||||
}
|
||||
void ContentParent::RegisterRemoteWorkerActor() { ++mRemoteWorkerActors; }
|
||||
|
||||
void ContentParent::UnregisterRemoveWorkerActor() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
{
|
||||
auto lock = mRemoteWorkerActorData.Lock();
|
||||
if (--lock->mCount) {
|
||||
if (--mRemoteWorkerActors) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
|
||||
if (!cpm->GetBrowserParentCountByProcessId(ChildID()) &&
|
||||
!ShouldKeepProcessAlive() && !TryToRecycle()) {
|
||||
MaybeAsyncSendShutDownMessage();
|
||||
// In the case of normal shutdown, send a shutdown message to child to
|
||||
// allow it to perform shutdown tasks.
|
||||
MessageLoop::current()->PostTask(NewRunnableMethod<ShutDownMethod>(
|
||||
"dom::ContentParent::ShutDownProcess", this,
|
||||
&ContentParent::ShutDownProcess, SEND_SHUTDOWN_MESSAGE));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
#include "mozilla/ipc/PParentToChildStreamParent.h"
|
||||
#include "mozilla/ipc/PChildToParentStreamParent.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/DataMutex.h"
|
||||
#include "mozilla/FileUtils.h"
|
||||
#include "mozilla/HalTypes.h"
|
||||
#include "mozilla/LinkedList.h"
|
||||
|
|
@ -115,7 +114,6 @@ class MemoryReport;
|
|||
class TabContext;
|
||||
class GetFilesHelper;
|
||||
class MemoryReportRequestHost;
|
||||
class RemoteWorkerManager;
|
||||
struct CancelContentJSOptions;
|
||||
|
||||
#define NS_CONTENTPARENT_IID \
|
||||
|
|
@ -147,7 +145,6 @@ class ContentParent final : public PContentParent,
|
|||
|
||||
friend class mozilla::PreallocatedProcessManagerImpl;
|
||||
friend class PContentParent;
|
||||
friend class mozilla::dom::RemoteWorkerManager;
|
||||
#ifdef FUZZING
|
||||
friend class mozilla::ipc::ProtocolFuzzerHelper;
|
||||
#endif
|
||||
|
|
@ -751,7 +748,7 @@ class ContentParent final : public PContentParent,
|
|||
* Decide whether the process should be kept alive even when it would normally
|
||||
* be shut down, for example when all its tabs are closed.
|
||||
*/
|
||||
bool ShouldKeepProcessAlive();
|
||||
bool ShouldKeepProcessAlive() const;
|
||||
|
||||
/**
|
||||
* Mark this ContentParent as "troubled". This means that it is still alive,
|
||||
|
|
@ -777,8 +774,6 @@ class ContentParent final : public PContentParent,
|
|||
CLOSE_CHANNEL_WITH_ERROR,
|
||||
};
|
||||
|
||||
void MaybeAsyncSendShutDownMessage();
|
||||
|
||||
/**
|
||||
* Exit the subprocess and vamoose. After this call IsAlive()
|
||||
* will return false and this ContentParent will not be returned
|
||||
|
|
@ -1241,24 +1236,11 @@ class ContentParent final : public PContentParent,
|
|||
// timer.
|
||||
nsCOMPtr<nsITimer> mForceKillTimer;
|
||||
|
||||
// `mCount` is increased when a RemoteWorkerParent actor is created for this
|
||||
// ContentProcess and it is decreased when the actor is destroyed.
|
||||
//
|
||||
// `mShutdownStarted` is flipped to `true` when a runnable that calls
|
||||
// `ShutDownProcess` is dispatched; it's needed because the corresponding
|
||||
// Content Process may be shutdown if there's no remote worker actors, and
|
||||
// decrementing `mCount` and the call to `ShutDownProcess` are async. So,
|
||||
// when a worker is going to be spawned and we see that `mCount` is 0,
|
||||
// we can decide whether or not to use that process based on the value of
|
||||
// `mShutdownStarted.`
|
||||
//
|
||||
// Number of active remote workers. This value is increased when a
|
||||
// RemoteWorkerParent actor is created for this ContentProcess and it is
|
||||
// decreased when the actor is destroyed.
|
||||
// It's touched on PBackground thread and on main-thread.
|
||||
struct RemoteWorkerActorData {
|
||||
uint32_t mCount = 0;
|
||||
bool mShutdownStarted = false;
|
||||
};
|
||||
|
||||
DataMutex<RemoteWorkerActorData> mRemoteWorkerActorData;
|
||||
Atomic<uint32_t> mRemoteWorkerActors;
|
||||
|
||||
// How many tabs we're waiting to finish their destruction
|
||||
// sequence. Precisely, how many BrowserParents have called
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class IPCURLClassifierFeature;
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// URLClassifierParent
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ using TabId from "mozilla/dom/ipc/IdType.h";
|
|||
|
||||
// ParamTraits stuff for our own classes
|
||||
using MediaPacket from "mtransport/mediapacket.h";
|
||||
include "mozilla/net/NrIceStunAddrMessageUtils.h";
|
||||
using net::NrIceStunAddrArray from "mozilla/net/PStunAddrsParams.h";
|
||||
#endif // MOZ_WEBRTC
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
#include "mozilla/dom/PromiseWorkerProxy.h"
|
||||
#include "mozilla/dom/ServiceWorkerGlobalScopeBinding.h"
|
||||
#include "mozilla/dom/ServiceWorkerManager.h"
|
||||
#include "mozilla/dom/ServiceWorkerUtils.h"
|
||||
#include "mozilla/dom/WorkerPrivate.h"
|
||||
#include "mozilla/dom/WorkerRunnable.h"
|
||||
#include "mozilla/dom/WorkerScope.h"
|
||||
|
|
|
|||
|
|
@ -42,8 +42,6 @@ UNIFIED_SOURCES += [
|
|||
'PerformanceWorker.cpp',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
MOCHITEST_MANIFESTS += [ 'tests/mochitest.ini' ]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
|
|
|||
|
|
@ -1,487 +0,0 @@
|
|||
/* -*- 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 "FetchEventOpChild.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "MainThreadUtils.h"
|
||||
#include "nsContentPolicyUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsError.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIConsoleReportCollector.h"
|
||||
#include "nsIContentPolicy.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsILoadInfo.h"
|
||||
#include "nsINetworkInterceptController.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsProxyRelease.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
#include "ServiceWorkerPrivate.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/LoadInfo.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/dom/InternalHeaders.h"
|
||||
#include "mozilla/dom/InternalResponse.h"
|
||||
#include "mozilla/dom/PRemoteWorkerControllerChild.h"
|
||||
#include "mozilla/dom/ServiceWorkerRegistrationInfo.h"
|
||||
#include "mozilla/net/NeckoChannelParams.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
namespace {
|
||||
|
||||
bool CSPPermitsResponse(nsILoadInfo* aLoadInfo, InternalResponse* aResponse,
|
||||
const nsACString& aWorkerScriptSpec) {
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aLoadInfo);
|
||||
|
||||
nsCString url = aResponse->GetUnfilteredURL();
|
||||
if (url.IsEmpty()) {
|
||||
// Synthetic response.
|
||||
url = aWorkerScriptSpec;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(uri), url, nullptr, nullptr);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int16_t decision = nsIContentPolicy::ACCEPT;
|
||||
rv = NS_CheckContentLoadPolicy(uri, aLoadInfo, EmptyCString(), &decision);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return decision == nsIContentPolicy::ACCEPT;
|
||||
}
|
||||
|
||||
void AsyncLog(nsIInterceptedChannel* aChannel, const nsACString& aScriptSpec,
|
||||
uint32_t aLineNumber, uint32_t aColumnNumber,
|
||||
const nsACString& aMessageName, nsTArray<nsString>&& aParams) {
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aChannel);
|
||||
|
||||
nsCOMPtr<nsIConsoleReportCollector> reporter =
|
||||
aChannel->GetConsoleReportCollector();
|
||||
|
||||
if (reporter) {
|
||||
// NOTE: is appears that `const nsTArray<nsString>&` is required for
|
||||
// nsIConsoleReportCollector::AddConsoleReport to resolve to the correct
|
||||
// overload.
|
||||
const nsTArray<nsString> params = std::move(aParams);
|
||||
|
||||
reporter->AddConsoleReport(
|
||||
nsIScriptError::errorFlag,
|
||||
NS_LITERAL_CSTRING("Service Worker Interception"),
|
||||
nsContentUtils::eDOM_PROPERTIES, aScriptSpec, aLineNumber,
|
||||
aColumnNumber, aMessageName, params);
|
||||
}
|
||||
}
|
||||
|
||||
class SynthesizeResponseWatcher final : public nsIInterceptedBodyCallback {
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
||||
SynthesizeResponseWatcher(
|
||||
const nsMainThreadPtrHandle<nsIInterceptedChannel>& aInterceptedChannel,
|
||||
const nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo>& aRegistration,
|
||||
const bool aIsNonSubresourceRequest,
|
||||
FetchEventRespondWithClosure&& aClosure, nsAString&& aRequestURL)
|
||||
: mInterceptedChannel(aInterceptedChannel),
|
||||
mRegistration(aRegistration),
|
||||
mIsNonSubresourceRequest(aIsNonSubresourceRequest),
|
||||
mClosure(std::move(aClosure)),
|
||||
mRequestURL(std::move(aRequestURL)) {
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(mInterceptedChannel);
|
||||
MOZ_ASSERT(mRegistration);
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
BodyComplete(nsresult aRv) override {
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(mInterceptedChannel);
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(aRv))) {
|
||||
AsyncLog(mInterceptedChannel, mClosure.respondWithScriptSpec(),
|
||||
mClosure.respondWithLineNumber(),
|
||||
mClosure.respondWithColumnNumber(),
|
||||
NS_LITERAL_CSTRING("InterceptionFailedWithURL"), {mRequestURL});
|
||||
|
||||
CancelInterception(NS_ERROR_INTERCEPTION_FAILED);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv = mInterceptedChannel->FinishSynthesizedResponse();
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
CancelInterception(rv);
|
||||
}
|
||||
|
||||
mInterceptedChannel = nullptr;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// See FetchEventOpChild::MaybeScheduleRegistrationUpdate() for comments.
|
||||
void CancelInterception(nsresult aStatus) {
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(mInterceptedChannel);
|
||||
MOZ_ASSERT(mRegistration);
|
||||
|
||||
mInterceptedChannel->CancelInterception(aStatus);
|
||||
|
||||
if (mIsNonSubresourceRequest) {
|
||||
mRegistration->MaybeScheduleUpdate();
|
||||
} else {
|
||||
mRegistration->MaybeScheduleTimeCheckAndUpdate();
|
||||
}
|
||||
|
||||
mInterceptedChannel = nullptr;
|
||||
mRegistration = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
~SynthesizeResponseWatcher() {
|
||||
if (NS_WARN_IF(mInterceptedChannel)) {
|
||||
CancelInterception(NS_ERROR_DOM_ABORT_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
nsMainThreadPtrHandle<nsIInterceptedChannel> mInterceptedChannel;
|
||||
nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> mRegistration;
|
||||
const bool mIsNonSubresourceRequest;
|
||||
const FetchEventRespondWithClosure mClosure;
|
||||
const nsString mRequestURL;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(SynthesizeResponseWatcher, nsIInterceptedBodyCallback)
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* static */ RefPtr<GenericPromise> FetchEventOpChild::Create(
|
||||
PRemoteWorkerControllerChild* aManager,
|
||||
ServiceWorkerFetchEventOpArgs&& aArgs,
|
||||
nsCOMPtr<nsIInterceptedChannel> aInterceptedChannel,
|
||||
RefPtr<ServiceWorkerRegistrationInfo> aRegistration,
|
||||
RefPtr<KeepAliveToken>&& aKeepAliveToken) {
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aManager);
|
||||
MOZ_ASSERT(aInterceptedChannel);
|
||||
MOZ_ASSERT(aKeepAliveToken);
|
||||
|
||||
FetchEventOpChild* actor = new FetchEventOpChild(
|
||||
std::move(aArgs), std::move(aInterceptedChannel),
|
||||
std::move(aRegistration), std::move(aKeepAliveToken));
|
||||
Unused << aManager->SendPFetchEventOpConstructor(actor, actor->mArgs);
|
||||
return actor->mPromiseHolder.Ensure(__func__);
|
||||
}
|
||||
|
||||
FetchEventOpChild::~FetchEventOpChild() {
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(mInterceptedChannelHandled);
|
||||
MOZ_DIAGNOSTIC_ASSERT(mPromiseHolder.IsEmpty());
|
||||
}
|
||||
|
||||
FetchEventOpChild::FetchEventOpChild(
|
||||
ServiceWorkerFetchEventOpArgs&& aArgs,
|
||||
nsCOMPtr<nsIInterceptedChannel>&& aInterceptedChannel,
|
||||
RefPtr<ServiceWorkerRegistrationInfo>&& aRegistration,
|
||||
RefPtr<KeepAliveToken>&& aKeepAliveToken)
|
||||
: mArgs(std::move(aArgs)),
|
||||
mInterceptedChannel(std::move(aInterceptedChannel)),
|
||||
mRegistration(std::move(aRegistration)),
|
||||
mKeepAliveToken(std::move(aKeepAliveToken)) {}
|
||||
|
||||
mozilla::ipc::IPCResult FetchEventOpChild::RecvAsyncLog(
|
||||
const nsCString& aScriptSpec, const uint32_t& aLineNumber,
|
||||
const uint32_t& aColumnNumber, const nsCString& aMessageName,
|
||||
nsTArray<nsString>&& aParams) {
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(mInterceptedChannel);
|
||||
|
||||
AsyncLog(mInterceptedChannel, aScriptSpec, aLineNumber, aColumnNumber,
|
||||
aMessageName, std::move(aParams));
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult FetchEventOpChild::RecvRespondWith(
|
||||
IPCFetchEventRespondWithResult&& aResult) {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
switch (aResult.type()) {
|
||||
case IPCFetchEventRespondWithResult::TIPCSynthesizeResponseArgs:
|
||||
SynthesizeResponse(std::move(aResult.get_IPCSynthesizeResponseArgs()));
|
||||
break;
|
||||
case IPCFetchEventRespondWithResult::TResetInterceptionArgs:
|
||||
ResetInterception();
|
||||
break;
|
||||
case IPCFetchEventRespondWithResult::TCancelInterceptionArgs:
|
||||
CancelInterception(aResult.get_CancelInterceptionArgs().status());
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Unknown IPCFetchEventRespondWithResult type!");
|
||||
break;
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult FetchEventOpChild::Recv__delete__(
|
||||
const ServiceWorkerFetchEventOpResult& aResult) {
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(mRegistration);
|
||||
|
||||
if (NS_WARN_IF(!mInterceptedChannelHandled)) {
|
||||
MOZ_ASSERT(NS_FAILED(aResult.rv()));
|
||||
NS_WARNING(
|
||||
"Failed to handle intercepted network request; canceling "
|
||||
"interception!");
|
||||
|
||||
CancelInterception(aResult.rv());
|
||||
}
|
||||
|
||||
mPromiseHolder.ResolveIfExists(true, __func__);
|
||||
|
||||
/**
|
||||
* This corresponds to the "Fire Functional Event" algorithm's step 9:
|
||||
*
|
||||
* "If the time difference in seconds calculated by the current time minus
|
||||
* registration's last update check time is greater than 84600, invoke Soft
|
||||
* Update algorithm with registration."
|
||||
*
|
||||
* TODO: this is probably being called later than it should be; it should be
|
||||
* called ASAP after dispatching the FetchEvent.
|
||||
*/
|
||||
mRegistration->MaybeScheduleTimeCheckAndUpdate();
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void FetchEventOpChild::ActorDestroy(ActorDestroyReason) {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
// If `Recv__delete__` was called, it would have resolved the promise already.
|
||||
mPromiseHolder.RejectIfExists(NS_ERROR_DOM_ABORT_ERR, __func__);
|
||||
|
||||
if (NS_WARN_IF(!mInterceptedChannelHandled)) {
|
||||
Unused << Recv__delete__(NS_ERROR_DOM_ABORT_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult FetchEventOpChild::StartSynthesizedResponse(
|
||||
IPCSynthesizeResponseArgs&& aArgs) {
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(mInterceptedChannel);
|
||||
MOZ_ASSERT(!mInterceptedChannelHandled);
|
||||
MOZ_ASSERT(mRegistration);
|
||||
|
||||
/**
|
||||
* TODO: moving the IPCInternalResponse won't do anything right now because
|
||||
* there isn't a prefect-forwarding or rvalue-ref-parameter overload of
|
||||
* `InternalResponse::FromIPC().`
|
||||
*/
|
||||
RefPtr<InternalResponse> response =
|
||||
InternalResponse::FromIPC(aArgs.internalResponse());
|
||||
if (NS_WARN_IF(!response)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIChannel> underlyingChannel;
|
||||
nsresult rv =
|
||||
mInterceptedChannel->GetChannel(getter_AddRefs(underlyingChannel));
|
||||
if (NS_WARN_IF(NS_FAILED(rv)) || NS_WARN_IF(!underlyingChannel)) {
|
||||
return NS_FAILED(rv) ? rv : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = underlyingChannel->LoadInfo();
|
||||
if (!CSPPermitsResponse(loadInfo, response, mArgs.workerScriptSpec())) {
|
||||
return NS_ERROR_CONTENT_BLOCKED;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(response->GetChannelInfo().IsInitialized());
|
||||
ChannelInfo channelInfo = response->GetChannelInfo();
|
||||
rv = mInterceptedChannel->SetChannelInfo(&channelInfo);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NS_ERROR_INTERCEPTION_FAILED;
|
||||
}
|
||||
|
||||
rv = mInterceptedChannel->SynthesizeStatus(
|
||||
response->GetUnfilteredStatus(), response->GetUnfilteredStatusText());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
AutoTArray<InternalHeaders::Entry, 5> entries;
|
||||
response->UnfilteredHeaders()->GetEntries(entries);
|
||||
for (auto& entry : entries) {
|
||||
mInterceptedChannel->SynthesizeHeader(entry.mName, entry.mValue);
|
||||
}
|
||||
|
||||
auto castLoadInfo = static_cast<mozilla::net::LoadInfo*>(loadInfo.get());
|
||||
castLoadInfo->SynthesizeServiceWorkerTainting(response->GetTainting());
|
||||
|
||||
// Get the preferred alternative data type of the outer channel
|
||||
nsAutoCString preferredAltDataType(EmptyCString());
|
||||
nsCOMPtr<nsICacheInfoChannel> outerChannel =
|
||||
do_QueryInterface(underlyingChannel);
|
||||
if (outerChannel &&
|
||||
!outerChannel->PreferredAlternativeDataTypes().IsEmpty()) {
|
||||
preferredAltDataType.Assign(
|
||||
outerChannel->PreferredAlternativeDataTypes()[0].type());
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInputStream> body;
|
||||
if (preferredAltDataType.Equals(response->GetAlternativeDataType())) {
|
||||
body = response->TakeAlternativeBody();
|
||||
}
|
||||
if (!body) {
|
||||
response->GetUnfilteredBody(getter_AddRefs(body));
|
||||
} else {
|
||||
Telemetry::ScalarAdd(Telemetry::ScalarID::SW_ALTERNATIVE_BODY_USED_COUNT,
|
||||
1);
|
||||
}
|
||||
|
||||
// Propagate the URL to the content if the request mode is not "navigate".
|
||||
// Note that, we only reflect the final URL if the response.redirected is
|
||||
// false. We propagate all the URLs if the response.redirected is true.
|
||||
const IPCInternalRequest& request = mArgs.internalRequest();
|
||||
nsAutoCString responseURL;
|
||||
if (request.requestMode() != RequestMode::Navigate) {
|
||||
responseURL = response->GetUnfilteredURL();
|
||||
|
||||
// Similar to how we apply the request fragment to redirects automatically
|
||||
// we also want to apply it automatically when propagating the response
|
||||
// URL from a service worker interception. Currently response.url strips
|
||||
// the fragment, so this will never conflict with an existing fragment
|
||||
// on the response. In the future we will have to check for a response
|
||||
// fragment and avoid overriding in that case.
|
||||
if (!request.fragment().IsEmpty() && !responseURL.IsEmpty()) {
|
||||
MOZ_ASSERT(!responseURL.Contains('#'));
|
||||
responseURL.AppendLiteral("#");
|
||||
responseURL.Append(request.fragment());
|
||||
}
|
||||
}
|
||||
|
||||
nsMainThreadPtrHandle<nsIInterceptedChannel> interceptedChannel(
|
||||
new nsMainThreadPtrHolder<nsIInterceptedChannel>(
|
||||
"nsIInterceptedChannel", mInterceptedChannel, false));
|
||||
|
||||
nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> registration(
|
||||
new nsMainThreadPtrHolder<ServiceWorkerRegistrationInfo>(
|
||||
"ServiceWorkerRegistrationInfo", mRegistration, false));
|
||||
|
||||
nsCString requestURL = request.urlList().LastElement();
|
||||
if (!request.fragment().IsEmpty()) {
|
||||
requestURL.AppendLiteral("#");
|
||||
requestURL.Append(request.fragment());
|
||||
}
|
||||
|
||||
RefPtr<SynthesizeResponseWatcher> watcher = new SynthesizeResponseWatcher(
|
||||
interceptedChannel, registration, mArgs.isNonSubresourceRequest(),
|
||||
std::move(aArgs.closure()), NS_ConvertUTF8toUTF16(responseURL));
|
||||
|
||||
rv = mInterceptedChannel->StartSynthesizedResponse(
|
||||
body, watcher, nullptr /* TODO */, responseURL, response->IsRedirected());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserverService> obsService = services::GetObserverService();
|
||||
if (obsService) {
|
||||
obsService->NotifyObservers(underlyingChannel,
|
||||
"service-worker-synthesized-response", nullptr);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void FetchEventOpChild::SynthesizeResponse(IPCSynthesizeResponseArgs&& aArgs) {
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(mInterceptedChannel);
|
||||
MOZ_ASSERT(!mInterceptedChannelHandled);
|
||||
|
||||
nsresult rv = StartSynthesizedResponse(std::move(aArgs));
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
NS_WARNING("Failed to synthesize response!");
|
||||
|
||||
mInterceptedChannel->CancelInterception(rv);
|
||||
}
|
||||
|
||||
mInterceptedChannelHandled = true;
|
||||
|
||||
MaybeScheduleRegistrationUpdate();
|
||||
}
|
||||
|
||||
void FetchEventOpChild::ResetInterception() {
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(mInterceptedChannel);
|
||||
MOZ_ASSERT(!mInterceptedChannelHandled);
|
||||
|
||||
nsresult rv = mInterceptedChannel->ResetInterception();
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
NS_WARNING("Failed to resume intercepted network request!");
|
||||
|
||||
mInterceptedChannel->CancelInterception(rv);
|
||||
}
|
||||
|
||||
mInterceptedChannelHandled = true;
|
||||
|
||||
MaybeScheduleRegistrationUpdate();
|
||||
}
|
||||
|
||||
void FetchEventOpChild::CancelInterception(nsresult aStatus) {
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(mInterceptedChannel);
|
||||
MOZ_ASSERT(!mInterceptedChannelHandled);
|
||||
MOZ_ASSERT(NS_FAILED(aStatus));
|
||||
|
||||
mInterceptedChannel->CancelInterception(aStatus);
|
||||
mInterceptedChannelHandled = true;
|
||||
|
||||
MaybeScheduleRegistrationUpdate();
|
||||
}
|
||||
|
||||
/**
|
||||
* This corresponds to the "Handle Fetch" algorithm's steps 20.3, 21.2, and
|
||||
* 22.2:
|
||||
*
|
||||
* "If request is a non-subresource request, or request is a subresource
|
||||
* request and the time difference in seconds calculated by the current time
|
||||
* minus registration's last update check time is greater than 86400, invoke
|
||||
* Soft Update algorithm with registration."
|
||||
*/
|
||||
void FetchEventOpChild::MaybeScheduleRegistrationUpdate() const {
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(mRegistration);
|
||||
MOZ_ASSERT(mInterceptedChannelHandled);
|
||||
|
||||
if (mArgs.isNonSubresourceRequest()) {
|
||||
mRegistration->MaybeScheduleUpdate();
|
||||
} else {
|
||||
mRegistration->MaybeScheduleTimeCheckAndUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
/* -*- 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_fetcheventopchild_h__
|
||||
#define mozilla_dom_fetcheventopchild_h__
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#include "mozilla/MozPromise.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/dom/PFetchEventOpChild.h"
|
||||
#include "mozilla/dom/ServiceWorkerOpArgs.h"
|
||||
|
||||
class nsIInterceptedChannel;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class KeepAliveToken;
|
||||
class PRemoteWorkerControllerChild;
|
||||
class ServiceWorkerRegistrationInfo;
|
||||
|
||||
/**
|
||||
* FetchEventOpChild represents an in-flight FetchEvent operation.
|
||||
*/
|
||||
class FetchEventOpChild final : public PFetchEventOpChild {
|
||||
friend class PFetchEventOpChild;
|
||||
|
||||
public:
|
||||
static RefPtr<GenericPromise> Create(
|
||||
PRemoteWorkerControllerChild* aManager,
|
||||
ServiceWorkerFetchEventOpArgs&& aArgs,
|
||||
nsCOMPtr<nsIInterceptedChannel> aInterceptedChannel,
|
||||
RefPtr<ServiceWorkerRegistrationInfo> aRegistrationInfo,
|
||||
RefPtr<KeepAliveToken>&& aKeepAliveToken);
|
||||
|
||||
~FetchEventOpChild();
|
||||
|
||||
private:
|
||||
FetchEventOpChild(ServiceWorkerFetchEventOpArgs&& aArgs,
|
||||
nsCOMPtr<nsIInterceptedChannel>&& aInterceptedChannel,
|
||||
RefPtr<ServiceWorkerRegistrationInfo>&& aRegistrationInfo,
|
||||
RefPtr<KeepAliveToken>&& aKeepAliveToken);
|
||||
|
||||
mozilla::ipc::IPCResult RecvAsyncLog(const nsCString& aScriptSpec,
|
||||
const uint32_t& aLineNumber,
|
||||
const uint32_t& aColumnNumber,
|
||||
const nsCString& aMessageName,
|
||||
nsTArray<nsString>&& aParams);
|
||||
|
||||
mozilla::ipc::IPCResult RecvRespondWith(
|
||||
IPCFetchEventRespondWithResult&& aResult);
|
||||
|
||||
mozilla::ipc::IPCResult Recv__delete__(
|
||||
const ServiceWorkerFetchEventOpResult& aResult) override;
|
||||
|
||||
void ActorDestroy(ActorDestroyReason) override;
|
||||
|
||||
nsresult StartSynthesizedResponse(IPCSynthesizeResponseArgs&& aArgs);
|
||||
|
||||
void SynthesizeResponse(IPCSynthesizeResponseArgs&& aArgs);
|
||||
|
||||
void ResetInterception();
|
||||
|
||||
void CancelInterception(nsresult aStatus);
|
||||
|
||||
void MaybeScheduleRegistrationUpdate() const;
|
||||
|
||||
const ServiceWorkerFetchEventOpArgs mArgs;
|
||||
nsCOMPtr<nsIInterceptedChannel> mInterceptedChannel;
|
||||
RefPtr<ServiceWorkerRegistrationInfo> mRegistration;
|
||||
RefPtr<KeepAliveToken> mKeepAliveToken;
|
||||
bool mInterceptedChannelHandled = false;
|
||||
MozPromiseHolder<GenericPromise> mPromiseHolder;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_fetcheventopchild_h__
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
/* -*- 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 "FetchEventOpParent.h"
|
||||
|
||||
#include "nsDebug.h"
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/dom/FetchEventOpProxyParent.h"
|
||||
#include "mozilla/dom/RemoteWorkerControllerParent.h"
|
||||
#include "mozilla/dom/RemoteWorkerParent.h"
|
||||
#include "mozilla/ipc/BackgroundParent.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
using namespace ipc;
|
||||
|
||||
namespace dom {
|
||||
|
||||
void FetchEventOpParent::Initialize(
|
||||
const ServiceWorkerFetchEventOpArgs& aArgs) {
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
RemoteWorkerControllerParent* manager =
|
||||
static_cast<RemoteWorkerControllerParent*>(Manager());
|
||||
MOZ_ASSERT(manager);
|
||||
|
||||
// This will be null when the manager's RemoteWorkerController has shutdown.
|
||||
RefPtr<RemoteWorkerParent> proxyManager = manager->GetRemoteWorkerParent();
|
||||
if (NS_WARN_IF(!proxyManager)) {
|
||||
Unused << Send__delete__(this, NS_ERROR_DOM_ABORT_ERR);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
FetchEventOpProxyParent::Create(proxyManager.get(), aArgs, this);
|
||||
}
|
||||
|
||||
void FetchEventOpParent::ActorDestroy(ActorDestroyReason) {
|
||||
AssertIsOnBackgroundThread();
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
/* -*- 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_fetcheventopparent_h__
|
||||
#define mozilla_dom_fetcheventopparent_h__
|
||||
|
||||
#include "nsISupports.h"
|
||||
|
||||
#include "mozilla/dom/PFetchEventOpParent.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class ServiceWorkerFetchEventOpArgs;
|
||||
|
||||
class FetchEventOpParent final : public PFetchEventOpParent {
|
||||
friend class PFetchEventOpParent;
|
||||
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(FetchEventOpParent)
|
||||
|
||||
FetchEventOpParent() = default;
|
||||
|
||||
void Initialize(const ServiceWorkerFetchEventOpArgs& aArgs);
|
||||
|
||||
private:
|
||||
~FetchEventOpParent() = default;
|
||||
|
||||
void ActorDestroy(ActorDestroyReason) override;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_fetcheventopparent_h__
|
||||
|
|
@ -1,154 +0,0 @@
|
|||
/* -*- 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 "FetchEventOpProxyChild.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/dom/RemoteWorkerChild.h"
|
||||
#include "mozilla/dom/RemoteWorkerService.h"
|
||||
#include "mozilla/dom/ServiceWorkerOp.h"
|
||||
#include "mozilla/dom/WorkerCommon.h"
|
||||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
#include "mozilla/ipc/IPCStreamUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
using namespace ipc;
|
||||
|
||||
namespace dom {
|
||||
|
||||
namespace {
|
||||
|
||||
nsresult GetIPCSynthesizeResponseArgs(
|
||||
IPCSynthesizeResponseArgs* aIPCArgs, SynthesizeResponseArgs&& aArgs,
|
||||
UniquePtr<AutoIPCStream>& aAutoBodyStream,
|
||||
UniquePtr<AutoIPCStream>& aAutoAlternativeBodyStream) {
|
||||
MOZ_ASSERT(RemoteWorkerService::Thread()->IsOnCurrentThread());
|
||||
|
||||
PBackgroundChild* bgChild = BackgroundChild::GetOrCreateForCurrentThread();
|
||||
|
||||
if (NS_WARN_IF(!bgChild)) {
|
||||
return NS_ERROR_DOM_INVALID_STATE_ERR;
|
||||
}
|
||||
|
||||
aArgs.first()->ToIPC(&aIPCArgs->internalResponse(), bgChild, aAutoBodyStream,
|
||||
aAutoAlternativeBodyStream);
|
||||
aIPCArgs->closure() = std::move(aArgs.second());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
void FetchEventOpProxyChild::Initialize(
|
||||
const ServiceWorkerFetchEventOpArgs& aArgs) {
|
||||
MOZ_ASSERT(RemoteWorkerService::Thread()->IsOnCurrentThread());
|
||||
MOZ_ASSERT(!mOp);
|
||||
|
||||
mInternalRequest = new InternalRequest(aArgs.internalRequest());
|
||||
|
||||
RemoteWorkerChild* manager = static_cast<RemoteWorkerChild*>(Manager());
|
||||
MOZ_ASSERT(manager);
|
||||
|
||||
RefPtr<FetchEventOpProxyChild> self = this;
|
||||
|
||||
auto callback = [self](const ServiceWorkerOpResult& aResult) {
|
||||
if (!self->CanSend()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(aResult.type() == ServiceWorkerOpResult::Tnsresult)) {
|
||||
Unused << self->Send__delete__(self, aResult.get_nsresult());
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aResult.type() ==
|
||||
ServiceWorkerOpResult::TServiceWorkerFetchEventOpResult);
|
||||
|
||||
Unused << self->Send__delete__(self, aResult);
|
||||
};
|
||||
|
||||
RefPtr<FetchEventOp> op = ServiceWorkerOp::Create(aArgs, std::move(callback))
|
||||
.template downcast<FetchEventOp>();
|
||||
|
||||
MOZ_ASSERT(op);
|
||||
|
||||
op->SetActor(this);
|
||||
mOp = op;
|
||||
|
||||
op->GetRespondWithPromise()
|
||||
->Then(GetCurrentThreadSerialEventTarget(), __func__,
|
||||
[self = std::move(self)](
|
||||
FetchEventRespondWithPromise::ResolveOrRejectValue&& aResult) {
|
||||
self->mRespondWithPromiseRequestHolder.Complete();
|
||||
|
||||
if (NS_WARN_IF(aResult.IsReject())) {
|
||||
MOZ_ASSERT(NS_FAILED(aResult.RejectValue()));
|
||||
|
||||
Unused << self->SendRespondWith(
|
||||
CancelInterceptionArgs(aResult.RejectValue()));
|
||||
return;
|
||||
}
|
||||
|
||||
auto& result = aResult.ResolveValue();
|
||||
|
||||
if (result.is<SynthesizeResponseArgs>()) {
|
||||
IPCSynthesizeResponseArgs ipcArgs;
|
||||
UniquePtr<AutoIPCStream> autoBodyStream =
|
||||
MakeUnique<AutoIPCStream>();
|
||||
UniquePtr<AutoIPCStream> autoAlternativeBodyStream =
|
||||
MakeUnique<AutoIPCStream>();
|
||||
nsresult rv = GetIPCSynthesizeResponseArgs(
|
||||
&ipcArgs, result.extract<SynthesizeResponseArgs>(),
|
||||
autoBodyStream, autoAlternativeBodyStream);
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
Unused << self->SendRespondWith(CancelInterceptionArgs(rv));
|
||||
return;
|
||||
}
|
||||
|
||||
Unused << self->SendRespondWith(ipcArgs);
|
||||
autoBodyStream->TakeOptionalValue();
|
||||
autoAlternativeBodyStream->TakeOptionalValue();
|
||||
} else if (result.is<ResetInterceptionArgs>()) {
|
||||
Unused << self->SendRespondWith(
|
||||
result.extract<ResetInterceptionArgs>());
|
||||
} else {
|
||||
Unused << self->SendRespondWith(
|
||||
result.extract<CancelInterceptionArgs>());
|
||||
}
|
||||
})
|
||||
->Track(mRespondWithPromiseRequestHolder);
|
||||
|
||||
manager->MaybeStartOp(std::move(op));
|
||||
}
|
||||
|
||||
RefPtr<InternalRequest> FetchEventOpProxyChild::ExtractInternalRequest() {
|
||||
MOZ_ASSERT(IsCurrentThreadRunningWorker());
|
||||
MOZ_ASSERT(mInternalRequest);
|
||||
|
||||
return RefPtr<InternalRequest>(std::move(mInternalRequest));
|
||||
}
|
||||
|
||||
void FetchEventOpProxyChild::ActorDestroy(ActorDestroyReason) {
|
||||
Unused << NS_WARN_IF(mRespondWithPromiseRequestHolder.Exists());
|
||||
mRespondWithPromiseRequestHolder.DisconnectIfExists();
|
||||
|
||||
mOp->RevokeActor(this);
|
||||
mOp = nullptr;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
/* -*- 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_fetcheventopproxychild_h__
|
||||
#define mozilla_dom_fetcheventopproxychild_h__
|
||||
|
||||
#include "nsISupportsImpl.h"
|
||||
|
||||
#include "ServiceWorkerOp.h"
|
||||
#include "ServiceWorkerOpPromise.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/dom/InternalRequest.h"
|
||||
#include "mozilla/dom/PFetchEventOpProxyChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class InternalRequest;
|
||||
class ServiceWorkerFetchEventOpArgs;
|
||||
|
||||
class FetchEventOpProxyChild final : public PFetchEventOpProxyChild {
|
||||
friend class PFetchEventOpProxyChild;
|
||||
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FetchEventOpProxyChild)
|
||||
|
||||
FetchEventOpProxyChild() = default;
|
||||
|
||||
void Initialize(const ServiceWorkerFetchEventOpArgs& aArgs);
|
||||
|
||||
// Must only be called once and on a worker thread.
|
||||
RefPtr<InternalRequest> ExtractInternalRequest();
|
||||
|
||||
private:
|
||||
~FetchEventOpProxyChild() = default;
|
||||
|
||||
void ActorDestroy(ActorDestroyReason) override;
|
||||
|
||||
MozPromiseRequestHolder<FetchEventRespondWithPromise>
|
||||
mRespondWithPromiseRequestHolder;
|
||||
|
||||
RefPtr<FetchEventOp> mOp;
|
||||
|
||||
// Initialized on RemoteWorkerService::Thread, read on a worker thread.
|
||||
RefPtr<InternalRequest> mInternalRequest;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_fetcheventopproxychild_h__
|
||||
|
|
@ -1,165 +0,0 @@
|
|||
/* -*- 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 "FetchEventOpProxyParent.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIInputStream.h"
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/dom/FetchEventOpParent.h"
|
||||
#include "mozilla/ipc/BackgroundParent.h"
|
||||
#include "mozilla/ipc/IPCStreamUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
using namespace ipc;
|
||||
|
||||
namespace dom {
|
||||
|
||||
namespace {
|
||||
|
||||
void MaybeDeserializeAndReserialize(const Maybe<IPCStream>& aDeserialize,
|
||||
Maybe<IPCStream>& aReserialize,
|
||||
UniquePtr<AutoIPCStream>& aAutoStream,
|
||||
PBackgroundParent* aManager) {
|
||||
nsCOMPtr<nsIInputStream> maybeDeserialized =
|
||||
DeserializeIPCStream(aDeserialize);
|
||||
|
||||
if (!maybeDeserialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
aAutoStream.reset(new AutoIPCStream(aReserialize));
|
||||
DebugOnly<bool> ok = aAutoStream->Serialize(maybeDeserialized, aManager);
|
||||
MOZ_ASSERT(ok);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* static */ void FetchEventOpProxyParent::Create(
|
||||
PRemoteWorkerParent* aManager, const ServiceWorkerFetchEventOpArgs& aArgs,
|
||||
RefPtr<FetchEventOpParent> aReal) {
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aManager);
|
||||
MOZ_ASSERT(aReal);
|
||||
|
||||
FetchEventOpProxyParent* actor =
|
||||
new FetchEventOpProxyParent(std::move(aReal));
|
||||
|
||||
if (aArgs.internalRequest().body().isNothing()) {
|
||||
Unused << aManager->SendPFetchEventOpProxyConstructor(actor, aArgs);
|
||||
return;
|
||||
}
|
||||
|
||||
ServiceWorkerFetchEventOpArgs copyArgs = aArgs;
|
||||
IPCInternalRequest& copyRequest = copyArgs.internalRequest();
|
||||
|
||||
PBackgroundParent* bgParent = aManager->Manager();
|
||||
MOZ_ASSERT(bgParent);
|
||||
|
||||
UniquePtr<AutoIPCStream> autoBodyStream = MakeUnique<AutoIPCStream>();
|
||||
MaybeDeserializeAndReserialize(aArgs.internalRequest().body(),
|
||||
copyRequest.body(), autoBodyStream, bgParent);
|
||||
|
||||
Unused << aManager->SendPFetchEventOpProxyConstructor(actor, copyArgs);
|
||||
autoBodyStream->TakeOptionalValue();
|
||||
}
|
||||
|
||||
FetchEventOpProxyParent::~FetchEventOpProxyParent() {
|
||||
AssertIsOnBackgroundThread();
|
||||
}
|
||||
|
||||
FetchEventOpProxyParent::FetchEventOpProxyParent(
|
||||
RefPtr<FetchEventOpParent>&& aReal)
|
||||
: mReal(std::move(aReal)) {}
|
||||
|
||||
mozilla::ipc::IPCResult FetchEventOpProxyParent::RecvAsyncLog(
|
||||
const nsCString& aScriptSpec, const uint32_t& aLineNumber,
|
||||
const uint32_t& aColumnNumber, const nsCString& aMessageName,
|
||||
nsTArray<nsString>&& aParams) {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(mReal);
|
||||
|
||||
Unused << mReal->SendAsyncLog(aScriptSpec, aLineNumber, aColumnNumber,
|
||||
aMessageName, aParams);
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult FetchEventOpProxyParent::RecvRespondWith(
|
||||
const IPCFetchEventRespondWithResult& aResult) {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(mReal);
|
||||
|
||||
// IPCSynthesizeResponseArgs possibly contains an IPCStream. If so,
|
||||
// deserialize it and reserialize it before forwarding it to the main thread.
|
||||
if (aResult.type() ==
|
||||
IPCFetchEventRespondWithResult::TIPCSynthesizeResponseArgs) {
|
||||
const IPCSynthesizeResponseArgs& originalArgs =
|
||||
aResult.get_IPCSynthesizeResponseArgs();
|
||||
const IPCInternalResponse& originalResponse =
|
||||
originalArgs.internalResponse();
|
||||
|
||||
// Do nothing if neither the body nor the alt. body can be deserialized.
|
||||
if (!originalResponse.body() && !originalResponse.alternativeBody()) {
|
||||
Unused << mReal->SendRespondWith(aResult);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
IPCSynthesizeResponseArgs copyArgs = originalArgs;
|
||||
IPCInternalResponse& copyResponse = copyArgs.internalResponse();
|
||||
|
||||
PRemoteWorkerControllerParent* manager = mReal->Manager();
|
||||
MOZ_ASSERT(manager);
|
||||
|
||||
PBackgroundParent* bgParent = manager->Manager();
|
||||
MOZ_ASSERT(bgParent);
|
||||
|
||||
UniquePtr<AutoIPCStream> autoBodyStream = MakeUnique<AutoIPCStream>();
|
||||
UniquePtr<AutoIPCStream> autoAlternativeBodyStream =
|
||||
MakeUnique<AutoIPCStream>();
|
||||
|
||||
MaybeDeserializeAndReserialize(originalResponse.body(), copyResponse.body(),
|
||||
autoBodyStream, bgParent);
|
||||
MaybeDeserializeAndReserialize(originalResponse.alternativeBody(),
|
||||
copyResponse.alternativeBody(),
|
||||
autoAlternativeBodyStream, bgParent);
|
||||
|
||||
Unused << mReal->SendRespondWith(copyArgs);
|
||||
|
||||
autoBodyStream->TakeOptionalValue();
|
||||
autoAlternativeBodyStream->TakeOptionalValue();
|
||||
} else {
|
||||
Unused << mReal->SendRespondWith(aResult);
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult FetchEventOpProxyParent::Recv__delete__(
|
||||
const ServiceWorkerFetchEventOpResult& aResult) {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(mReal);
|
||||
|
||||
Unused << mReal->Send__delete__(mReal, aResult);
|
||||
mReal = nullptr;
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void FetchEventOpProxyParent::ActorDestroy(ActorDestroyReason) {
|
||||
AssertIsOnBackgroundThread();
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
/* -*- 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_fetcheventopproxyparent_h__
|
||||
#define mozilla_dom_fetcheventopproxyparent_h__
|
||||
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/dom/PFetchEventOpProxyParent.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class FetchEventOpParent;
|
||||
class PRemoteWorkerParent;
|
||||
class ServiceWorkerFetchEventOpArgs;
|
||||
|
||||
/**
|
||||
* FetchEventOpProxyParent owns a FetchEventOpParent and is responsible for
|
||||
* calling PFetchEventOpParent::Send__delete__.
|
||||
*/
|
||||
class FetchEventOpProxyParent final : public PFetchEventOpProxyParent {
|
||||
friend class PFetchEventOpProxyParent;
|
||||
|
||||
public:
|
||||
static void Create(PRemoteWorkerParent* aManager,
|
||||
const ServiceWorkerFetchEventOpArgs& aArgs,
|
||||
RefPtr<FetchEventOpParent> aReal);
|
||||
|
||||
~FetchEventOpProxyParent();
|
||||
|
||||
private:
|
||||
explicit FetchEventOpProxyParent(RefPtr<FetchEventOpParent>&& aReal);
|
||||
|
||||
mozilla::ipc::IPCResult RecvAsyncLog(const nsCString& aScriptSpec,
|
||||
const uint32_t& aLineNumber,
|
||||
const uint32_t& aColumnNumber,
|
||||
const nsCString& aMessageName,
|
||||
nsTArray<nsString>&& aParams);
|
||||
|
||||
mozilla::ipc::IPCResult RecvRespondWith(
|
||||
const IPCFetchEventRespondWithResult& aResult);
|
||||
|
||||
mozilla::ipc::IPCResult Recv__delete__(
|
||||
const ServiceWorkerFetchEventOpResult& aResult) override;
|
||||
|
||||
void ActorDestroy(ActorDestroyReason) override;
|
||||
|
||||
RefPtr<FetchEventOpParent> mReal;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_fetcheventopproxyparent_h__
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
/* 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 protocol PRemoteWorkerController;
|
||||
|
||||
include ServiceWorkerOpArgs;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
protocol PFetchEventOp {
|
||||
manager PRemoteWorkerController;
|
||||
|
||||
child:
|
||||
async AsyncLog(nsCString aScriptSpec, uint32_t aLineNumber,
|
||||
uint32_t aColumnNumber, nsCString aMessageName,
|
||||
nsString[] aParams);
|
||||
|
||||
async RespondWith(IPCFetchEventRespondWithResult aResult);
|
||||
|
||||
async __delete__(ServiceWorkerFetchEventOpResult aResult);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
/* 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 protocol PRemoteWorker;
|
||||
|
||||
include ServiceWorkerOpArgs;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
protocol PFetchEventOpProxy {
|
||||
manager PRemoteWorker;
|
||||
|
||||
parent:
|
||||
async AsyncLog(nsCString aScriptSpec, uint32_t aLineNumber,
|
||||
uint32_t aColumnNumber, nsCString aMessageName,
|
||||
nsString[] aParams);
|
||||
|
||||
async RespondWith(IPCFetchEventRespondWithResult aResult);
|
||||
|
||||
async __delete__(ServiceWorkerFetchEventOpResult aResult);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
@ -6,8 +6,6 @@
|
|||
|
||||
#include "ServiceWorkerEvents.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIConsoleReportCollector.h"
|
||||
|
|
@ -43,7 +41,6 @@
|
|||
#include "mozilla/dom/PushMessageDataBinding.h"
|
||||
#include "mozilla/dom/PushUtil.h"
|
||||
#include "mozilla/dom/Request.h"
|
||||
#include "mozilla/dom/ServiceWorkerOp.h"
|
||||
#include "mozilla/dom/TypedArray.h"
|
||||
#include "mozilla/dom/Response.h"
|
||||
#include "mozilla/dom/WorkerScope.h"
|
||||
|
|
@ -139,14 +136,6 @@ void FetchEvent::PostInit(
|
|||
mScriptSpec.Assign(aScriptSpec);
|
||||
}
|
||||
|
||||
void FetchEvent::PostInit(const nsACString& aScriptSpec,
|
||||
RefPtr<FetchEventOp> aRespondWithHandler) {
|
||||
MOZ_ASSERT(aRespondWithHandler);
|
||||
|
||||
mScriptSpec.Assign(aScriptSpec);
|
||||
mRespondWithHandler = std::move(aRespondWithHandler);
|
||||
}
|
||||
|
||||
/*static*/
|
||||
already_AddRefed<FetchEvent> FetchEvent::Constructor(
|
||||
const GlobalObject& aGlobal, const nsAString& aType,
|
||||
|
|
@ -806,21 +795,11 @@ void FetchEvent::RespondWith(JSContext* aCx, Promise& aArg, ErrorResult& aRv) {
|
|||
|
||||
StopImmediatePropagation();
|
||||
mWaitToRespond = true;
|
||||
|
||||
if (mChannel) {
|
||||
RefPtr<RespondWithHandler> handler = new RespondWithHandler(
|
||||
mChannel, mRegistration, mRequest->Mode(), ir->IsClientRequest(),
|
||||
mRequest->Redirect(), mScriptSpec, NS_ConvertUTF8toUTF16(requestURL),
|
||||
ir->GetFragment(), spec, line, column);
|
||||
|
||||
aArg.AppendNativeHandler(handler);
|
||||
} else {
|
||||
MOZ_ASSERT(mRespondWithHandler);
|
||||
|
||||
mRespondWithHandler->RespondWithCalledAt(spec, line, column);
|
||||
aArg.AppendNativeHandler(mRespondWithHandler);
|
||||
mRespondWithHandler = nullptr;
|
||||
}
|
||||
|
||||
if (!WaitOnPromise(aArg)) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
|
|
@ -859,16 +838,9 @@ void FetchEvent::ReportCanceled() {
|
|||
// nsString requestURL;
|
||||
// CopyUTF8toUTF16(url, requestURL);
|
||||
|
||||
if (mChannel) {
|
||||
::AsyncLog(mChannel.get(), mPreventDefaultScriptSpec,
|
||||
mPreventDefaultLineNumber, mPreventDefaultColumnNumber,
|
||||
NS_LITERAL_CSTRING("InterceptionCanceledWithURL"), requestURL);
|
||||
} else {
|
||||
mRespondWithHandler->ReportCanceled(mPreventDefaultScriptSpec,
|
||||
mPreventDefaultLineNumber,
|
||||
mPreventDefaultColumnNumber);
|
||||
mRespondWithHandler = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ namespace dom {
|
|||
|
||||
class Blob;
|
||||
class Client;
|
||||
class FetchEventOp;
|
||||
class MessagePort;
|
||||
struct PushEventInit;
|
||||
class Request;
|
||||
|
|
@ -51,15 +50,6 @@ class CancelChannelRunnable final : public Runnable {
|
|||
NS_IMETHOD Run() override;
|
||||
};
|
||||
|
||||
enum ExtendableEventResult { Rejected = 0, Resolved };
|
||||
|
||||
class ExtendableEventCallback {
|
||||
public:
|
||||
virtual void FinishedWithResult(ExtendableEventResult aResult) = 0;
|
||||
|
||||
NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
|
||||
};
|
||||
|
||||
class ExtendableEvent : public Event {
|
||||
public:
|
||||
class ExtensionsHandler {
|
||||
|
|
@ -76,7 +66,7 @@ class ExtendableEvent : public Event {
|
|||
bool WaitOnPromise(Promise& aPromise);
|
||||
|
||||
explicit ExtendableEvent(mozilla::dom::EventTarget* aOwner);
|
||||
~ExtendableEvent() = default;
|
||||
~ExtendableEvent() {}
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
|
@ -112,7 +102,6 @@ class ExtendableEvent : public Event {
|
|||
};
|
||||
|
||||
class FetchEvent final : public ExtendableEvent {
|
||||
RefPtr<FetchEventOp> mRespondWithHandler;
|
||||
nsMainThreadPtrHandle<nsIInterceptedChannel> mChannel;
|
||||
nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> mRegistration;
|
||||
RefPtr<Request> mRequest;
|
||||
|
|
@ -143,9 +132,6 @@ class FetchEvent final : public ExtendableEvent {
|
|||
nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo>& aRegistration,
|
||||
const nsACString& aScriptSpec);
|
||||
|
||||
void PostInit(const nsACString& aScriptSpec,
|
||||
RefPtr<FetchEventOp> aRespondWithHandler);
|
||||
|
||||
static already_AddRefed<FetchEvent> Constructor(
|
||||
const GlobalObject& aGlobal, const nsAString& aType,
|
||||
const FetchEventInit& aOptions, ErrorResult& aRv);
|
||||
|
|
@ -167,6 +153,10 @@ class FetchEvent final : public ExtendableEvent {
|
|||
|
||||
void RespondWith(JSContext* aCx, Promise& aArg, ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<Promise> ForwardTo(const nsAString& aUrl);
|
||||
|
||||
already_AddRefed<Promise> Default();
|
||||
|
||||
// Pull in the Event version of PreventDefault so we don't get
|
||||
// shadowing warnings.
|
||||
using Event::PreventDefault;
|
||||
|
|
@ -209,7 +199,7 @@ class PushEvent final : public ExtendableEvent {
|
|||
|
||||
protected:
|
||||
explicit PushEvent(mozilla::dom::EventTarget* aOwner);
|
||||
~PushEvent() = default;
|
||||
~PushEvent() {}
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
|
|
|||
|
|
@ -6,11 +6,7 @@
|
|||
|
||||
#include "ServiceWorkerInfo.h"
|
||||
|
||||
#include "ServiceWorkerPrivate.h"
|
||||
#include "ServiceWorkerScriptCache.h"
|
||||
#include "mozilla/dom/ClientIPCTypes.h"
|
||||
#include "mozilla/dom/ClientState.h"
|
||||
#include "mozilla/dom/RemoteWorkerTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
|
@ -150,7 +146,6 @@ void ServiceWorkerInfo::UpdateState(ServiceWorkerState aState) {
|
|||
mDescriptor.SetState(aState);
|
||||
if (State() == ServiceWorkerState::Redundant) {
|
||||
serviceWorkerScriptCache::PurgeCache(mPrincipal, mCacheName);
|
||||
mServiceWorkerPrivate->NoteDeadServiceWorkerInfo();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
#include "nsDebug.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsIPermissionManager.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
|
||||
|
|
@ -77,7 +76,6 @@
|
|||
#include "ServiceWorkerRegistrar.h"
|
||||
#include "ServiceWorkerRegistration.h"
|
||||
#include "ServiceWorkerScriptCache.h"
|
||||
#include "ServiceWorkerShutdownBlocker.h"
|
||||
#include "ServiceWorkerEvents.h"
|
||||
#include "ServiceWorkerUnregisterJob.h"
|
||||
#include "ServiceWorkerUpdateJob.h"
|
||||
|
|
@ -261,36 +259,6 @@ class TeardownRunnable final : public Runnable {
|
|||
RefPtr<ServiceWorkerManagerChild> mActor;
|
||||
};
|
||||
|
||||
bool ServiceWorkersAreCrossProcess() {
|
||||
return ServiceWorkerParentInterceptEnabled() && XRE_IsE10sParentProcess();
|
||||
}
|
||||
|
||||
const char* GetXPCOMShutdownTopic() {
|
||||
if (ServiceWorkersAreCrossProcess()) {
|
||||
return "profile-change-teardown";
|
||||
}
|
||||
|
||||
return NS_XPCOM_SHUTDOWN_OBSERVER_ID;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIAsyncShutdownClient> GetAsyncShutdownBarrier() {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (!ServiceWorkersAreCrossProcess()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAsyncShutdownService> svc = services::GetAsyncShutdown();
|
||||
MOZ_ASSERT(svc);
|
||||
|
||||
nsCOMPtr<nsIAsyncShutdownClient> barrier;
|
||||
DebugOnly<nsresult> rv =
|
||||
svc->GetProfileChangeTeardown(getter_AddRefs(barrier));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
return barrier.forget();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
//////////////////////////
|
||||
|
|
@ -312,40 +280,15 @@ ServiceWorkerManager::ServiceWorkerManager()
|
|||
ServiceWorkerManager::~ServiceWorkerManager() {
|
||||
// The map will assert if it is not empty when destroyed.
|
||||
mRegistrationInfos.Clear();
|
||||
|
||||
if (!ServiceWorkersAreCrossProcess()) {
|
||||
MOZ_ASSERT(!mActor);
|
||||
}
|
||||
}
|
||||
|
||||
void ServiceWorkerManager::BlockShutdownOn(
|
||||
GenericNonExclusivePromise* aPromise) {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
// This may be called when in non-e10s mode with parent-intercept enabled.
|
||||
if (!ServiceWorkersAreCrossProcess()) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mShutdownBlocker);
|
||||
MOZ_ASSERT(aPromise);
|
||||
|
||||
mShutdownBlocker->WaitOnPromise(aPromise);
|
||||
}
|
||||
|
||||
void ServiceWorkerManager::Init(ServiceWorkerRegistrar* aRegistrar) {
|
||||
nsCOMPtr<nsIAsyncShutdownClient> shutdownBarrier = GetAsyncShutdownBarrier();
|
||||
|
||||
if (shutdownBarrier) {
|
||||
mShutdownBlocker =
|
||||
ServiceWorkerShutdownBlocker::CreateAndRegisterOn(shutdownBarrier);
|
||||
MOZ_ASSERT(mShutdownBlocker);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
DebugOnly<nsresult> rv;
|
||||
rv = obs->AddObserver(this, GetXPCOMShutdownTopic(), false /* ownsWeak */);
|
||||
rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
|
||||
false /* ownsWeak */);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
|
||||
|
|
@ -508,13 +451,9 @@ void ServiceWorkerManager::MaybeStartShutdown() {
|
|||
it1.UserData()->mInfos.Clear();
|
||||
}
|
||||
|
||||
if (mShutdownBlocker) {
|
||||
mShutdownBlocker->StopAcceptingPromises();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
obs->RemoveObserver(this, GetXPCOMShutdownTopic());
|
||||
obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
|
||||
|
||||
if (XRE_IsParentProcess()) {
|
||||
obs->RemoveObserver(this, CLEAR_ORIGIN_DATA);
|
||||
|
|
@ -2336,6 +2275,19 @@ void ServiceWorkerManager::Update(
|
|||
actor, aPrincipal->OriginAttributesRef(), nsCString(aScope));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void RejectUpdateWithInvalidStateError(
|
||||
ServiceWorkerUpdateFinishCallback& aCallback) {
|
||||
ErrorResult error(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
aCallback.UpdateFailed(error);
|
||||
|
||||
// In case the callback does not consume the exception
|
||||
error.SuppressException();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void ServiceWorkerManager::UpdateInternal(
|
||||
nsIPrincipal* aPrincipal, const nsACString& aScope,
|
||||
ServiceWorkerUpdateFinishCallback* aCallback) {
|
||||
|
|
@ -2351,20 +2303,22 @@ void ServiceWorkerManager::UpdateInternal(
|
|||
RefPtr<ServiceWorkerRegistrationInfo> registration =
|
||||
GetRegistration(scopeKey, aScope);
|
||||
if (NS_WARN_IF(!registration)) {
|
||||
ErrorResult error;
|
||||
error.ThrowTypeError<MSG_SW_UPDATE_BAD_REGISTRATION>(
|
||||
NS_ConvertUTF8toUTF16(aScope), NS_LITERAL_STRING("uninstalled"));
|
||||
aCallback->UpdateFailed(error);
|
||||
|
||||
// In case the callback does not consume the exception
|
||||
error.SuppressException();
|
||||
return;
|
||||
}
|
||||
|
||||
// "Let newestWorker be the result of running Get Newest Worker algorithm
|
||||
// passing registration as its argument.
|
||||
// If newestWorker is null, return a promise rejected with "InvalidStateError"
|
||||
RefPtr<ServiceWorkerInfo> newest = registration->Newest();
|
||||
MOZ_DIAGNOSTIC_ASSERT(newest,
|
||||
"The Update algorithm should have been aborted already "
|
||||
"if there wasn't a newest worker");
|
||||
if (!newest) {
|
||||
RejectUpdateWithInvalidStateError(*aCallback);
|
||||
return;
|
||||
}
|
||||
|
||||
if (newest->State() == ServiceWorkerState::Installing) {
|
||||
RejectUpdateWithInvalidStateError(*aCallback);
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<ServiceWorkerJobQueue> queue = GetOrCreateJobQueue(scopeKey, aScope);
|
||||
|
||||
|
|
@ -2783,7 +2737,7 @@ ServiceWorkerManager::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
if (strcmp(aTopic, GetXPCOMShutdownTopic()) == 0) {
|
||||
if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
|
||||
MaybeStartShutdown();
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,6 @@ class ServiceWorkerJobQueue;
|
|||
class ServiceWorkerManagerChild;
|
||||
class ServiceWorkerPrivate;
|
||||
class ServiceWorkerRegistrar;
|
||||
class ServiceWorkerShutdownBlocker;
|
||||
|
||||
class ServiceWorkerUpdateFinishCallback {
|
||||
protected:
|
||||
|
|
@ -281,8 +280,6 @@ class ServiceWorkerManager final : public nsIServiceWorkerManager,
|
|||
void NoteInheritedController(const ClientInfo& aClientInfo,
|
||||
const ServiceWorkerDescriptor& aController);
|
||||
|
||||
void BlockShutdownOn(GenericNonExclusivePromise* aPromise);
|
||||
|
||||
nsresult GetClientRegistration(
|
||||
const ClientInfo& aClientInfo,
|
||||
ServiceWorkerRegistrationInfo** aRegistrationInfo);
|
||||
|
|
@ -388,8 +385,6 @@ class ServiceWorkerManager final : public nsIServiceWorkerManager,
|
|||
const nsAString& aTag, const nsAString& aIcon,
|
||||
const nsAString& aData,
|
||||
const nsAString& aBehavior);
|
||||
|
||||
RefPtr<ServiceWorkerShutdownBlocker> mShutdownBlocker;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,172 +0,0 @@
|
|||
/* -*- 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_serviceworkerop_h__
|
||||
#define mozilla_dom_serviceworkerop_h__
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "nsISupportsImpl.h"
|
||||
|
||||
#include "ServiceWorkerEvents.h"
|
||||
#include "ServiceWorkerOpPromise.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/dom/PromiseNativeHandler.h"
|
||||
#include "mozilla/dom/RemoteWorkerChild.h"
|
||||
#include "mozilla/dom/ServiceWorkerOpArgs.h"
|
||||
#include "mozilla/dom/WorkerRunnable.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class FetchEventOpProxyChild;
|
||||
|
||||
class ServiceWorkerOp : public RemoteWorkerChild::Op {
|
||||
public:
|
||||
// `aCallback` will be called when the operation completes or is canceled.
|
||||
static already_AddRefed<ServiceWorkerOp> Create(
|
||||
const ServiceWorkerOpArgs& aArgs,
|
||||
std::function<void(const ServiceWorkerOpResult&)>&& aCallback);
|
||||
|
||||
ServiceWorkerOp(
|
||||
const ServiceWorkerOpArgs& aArgs,
|
||||
std::function<void(const ServiceWorkerOpResult&)>&& aCallback);
|
||||
|
||||
ServiceWorkerOp(const ServiceWorkerOp&) = delete;
|
||||
|
||||
ServiceWorkerOp& operator=(const ServiceWorkerOp&) = delete;
|
||||
|
||||
ServiceWorkerOp(ServiceWorkerOp&&) = default;
|
||||
|
||||
ServiceWorkerOp& operator=(ServiceWorkerOp&&) = default;
|
||||
|
||||
// Returns `true` if the operation has started and `false` otherwise.
|
||||
bool MaybeStart(RemoteWorkerChild* aOwner,
|
||||
RemoteWorkerChild::State& aState) final;
|
||||
|
||||
void Cancel() final;
|
||||
|
||||
protected:
|
||||
~ServiceWorkerOp();
|
||||
|
||||
bool Started() const;
|
||||
|
||||
bool IsTerminationOp() const;
|
||||
|
||||
// Override to provide a runnable that's not a `ServiceWorkerOpRunnable.`
|
||||
virtual RefPtr<WorkerRunnable> GetRunnable(WorkerPrivate* aWorkerPrivate);
|
||||
|
||||
virtual bool Exec(JSContext* aCx, WorkerPrivate* aWorkerPrivate) = 0;
|
||||
|
||||
// Override to reject any additional MozPromises that subclasses may contain.
|
||||
virtual void RejectAll(nsresult aStatus);
|
||||
|
||||
ServiceWorkerOpArgs mArgs;
|
||||
|
||||
// Subclasses must settle this promise when appropriate.
|
||||
MozPromiseHolder<ServiceWorkerOpPromise> mPromiseHolder;
|
||||
|
||||
private:
|
||||
class ServiceWorkerOpRunnable;
|
||||
|
||||
bool mStarted = false;
|
||||
};
|
||||
|
||||
class ExtendableEventOp : public ServiceWorkerOp,
|
||||
public ExtendableEventCallback {
|
||||
using ServiceWorkerOp::ServiceWorkerOp;
|
||||
|
||||
protected:
|
||||
~ExtendableEventOp() = default;
|
||||
|
||||
void FinishedWithResult(ExtendableEventResult aResult) override;
|
||||
};
|
||||
|
||||
class FetchEventOp final : public ExtendableEventOp,
|
||||
public PromiseNativeHandler {
|
||||
using ExtendableEventOp::ExtendableEventOp;
|
||||
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
||||
/**
|
||||
* This must be called once and only once before the first call to
|
||||
* `MaybeStart()`; `aActor` will be used for `AsyncLog()` and
|
||||
* `ReportCanceled().`
|
||||
*/
|
||||
void SetActor(RefPtr<FetchEventOpProxyChild> aActor);
|
||||
|
||||
void RevokeActor(FetchEventOpProxyChild* aActor);
|
||||
|
||||
// This must be called at most once before the first call to `MaybeStart().`
|
||||
RefPtr<FetchEventRespondWithPromise> GetRespondWithPromise();
|
||||
|
||||
// This must be called when `FetchEvent::RespondWith()` is called.
|
||||
void RespondWithCalledAt(const nsCString& aRespondWithScriptSpec,
|
||||
uint32_t aRespondWithLineNumber,
|
||||
uint32_t aRespondWithColumnNumber);
|
||||
|
||||
void ReportCanceled(const nsCString& aPreventDefaultScriptSpec,
|
||||
uint32_t aPreventDefaultLineNumber,
|
||||
uint32_t aPreventDefaultColumnNumber);
|
||||
|
||||
private:
|
||||
class AutoCancel;
|
||||
|
||||
~FetchEventOp();
|
||||
|
||||
bool Exec(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override;
|
||||
|
||||
void RejectAll(nsresult aStatus) override;
|
||||
|
||||
void FinishedWithResult(ExtendableEventResult aResult) override;
|
||||
|
||||
/**
|
||||
* `{Resolved,Reject}Callback()` are use to handle the
|
||||
* `FetchEvent::RespondWith()` promise.
|
||||
*/
|
||||
void ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
|
||||
|
||||
void RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
|
||||
|
||||
void MaybeFinished();
|
||||
|
||||
// Requires mRespondWithClosure to be non-empty.
|
||||
void AsyncLog(const nsCString& aMessageName, nsTArray<nsString> aParams);
|
||||
|
||||
void AsyncLog(const nsCString& aScriptSpec, uint32_t aLineNumber,
|
||||
uint32_t aColumnNumber, const nsCString& aMessageName,
|
||||
nsTArray<nsString> aParams);
|
||||
|
||||
void GetRequestURL(nsAString& aOutRequestURL);
|
||||
|
||||
// A failure code means that the dispatch failed.
|
||||
nsresult DispatchFetchEvent(JSContext* aCx, WorkerPrivate* aWorkerPrivate);
|
||||
|
||||
// Worker Launcher thread only. Used for `AsyncLog().`
|
||||
RefPtr<FetchEventOpProxyChild> mActor;
|
||||
|
||||
/**
|
||||
* Created on the Worker Launcher thread and settled on the worker thread.
|
||||
* If this isn't settled before `mPromiseHolder` (which it should be),
|
||||
* `FetchEventOpChild` will cancel the intercepted network request.
|
||||
*/
|
||||
MozPromiseHolder<FetchEventRespondWithPromise> mRespondWithPromiseHolder;
|
||||
|
||||
// Worker thread only.
|
||||
Maybe<ExtendableEventResult> mResult;
|
||||
bool mPostDispatchChecksDone = false;
|
||||
|
||||
// Worker thread only; set when `FetchEvent::RespondWith()` is called.
|
||||
Maybe<FetchEventRespondWithClosure> mRespondWithClosure;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_serviceworkerop_h__
|
||||
|
|
@ -1,129 +0,0 @@
|
|||
/* 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 ChannelInfo;
|
||||
include ClientIPCTypes;
|
||||
include DOMTypes;
|
||||
include FetchTypes;
|
||||
|
||||
using ServiceWorkerState from "mozilla/dom/ServiceWorkerIPCUtils.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
/**
|
||||
* ServiceWorkerOpArgs
|
||||
*/
|
||||
struct ServiceWorkerCheckScriptEvaluationOpArgs {};
|
||||
|
||||
struct ServiceWorkerUpdateStateOpArgs {
|
||||
ServiceWorkerState state;
|
||||
};
|
||||
|
||||
struct ServiceWorkerTerminateWorkerOpArgs {};
|
||||
|
||||
struct ServiceWorkerLifeCycleEventOpArgs {
|
||||
nsString eventName;
|
||||
};
|
||||
|
||||
// Possibly need to differentiate an empty array from the absence of an array.
|
||||
union OptionalPushData {
|
||||
void_t;
|
||||
uint8_t[];
|
||||
};
|
||||
|
||||
struct ServiceWorkerPushEventOpArgs {
|
||||
nsString messageId;
|
||||
OptionalPushData data;
|
||||
};
|
||||
|
||||
struct ServiceWorkerPushSubscriptionChangeEventOpArgs {};
|
||||
|
||||
struct ServiceWorkerNotificationEventOpArgs {
|
||||
nsString eventName;
|
||||
nsString id;
|
||||
nsString title;
|
||||
nsString dir;
|
||||
nsString lang;
|
||||
nsString body;
|
||||
nsString tag;
|
||||
nsString icon;
|
||||
nsString data;
|
||||
nsString behavior;
|
||||
nsString scope;
|
||||
uint32_t disableOpenClickDelay;
|
||||
};
|
||||
|
||||
struct ServiceWorkerMessageEventOpArgs {
|
||||
ClientInfoAndState clientInfoAndState;
|
||||
ClonedMessageData clonedData;
|
||||
};
|
||||
|
||||
struct ServiceWorkerFetchEventOpArgs {
|
||||
nsCString workerScriptSpec;
|
||||
IPCInternalRequest internalRequest;
|
||||
nsString clientId;
|
||||
nsString resultingClientId;
|
||||
bool isReload;
|
||||
bool isNonSubresourceRequest;
|
||||
};
|
||||
|
||||
union ServiceWorkerOpArgs {
|
||||
ServiceWorkerCheckScriptEvaluationOpArgs;
|
||||
ServiceWorkerUpdateStateOpArgs;
|
||||
ServiceWorkerTerminateWorkerOpArgs;
|
||||
ServiceWorkerLifeCycleEventOpArgs;
|
||||
ServiceWorkerPushEventOpArgs;
|
||||
ServiceWorkerPushSubscriptionChangeEventOpArgs;
|
||||
ServiceWorkerNotificationEventOpArgs;
|
||||
ServiceWorkerMessageEventOpArgs;
|
||||
ServiceWorkerFetchEventOpArgs;
|
||||
};
|
||||
|
||||
/**
|
||||
* IPCFetchEventRespondWithResult
|
||||
*/
|
||||
struct FetchEventRespondWithClosure {
|
||||
nsCString respondWithScriptSpec;
|
||||
uint32_t respondWithLineNumber;
|
||||
uint32_t respondWithColumnNumber;
|
||||
};
|
||||
|
||||
struct IPCSynthesizeResponseArgs {
|
||||
IPCInternalResponse internalResponse;
|
||||
FetchEventRespondWithClosure closure;
|
||||
};
|
||||
|
||||
struct ResetInterceptionArgs {};
|
||||
|
||||
struct CancelInterceptionArgs {
|
||||
nsresult status;
|
||||
};
|
||||
|
||||
union IPCFetchEventRespondWithResult {
|
||||
IPCSynthesizeResponseArgs;
|
||||
ResetInterceptionArgs;
|
||||
CancelInterceptionArgs;
|
||||
};
|
||||
|
||||
/**
|
||||
* ServiceWorkerOpResult
|
||||
*/
|
||||
struct ServiceWorkerCheckScriptEvaluationOpResult {
|
||||
bool workerScriptExecutedSuccessfully;
|
||||
bool fetchHandlerWasAdded;
|
||||
};
|
||||
|
||||
struct ServiceWorkerFetchEventOpResult {
|
||||
nsresult rv;
|
||||
};
|
||||
|
||||
union ServiceWorkerOpResult {
|
||||
nsresult;
|
||||
ServiceWorkerCheckScriptEvaluationOpResult;
|
||||
ServiceWorkerFetchEventOpResult;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
/* -*- 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_serviceworkeroppromise_h__
|
||||
#define mozilla_dom_serviceworkeroppromise_h__
|
||||
|
||||
#include "mozilla/MozPromise.h"
|
||||
#include "mozilla/Pair.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/dom/ServiceWorkerOpArgs.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class InternalResponse;
|
||||
|
||||
using SynthesizeResponseArgs =
|
||||
Pair<RefPtr<InternalResponse>, FetchEventRespondWithClosure>;
|
||||
|
||||
using FetchEventRespondWithResult =
|
||||
Variant<SynthesizeResponseArgs, ResetInterceptionArgs,
|
||||
CancelInterceptionArgs>;
|
||||
|
||||
using FetchEventRespondWithPromise =
|
||||
MozPromise<FetchEventRespondWithResult, nsresult, true>;
|
||||
|
||||
using ServiceWorkerOpPromise =
|
||||
MozPromise<ServiceWorkerOpResult, nsresult, true>;
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_serviceworkeroppromise_h__
|
||||
|
|
@ -6,12 +6,8 @@
|
|||
|
||||
#include "ServiceWorkerPrivate.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "ServiceWorkerCloneData.h"
|
||||
#include "ServiceWorkerManager.h"
|
||||
#include "ServiceWorkerPrivateImpl.h"
|
||||
#include "ServiceWorkerUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsICacheInfoChannel.h"
|
||||
#include "nsIHttpChannelInternal.h"
|
||||
|
|
@ -44,10 +40,8 @@
|
|||
#include "mozilla/dom/WorkerRunnable.h"
|
||||
#include "mozilla/dom/WorkerScope.h"
|
||||
#include "mozilla/dom/ipc/StructuredCloneData.h"
|
||||
#include "mozilla/ipc/BackgroundUtils.h"
|
||||
#include "mozilla/net/CookieSettings.h"
|
||||
#include "mozilla/net/NeckoChannelParams.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/StaticPrefs_dom.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsIReferrerInfo.h"
|
||||
|
|
@ -74,17 +68,26 @@ NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(ServiceWorkerPrivate, Release)
|
|||
// still be a valid value since it was set prior to dispatching the runnable.
|
||||
Atomic<uint32_t> gDOMDisableOpenClickDelay(0);
|
||||
|
||||
KeepAliveToken::KeepAliveToken(ServiceWorkerPrivate* aPrivate)
|
||||
: mPrivate(aPrivate) {
|
||||
// Used to keep track of pending waitUntil as well as in-flight extendable
|
||||
// events. When the last token is released, we attempt to terminate the worker.
|
||||
class KeepAliveToken final : public nsISupports {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
explicit KeepAliveToken(ServiceWorkerPrivate* aPrivate) : mPrivate(aPrivate) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aPrivate);
|
||||
mPrivate->AddToken();
|
||||
}
|
||||
}
|
||||
|
||||
KeepAliveToken::~KeepAliveToken() {
|
||||
private:
|
||||
~KeepAliveToken() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mPrivate->ReleaseToken();
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<ServiceWorkerPrivate> mPrivate;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS0(KeepAliveToken)
|
||||
|
||||
|
|
@ -95,20 +98,11 @@ ServiceWorkerPrivate::ServiceWorkerPrivate(ServiceWorkerInfo* aInfo)
|
|||
|
||||
mIdleWorkerTimer = NS_NewTimer();
|
||||
MOZ_ASSERT(mIdleWorkerTimer);
|
||||
|
||||
if (ServiceWorkerParentInterceptEnabled()) {
|
||||
RefPtr<ServiceWorkerPrivateImpl> inner = new ServiceWorkerPrivateImpl(this);
|
||||
nsresult rv = inner->Initialize();
|
||||
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
mInner = inner.forget();
|
||||
}
|
||||
}
|
||||
|
||||
ServiceWorkerPrivate::~ServiceWorkerPrivate() {
|
||||
MOZ_ASSERT(!mWorkerPrivate);
|
||||
MOZ_ASSERT(!mTokenCount);
|
||||
MOZ_ASSERT(!mInner);
|
||||
MOZ_ASSERT(!mInfo);
|
||||
MOZ_ASSERT(mSupportsArray.IsEmpty());
|
||||
MOZ_ASSERT(mIdlePromiseHolder.IsEmpty());
|
||||
|
|
@ -195,12 +189,6 @@ class CheckScriptEvaluationWithCallback final : public WorkerRunnable {
|
|||
|
||||
nsresult ServiceWorkerPrivate::CheckScriptEvaluation(
|
||||
LifeCycleEventCallback* aScriptEvaluationCallback) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mInner) {
|
||||
return mInner->CheckScriptEvaluation(aScriptEvaluationCallback);
|
||||
}
|
||||
|
||||
nsresult rv = SpawnWorkerIfNeeded(LifeCycleEvent);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
|
@ -216,6 +204,15 @@ nsresult ServiceWorkerPrivate::CheckScriptEvaluation(
|
|||
|
||||
namespace {
|
||||
|
||||
enum ExtendableEventResult { Rejected = 0, Resolved };
|
||||
|
||||
class ExtendableEventCallback {
|
||||
public:
|
||||
virtual void FinishedWithResult(ExtendableEventResult aResult) = 0;
|
||||
|
||||
NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
|
||||
};
|
||||
|
||||
class KeepAliveHandler final : public ExtendableEvent::ExtensionsHandler,
|
||||
public PromiseNativeHandler {
|
||||
// This class manages lifetime extensions added by calling WaitUntil()
|
||||
|
|
@ -519,10 +516,6 @@ nsresult ServiceWorkerPrivate::SendMessageEvent(
|
|||
const ClientInfoAndState& aClientInfoAndState) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mInner) {
|
||||
return mInner->SendMessageEvent(std::move(aData), aClientInfoAndState);
|
||||
}
|
||||
|
||||
nsresult rv = SpawnWorkerIfNeeded(MessageEvent);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
|
@ -731,12 +724,6 @@ bool LifecycleEventWorkerRunnable::DispatchLifecycleEvent(
|
|||
|
||||
nsresult ServiceWorkerPrivate::SendLifeCycleEvent(
|
||||
const nsAString& aEventType, LifeCycleEventCallback* aCallback) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mInner) {
|
||||
return mInner->SendLifeCycleEvent(aEventType, aCallback);
|
||||
}
|
||||
|
||||
nsresult rv = SpawnWorkerIfNeeded(LifeCycleEvent);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
|
@ -897,12 +884,6 @@ class SendPushSubscriptionChangeEventRunnable final
|
|||
nsresult ServiceWorkerPrivate::SendPushEvent(
|
||||
const nsAString& aMessageId, const Maybe<nsTArray<uint8_t>>& aData,
|
||||
ServiceWorkerRegistrationInfo* aRegistration) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mInner) {
|
||||
return mInner->SendPushEvent(aRegistration, aMessageId, aData);
|
||||
}
|
||||
|
||||
nsresult rv = SpawnWorkerIfNeeded(PushEvent);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
|
@ -930,12 +911,6 @@ nsresult ServiceWorkerPrivate::SendPushEvent(
|
|||
}
|
||||
|
||||
nsresult ServiceWorkerPrivate::SendPushSubscriptionChangeEvent() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mInner) {
|
||||
return mInner->SendPushSubscriptionChangeEvent();
|
||||
}
|
||||
|
||||
nsresult rv = SpawnWorkerIfNeeded(PushSubscriptionChangeEvent);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
|
@ -1151,8 +1126,6 @@ nsresult ServiceWorkerPrivate::SendNotificationEvent(
|
|||
const nsAString& aDir, const nsAString& aLang, const nsAString& aBody,
|
||||
const nsAString& aTag, const nsAString& aIcon, const nsAString& aData,
|
||||
const nsAString& aBehavior, const nsAString& aScope) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
WakeUpReason why;
|
||||
if (aEventName.EqualsLiteral(NOTIFICATION_CLICK_EVENT_NAME)) {
|
||||
why = NotificationClickEvent;
|
||||
|
|
@ -1165,12 +1138,6 @@ nsresult ServiceWorkerPrivate::SendNotificationEvent(
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (mInner) {
|
||||
return mInner->SendNotificationEvent(aEventName, aID, aTitle, aDir, aLang,
|
||||
aBody, aTag, aIcon, aData, aBehavior,
|
||||
aScope, gDOMDisableOpenClickDelay);
|
||||
}
|
||||
|
||||
nsresult rv = SpawnWorkerIfNeeded(why);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
|
@ -1620,11 +1587,6 @@ nsresult ServiceWorkerPrivate::SendFetchEvent(
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mInner) {
|
||||
return mInner->SendFetchEvent(std::move(registration), aChannel, aClientId,
|
||||
aResultingClientId, aIsReload);
|
||||
}
|
||||
|
||||
aChannel->SetLaunchServiceWorkerStart(TimeStamp::Now());
|
||||
aChannel->SetDispatchFetchEventStart(TimeStamp::Now());
|
||||
|
||||
|
|
@ -1672,7 +1634,6 @@ nsresult ServiceWorkerPrivate::SpawnWorkerIfNeeded(WakeUpReason aWhy,
|
|||
bool* aNewWorkerCreated,
|
||||
nsILoadGroup* aLoadGroup) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!mInner);
|
||||
|
||||
// Defaults to no new worker created, but if there is one, we'll set the value
|
||||
// to true at the end of this function.
|
||||
|
|
@ -1829,10 +1790,6 @@ void ServiceWorkerPrivate::RemoveISupports(nsISupports* aSupports) {
|
|||
void ServiceWorkerPrivate::TerminateWorker() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mInner) {
|
||||
return mInner->TerminateWorker();
|
||||
}
|
||||
|
||||
mIdleWorkerTimer->Cancel();
|
||||
mIdleKeepAliveToken = nullptr;
|
||||
if (mWorkerPrivate) {
|
||||
|
|
@ -1860,15 +1817,8 @@ void ServiceWorkerPrivate::TerminateWorker() {
|
|||
|
||||
void ServiceWorkerPrivate::NoteDeadServiceWorkerInfo() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mInner) {
|
||||
mInner->NoteDeadOuter();
|
||||
mInner = nullptr;
|
||||
} else {
|
||||
TerminateWorker();
|
||||
}
|
||||
|
||||
mInfo = nullptr;
|
||||
TerminateWorker();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
|
@ -1894,10 +1844,6 @@ class UpdateStateControlRunnable final
|
|||
void ServiceWorkerPrivate::UpdateState(ServiceWorkerState aState) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mInner) {
|
||||
return mInner->UpdateState(aState);
|
||||
}
|
||||
|
||||
if (!mWorkerPrivate) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(mPendingFunctionalEvents.IsEmpty());
|
||||
return;
|
||||
|
|
@ -1926,11 +1872,6 @@ nsresult ServiceWorkerPrivate::GetDebugger(nsIWorkerDebugger** aResult) {
|
|||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aResult);
|
||||
|
||||
if (mInner) {
|
||||
*aResult = nullptr;
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (!mDebuggerCount) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
@ -1946,10 +1887,6 @@ nsresult ServiceWorkerPrivate::GetDebugger(nsIWorkerDebugger** aResult) {
|
|||
nsresult ServiceWorkerPrivate::AttachDebugger() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mInner) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// When the first debugger attaches to a worker, we spawn a worker if needed,
|
||||
// and cancel the idle timeout. The idle timeout should not be reset until
|
||||
// the last debugger detached from the worker.
|
||||
|
|
@ -1968,10 +1905,6 @@ nsresult ServiceWorkerPrivate::AttachDebugger() {
|
|||
nsresult ServiceWorkerPrivate::DetachDebugger() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mInner) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (!mDebuggerCount) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
|
@ -2053,10 +1986,7 @@ void ServiceWorkerPrivate::NoteIdleWorkerCallback(nsITimer* aTimer) {
|
|||
// Release ServiceWorkerPrivate's token, since the grace period has ended.
|
||||
mIdleKeepAliveToken = nullptr;
|
||||
|
||||
if (mWorkerPrivate || (mInner && !mInner->WorkerIsDead())) {
|
||||
// There sould only be EITHER mWorkerPrivate or mInner (but not both).
|
||||
MOZ_ASSERT(!(mWorkerPrivate && mInner));
|
||||
|
||||
if (mWorkerPrivate) {
|
||||
// If we still have a workerPrivate at this point it means there are pending
|
||||
// waitUntil promises. Wait a bit more until we forcibly terminate the
|
||||
// worker.
|
||||
|
|
@ -2087,7 +2017,7 @@ void ServiceWorkerPrivate::TerminateWorkerCallback(nsITimer* aTimer) {
|
|||
|
||||
void ServiceWorkerPrivate::RenewKeepAliveToken(WakeUpReason aWhy) {
|
||||
// We should have an active worker if we're renewing the keep alive token.
|
||||
MOZ_ASSERT(mWorkerPrivate || (mInner && !mInner->WorkerIsDead()));
|
||||
MOZ_ASSERT(mWorkerPrivate);
|
||||
|
||||
// If there is at least one debugger attached to the worker, the idle worker
|
||||
// timeout was canceled when the first debugger attached to the worker. It
|
||||
|
|
@ -2142,13 +2072,8 @@ void ServiceWorkerPrivate::ReleaseToken() {
|
|||
already_AddRefed<KeepAliveToken>
|
||||
ServiceWorkerPrivate::CreateEventKeepAliveToken() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// When the WorkerPrivate is in a separate process, we first hold a normal
|
||||
// KeepAliveToken. Then, after we're notified that the worker is alive, we
|
||||
// create the idle KeepAliveToken.
|
||||
MOZ_ASSERT(mWorkerPrivate || (mInner && !mInner->WorkerIsDead()));
|
||||
MOZ_ASSERT(mIdleKeepAliveToken || (mInner && !mInner->WorkerIsDead()));
|
||||
|
||||
MOZ_ASSERT(mWorkerPrivate);
|
||||
MOZ_ASSERT(mIdleKeepAliveToken);
|
||||
RefPtr<KeepAliveToken> ref = new KeepAliveToken(this);
|
||||
return ref.forget();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,10 +24,9 @@ class JSObjectHolder;
|
|||
namespace dom {
|
||||
|
||||
class ClientInfoAndState;
|
||||
class KeepAliveToken;
|
||||
class ServiceWorkerCloneData;
|
||||
class ServiceWorkerInfo;
|
||||
class ServiceWorkerPrivate;
|
||||
class ServiceWorkerPrivateImpl;
|
||||
class ServiceWorkerRegistrationInfo;
|
||||
|
||||
namespace ipc {
|
||||
|
|
@ -42,20 +41,6 @@ class LifeCycleEventCallback : public Runnable {
|
|||
virtual void SetResult(bool aResult) = 0;
|
||||
};
|
||||
|
||||
// Used to keep track of pending waitUntil as well as in-flight extendable
|
||||
// events. When the last token is released, we attempt to terminate the worker.
|
||||
class KeepAliveToken final : public nsISupports {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
explicit KeepAliveToken(ServiceWorkerPrivate* aPrivate);
|
||||
|
||||
private:
|
||||
~KeepAliveToken();
|
||||
|
||||
RefPtr<ServiceWorkerPrivate> mPrivate;
|
||||
};
|
||||
|
||||
// ServiceWorkerPrivate is a wrapper for managing the on-demand aspect of
|
||||
// service workers. It handles all event dispatching to the worker and ensures
|
||||
// the worker thread is running when needed.
|
||||
|
|
@ -89,7 +74,6 @@ class KeepAliveToken final : public nsISupports {
|
|||
// ExtendableEventWorkerRunnable.
|
||||
class ServiceWorkerPrivate final {
|
||||
friend class KeepAliveToken;
|
||||
friend class ServiceWorkerPrivateImpl;
|
||||
|
||||
public:
|
||||
NS_IMETHOD_(MozExternalRefCountType) AddRef();
|
||||
|
|
@ -103,48 +87,6 @@ class ServiceWorkerPrivate final {
|
|||
NS_DECL_OWNINGTHREAD
|
||||
|
||||
public:
|
||||
class Inner {
|
||||
public:
|
||||
NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
|
||||
|
||||
virtual nsresult SendMessageEvent(
|
||||
RefPtr<ServiceWorkerCloneData>&& aData,
|
||||
const ClientInfoAndState& aClientInfoAndState) = 0;
|
||||
|
||||
virtual nsresult CheckScriptEvaluation(
|
||||
RefPtr<LifeCycleEventCallback> aScriptEvaluationCallback) = 0;
|
||||
|
||||
virtual nsresult SendLifeCycleEvent(
|
||||
const nsAString& aEventName,
|
||||
RefPtr<LifeCycleEventCallback> aCallback) = 0;
|
||||
|
||||
virtual nsresult SendPushEvent(
|
||||
RefPtr<ServiceWorkerRegistrationInfo> aRegistration,
|
||||
const nsAString& aMessageId, const Maybe<nsTArray<uint8_t>>& aData) = 0;
|
||||
|
||||
virtual nsresult SendPushSubscriptionChangeEvent() = 0;
|
||||
|
||||
virtual nsresult SendNotificationEvent(
|
||||
const nsAString& aEventName, const nsAString& aID,
|
||||
const nsAString& aTitle, const nsAString& aDir, const nsAString& aLang,
|
||||
const nsAString& aBody, const nsAString& aTag, const nsAString& aIcon,
|
||||
const nsAString& aData, const nsAString& aBehavior,
|
||||
const nsAString& aScope, uint32_t aDisableOpenClickDelay) = 0;
|
||||
|
||||
virtual nsresult SendFetchEvent(
|
||||
RefPtr<ServiceWorkerRegistrationInfo> aRegistration,
|
||||
nsCOMPtr<nsIInterceptedChannel> aChannel, const nsAString& aClientId,
|
||||
const nsAString& aResultingClientId, bool aIsReload) = 0;
|
||||
|
||||
virtual void TerminateWorker() = 0;
|
||||
|
||||
virtual void UpdateState(ServiceWorkerState aState) = 0;
|
||||
|
||||
virtual void NoteDeadOuter() = 0;
|
||||
|
||||
virtual bool WorkerIsDead() const = 0;
|
||||
};
|
||||
|
||||
explicit ServiceWorkerPrivate(ServiceWorkerInfo* aInfo);
|
||||
|
||||
nsresult SendMessageEvent(RefPtr<ServiceWorkerCloneData>&& aData,
|
||||
|
|
@ -213,8 +155,7 @@ class ServiceWorkerPrivate final {
|
|||
NotificationClickEvent,
|
||||
NotificationCloseEvent,
|
||||
LifeCycleEvent,
|
||||
AttachEvent,
|
||||
Unknown
|
||||
AttachEvent
|
||||
};
|
||||
|
||||
// Timer callbacks
|
||||
|
|
@ -268,8 +209,6 @@ class ServiceWorkerPrivate final {
|
|||
// the worker activating. Main thread only.
|
||||
nsTArray<RefPtr<WorkerRunnable>> mPendingFunctionalEvents;
|
||||
|
||||
RefPtr<Inner> mInner;
|
||||
|
||||
// Used by the owning `ServiceWorkerRegistrationInfo` when it wants to call
|
||||
// `Clear` after being unregistered and isn't controlling any clients but this
|
||||
// worker (i.e. the registration's active worker) isn't idle yet. Note that
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,242 +0,0 @@
|
|||
/* -*- 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_serviceworkerprivateimpl_h__
|
||||
#define mozilla_dom_serviceworkerprivateimpl_h__
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
#include "ServiceWorkerPrivate.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/MozPromise.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/dom/RemoteWorkerController.h"
|
||||
#include "mozilla/dom/RemoteWorkerTypes.h"
|
||||
#include "mozilla/dom/ServiceWorkerOpArgs.h"
|
||||
|
||||
class nsIInterceptedChannel;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
template <typename T>
|
||||
class Maybe;
|
||||
|
||||
namespace ipc {
|
||||
|
||||
class AutoIPCStream;
|
||||
|
||||
} // namespace ipc
|
||||
|
||||
namespace dom {
|
||||
|
||||
class ClientInfoAndState;
|
||||
class LifeCycleEventCallback;
|
||||
class RemoteWorkerControllerChild;
|
||||
class ServiceWorkerCloneData;
|
||||
class ServiceWorkerRegistrationInfo;
|
||||
|
||||
class ServiceWorkerPrivateImpl final : public ServiceWorkerPrivate::Inner,
|
||||
public RemoteWorkerObserver {
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(ServiceWorkerPrivateImpl, override);
|
||||
|
||||
explicit ServiceWorkerPrivateImpl(RefPtr<ServiceWorkerPrivate> aOuter);
|
||||
|
||||
nsresult Initialize();
|
||||
|
||||
RefPtr<GenericPromise> SetSkipWaitingFlag();
|
||||
|
||||
private:
|
||||
class RAIIActorPtrHolder;
|
||||
|
||||
~ServiceWorkerPrivateImpl();
|
||||
|
||||
/**
|
||||
* ServiceWorkerPrivate::Inner
|
||||
*/
|
||||
nsresult SendMessageEvent(
|
||||
RefPtr<ServiceWorkerCloneData>&& aData,
|
||||
const ClientInfoAndState& aClientInfoAndState) override;
|
||||
|
||||
nsresult CheckScriptEvaluation(
|
||||
RefPtr<LifeCycleEventCallback> aCallback) override;
|
||||
|
||||
nsresult SendLifeCycleEvent(
|
||||
const nsAString& aEventName,
|
||||
RefPtr<LifeCycleEventCallback> aCallback) override;
|
||||
|
||||
nsresult SendPushEvent(RefPtr<ServiceWorkerRegistrationInfo> aRegistration,
|
||||
const nsAString& aMessageId,
|
||||
const Maybe<nsTArray<uint8_t>>& aData) override;
|
||||
|
||||
nsresult SendPushSubscriptionChangeEvent() override;
|
||||
|
||||
nsresult SendNotificationEvent(const nsAString& aEventName,
|
||||
const nsAString& aID, const nsAString& aTitle,
|
||||
const nsAString& aDir, const nsAString& aLang,
|
||||
const nsAString& aBody, const nsAString& aTag,
|
||||
const nsAString& aIcon, const nsAString& aData,
|
||||
const nsAString& aBehavior,
|
||||
const nsAString& aScope,
|
||||
uint32_t aDisableOpenClickDelay) override;
|
||||
|
||||
nsresult SendFetchEvent(RefPtr<ServiceWorkerRegistrationInfo> aRegistration,
|
||||
nsCOMPtr<nsIInterceptedChannel> aChannel,
|
||||
const nsAString& aClientId,
|
||||
const nsAString& aResultingClientId,
|
||||
bool aIsReload) override;
|
||||
|
||||
void TerminateWorker() override;
|
||||
|
||||
void UpdateState(ServiceWorkerState aState) override;
|
||||
|
||||
void NoteDeadOuter() override;
|
||||
|
||||
bool WorkerIsDead() const override;
|
||||
|
||||
/**
|
||||
* RemoteWorkerObserver
|
||||
*/
|
||||
void CreationFailed() override;
|
||||
|
||||
void CreationSucceeded() override;
|
||||
|
||||
void ErrorReceived(const ErrorValue& aError) override;
|
||||
|
||||
void Terminated() override;
|
||||
|
||||
// Refreshes only the parts of mRemoteWorkerData that may change over time.
|
||||
nsresult RefreshRemoteWorkerData(
|
||||
const RefPtr<ServiceWorkerRegistrationInfo>& aRegistration);
|
||||
|
||||
nsresult SpawnWorkerIfNeeded();
|
||||
|
||||
nsresult SendPushEventInternal(
|
||||
RefPtr<ServiceWorkerRegistrationInfo>&& aRegistration,
|
||||
ServiceWorkerPushEventOpArgs&& aArgs);
|
||||
|
||||
nsresult SendFetchEventInternal(
|
||||
RefPtr<ServiceWorkerRegistrationInfo>&& aRegistration,
|
||||
ServiceWorkerFetchEventOpArgs&& aArgs,
|
||||
nsCOMPtr<nsIInterceptedChannel>&& aChannel,
|
||||
UniquePtr<mozilla::ipc::AutoIPCStream>&& aAutoStream);
|
||||
|
||||
void Shutdown();
|
||||
|
||||
RefPtr<GenericNonExclusivePromise> ShutdownInternal();
|
||||
|
||||
nsresult ExecServiceWorkerOp(
|
||||
ServiceWorkerOpArgs&& aArgs,
|
||||
std::function<void(ServiceWorkerOpResult&&)>&& aSuccessCallback,
|
||||
std::function<void()>&& aFailureCallback = [] {});
|
||||
|
||||
class PendingFunctionalEvent {
|
||||
public:
|
||||
PendingFunctionalEvent(
|
||||
ServiceWorkerPrivateImpl* aOwner,
|
||||
RefPtr<ServiceWorkerRegistrationInfo>&& aRegistration);
|
||||
|
||||
virtual ~PendingFunctionalEvent();
|
||||
|
||||
virtual nsresult Send() = 0;
|
||||
|
||||
protected:
|
||||
ServiceWorkerPrivateImpl* const MOZ_NON_OWNING_REF mOwner;
|
||||
RefPtr<ServiceWorkerRegistrationInfo> mRegistration;
|
||||
};
|
||||
|
||||
class PendingPushEvent final : public PendingFunctionalEvent {
|
||||
public:
|
||||
PendingPushEvent(ServiceWorkerPrivateImpl* aOwner,
|
||||
RefPtr<ServiceWorkerRegistrationInfo>&& aRegistration,
|
||||
ServiceWorkerPushEventOpArgs&& aArgs);
|
||||
|
||||
nsresult Send() override;
|
||||
|
||||
private:
|
||||
ServiceWorkerPushEventOpArgs mArgs;
|
||||
};
|
||||
|
||||
class PendingFetchEvent final : public PendingFunctionalEvent {
|
||||
public:
|
||||
PendingFetchEvent(ServiceWorkerPrivateImpl* aOwner,
|
||||
RefPtr<ServiceWorkerRegistrationInfo>&& aRegistration,
|
||||
ServiceWorkerFetchEventOpArgs&& aArgs,
|
||||
nsCOMPtr<nsIInterceptedChannel>&& aChannel,
|
||||
UniquePtr<AutoIPCStream>&& aAutoStream);
|
||||
|
||||
nsresult Send() override;
|
||||
|
||||
~PendingFetchEvent();
|
||||
|
||||
private:
|
||||
ServiceWorkerFetchEventOpArgs mArgs;
|
||||
nsCOMPtr<nsIInterceptedChannel> mChannel;
|
||||
UniquePtr<mozilla::ipc::AutoIPCStream> mAutoStream;
|
||||
};
|
||||
|
||||
nsTArray<UniquePtr<PendingFunctionalEvent>> mPendingFunctionalEvents;
|
||||
|
||||
/**
|
||||
* It's possible that there are still in-progress operations when a
|
||||
* a termination operation is issued. In this case, it's important to keep
|
||||
* the RemoteWorkerControllerChild actor alive until all pending operations
|
||||
* have completed before destroying it with Send__delete__().
|
||||
*
|
||||
* RAIIActorPtrHolder holds a singular, owning reference to a
|
||||
* RemoteWorkerControllerChild actor and is responsible for destroying the
|
||||
* actor in its (i.e. the holder's) destructor. This implies that all
|
||||
* in-progress operations must maintain a strong reference to their
|
||||
* corresponding holders and release the reference once completed/canceled.
|
||||
*
|
||||
* Additionally a RAIIActorPtrHolder must be initialized with a non-null actor
|
||||
* and cannot be moved or copied. Therefore, the identities of two held
|
||||
* actors can be compared by simply comparing their holders' addresses.
|
||||
*/
|
||||
class RAIIActorPtrHolder final {
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(RAIIActorPtrHolder)
|
||||
|
||||
explicit RAIIActorPtrHolder(
|
||||
already_AddRefed<RemoteWorkerControllerChild> aActor);
|
||||
|
||||
RAIIActorPtrHolder(const RAIIActorPtrHolder& aOther) = delete;
|
||||
RAIIActorPtrHolder& operator=(const RAIIActorPtrHolder& aOther) = delete;
|
||||
|
||||
RAIIActorPtrHolder(RAIIActorPtrHolder&& aOther) = delete;
|
||||
RAIIActorPtrHolder& operator=(RAIIActorPtrHolder&& aOther) = delete;
|
||||
|
||||
RemoteWorkerControllerChild* operator->() const
|
||||
MOZ_NO_ADDREF_RELEASE_ON_RETURN;
|
||||
|
||||
RemoteWorkerControllerChild* get() const;
|
||||
|
||||
RefPtr<GenericPromise> OnDestructor();
|
||||
|
||||
private:
|
||||
~RAIIActorPtrHolder();
|
||||
|
||||
MozPromiseHolder<GenericPromise> mDestructorPromiseHolder;
|
||||
|
||||
const RefPtr<RemoteWorkerControllerChild> mActor;
|
||||
};
|
||||
|
||||
RefPtr<RAIIActorPtrHolder> mControllerChild;
|
||||
|
||||
RefPtr<ServiceWorkerPrivate> mOuter;
|
||||
|
||||
RemoteWorkerData mRemoteWorkerData;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_serviceworkerprivateimpl_h__
|
||||
|
|
@ -12,7 +12,6 @@
|
|||
#include "mozilla/dom/PushManager.h"
|
||||
#include "mozilla/dom/ServiceWorker.h"
|
||||
#include "mozilla/dom/ServiceWorkerRegistrationBinding.h"
|
||||
#include "mozilla/dom/ServiceWorkerUtils.h"
|
||||
#include "mozilla/dom/WorkerPrivate.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
|
|
@ -200,41 +199,6 @@ already_AddRefed<Promise> ServiceWorkerRegistration::Update(ErrorResult& aRv) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* `ServiceWorker` objects are not exposed on worker threads yet, so calling
|
||||
* `ServiceWorkerRegistration::Get{Installing,Waiting,Active}` won't work.
|
||||
*/
|
||||
const bool hasNewestWorker = mDescriptor.GetInstalling() ||
|
||||
mDescriptor.GetWaiting() ||
|
||||
mDescriptor.GetActive();
|
||||
|
||||
/**
|
||||
* If newestWorker is null, return a promise rejected with an
|
||||
* "InvalidStateError" DOMException and abort these steps.
|
||||
*/
|
||||
if (!hasNewestWorker) {
|
||||
outer->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return outer.forget();
|
||||
}
|
||||
|
||||
/**
|
||||
* If the context object’s relevant settings object’s global object
|
||||
* globalObject is a ServiceWorkerGlobalScope object, and globalObject’s
|
||||
* associated service worker's state is "installing", return a promise
|
||||
* rejected with an "InvalidStateError" DOMException and abort these steps.
|
||||
*/
|
||||
if (!NS_IsMainThread()) {
|
||||
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
||||
MOZ_ASSERT(workerPrivate);
|
||||
|
||||
if (workerPrivate->IsServiceWorker() &&
|
||||
(workerPrivate->GetServiceWorkerDescriptor().State() ==
|
||||
ServiceWorkerState::Installing)) {
|
||||
outer->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return outer.forget();
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<ServiceWorkerRegistration> self = this;
|
||||
|
||||
mInner->Update(
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
#include "ServiceWorkerRegistrationChild.h"
|
||||
|
||||
#include "RemoteServiceWorkerRegistrationImpl.h"
|
||||
#include "mozilla/dom/WorkerRef.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
|
|
|||
|
|
@ -294,20 +294,16 @@ ServiceWorkerRegistrationInfo::GetServiceWorkerInfoById(uint64_t aId) {
|
|||
return serviceWorker.forget();
|
||||
}
|
||||
|
||||
void ServiceWorkerRegistrationInfo::TryToActivateAsync(
|
||||
TryToActivateCallback&& aCallback) {
|
||||
void ServiceWorkerRegistrationInfo::TryToActivateAsync() {
|
||||
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(
|
||||
NewRunnableMethod<StoreCopyPassByRRef<TryToActivateCallback>>(
|
||||
"ServiceWorkerRegistrationInfo::TryToActivate", this,
|
||||
&ServiceWorkerRegistrationInfo::TryToActivate,
|
||||
std::move(aCallback))));
|
||||
NewRunnableMethod("ServiceWorkerRegistrationInfo::TryToActivate", this,
|
||||
&ServiceWorkerRegistrationInfo::TryToActivate)));
|
||||
}
|
||||
|
||||
/*
|
||||
* TryToActivate should not be called directly, use TryToActivateAsync instead.
|
||||
*/
|
||||
void ServiceWorkerRegistrationInfo::TryToActivate(
|
||||
TryToActivateCallback&& aCallback) {
|
||||
void ServiceWorkerRegistrationInfo::TryToActivate() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
bool controlling = IsControllingClients();
|
||||
bool skipWaiting = mWaitingWorker && mWaitingWorker->SkipWaitingFlag();
|
||||
|
|
@ -315,10 +311,6 @@ void ServiceWorkerRegistrationInfo::TryToActivate(
|
|||
if (idle && (!controlling || skipWaiting)) {
|
||||
Activate();
|
||||
}
|
||||
|
||||
if (aCallback) {
|
||||
aCallback();
|
||||
}
|
||||
}
|
||||
|
||||
void ServiceWorkerRegistrationInfo::Activate() {
|
||||
|
|
@ -709,14 +701,8 @@ uint64_t ServiceWorkerRegistrationInfo::Version() const {
|
|||
return mDescriptor.Version();
|
||||
}
|
||||
|
||||
uint32_t ServiceWorkerRegistrationInfo::GetUpdateDelay(
|
||||
const bool aWithMultiplier) {
|
||||
uint32_t ServiceWorkerRegistrationInfo::GetUpdateDelay() {
|
||||
uint32_t delay = Preferences::GetInt("dom.serviceWorkers.update_delay", 1000);
|
||||
|
||||
if (!aWithMultiplier) {
|
||||
return delay;
|
||||
}
|
||||
|
||||
// This can potentially happen if you spam registration->Update(). We don't
|
||||
// want to wrap to a lower value.
|
||||
if (mDelayMultiplier >= INT_MAX / (delay ? delay : 1)) {
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@
|
|||
#ifndef mozilla_dom_serviceworkerregistrationinfo_h
|
||||
#define mozilla_dom_serviceworkerregistrationinfo_h
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "mozilla/dom/ServiceWorkerInfo.h"
|
||||
#include "mozilla/dom/ServiceWorkerRegistrationBinding.h"
|
||||
#include "mozilla/dom/ServiceWorkerRegistrationDescriptor.h"
|
||||
|
|
@ -70,8 +68,6 @@ class ServiceWorkerRegistrationInfo final
|
|||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISERVICEWORKERREGISTRATIONINFO
|
||||
|
||||
typedef std::function<void()> TryToActivateCallback;
|
||||
|
||||
ServiceWorkerRegistrationInfo(const nsACString& aScope,
|
||||
nsIPrincipal* aPrincipal,
|
||||
ServiceWorkerUpdateViaCache aUpdateViaCache);
|
||||
|
|
@ -124,9 +120,9 @@ class ServiceWorkerRegistrationInfo final
|
|||
|
||||
bool IsCorrupt() const;
|
||||
|
||||
void TryToActivateAsync(TryToActivateCallback&& aCallback = nullptr);
|
||||
void TryToActivateAsync();
|
||||
|
||||
void TryToActivate(TryToActivateCallback&& aCallback);
|
||||
void TryToActivate();
|
||||
|
||||
void Activate();
|
||||
|
||||
|
|
@ -201,7 +197,7 @@ class ServiceWorkerRegistrationInfo final
|
|||
|
||||
uint64_t Version() const;
|
||||
|
||||
uint32_t GetUpdateDelay(const bool aWithMultiplier = true);
|
||||
uint32_t GetUpdateDelay();
|
||||
|
||||
void FireUpdateFound();
|
||||
|
||||
|
|
|
|||
|
|
@ -31,9 +31,6 @@ class ServiceWorkerRegistrationProxy::DelayedUpdate final
|
|||
DelayedUpdate(RefPtr<ServiceWorkerRegistrationProxy>&& aProxy,
|
||||
RefPtr<ServiceWorkerRegistrationPromise::Private>&& aPromise,
|
||||
uint32_t delay);
|
||||
|
||||
void ChainTo(RefPtr<ServiceWorkerRegistrationPromise::Private> aPromise);
|
||||
|
||||
void Reject();
|
||||
};
|
||||
|
||||
|
|
@ -267,15 +264,6 @@ ServiceWorkerRegistrationProxy::DelayedUpdate::DelayedUpdate(
|
|||
MOZ_DIAGNOSTIC_ASSERT(mTimer);
|
||||
}
|
||||
|
||||
void ServiceWorkerRegistrationProxy::DelayedUpdate::ChainTo(
|
||||
RefPtr<ServiceWorkerRegistrationPromise::Private> aPromise) {
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(mProxy->mDelayedUpdate == this);
|
||||
MOZ_ASSERT(mPromise);
|
||||
|
||||
mPromise->ChainTo(aPromise.forget(), __func__);
|
||||
}
|
||||
|
||||
void ServiceWorkerRegistrationProxy::DelayedUpdate::Reject() {
|
||||
MOZ_DIAGNOSTIC_ASSERT(mPromise);
|
||||
if (mTimer) {
|
||||
|
|
@ -287,13 +275,9 @@ void ServiceWorkerRegistrationProxy::DelayedUpdate::Reject() {
|
|||
|
||||
NS_IMETHODIMP
|
||||
ServiceWorkerRegistrationProxy::DelayedUpdate::Notify(nsITimer* aTimer) {
|
||||
// Already shutting down.
|
||||
if (mProxy->mDelayedUpdate != this) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
auto scopeExit = MakeScopeExit(
|
||||
[&] { mPromise->Reject(NS_ERROR_DOM_INVALID_STATE_ERR, __func__); });
|
||||
MOZ_DIAGNOSTIC_ASSERT((mProxy->mDelayedUpdate == this));
|
||||
|
||||
NS_ENSURE_TRUE(mProxy->mReg, NS_ERROR_FAILURE);
|
||||
|
||||
|
|
@ -325,21 +309,14 @@ ServiceWorkerRegistrationProxy::Update() {
|
|||
|
||||
// Get the delay value for the update
|
||||
NS_ENSURE_TRUE_VOID(self->mReg);
|
||||
uint32_t delay = self->mReg->GetUpdateDelay(false);
|
||||
uint32_t delay = self->mReg->GetUpdateDelay();
|
||||
|
||||
// If the delay value does not equal to 0, create a timer and a timer
|
||||
// callback to perform the delayed update. Otherwise, update directly.
|
||||
if (delay) {
|
||||
if (self->mDelayedUpdate) {
|
||||
// NOTE: if we `ChainTo(),` there will ultimately be a single
|
||||
// update, and this update will resolve all promises that were
|
||||
// issued while the update's timer was ticking down.
|
||||
self->mDelayedUpdate->ChainTo(std::move(promise));
|
||||
} else {
|
||||
RefPtr<ServiceWorkerRegistrationProxy::DelayedUpdate> du =
|
||||
new ServiceWorkerRegistrationProxy::DelayedUpdate(
|
||||
std::move(self), std::move(promise), delay);
|
||||
}
|
||||
} else {
|
||||
RefPtr<ServiceWorkerManager> swm =
|
||||
ServiceWorkerManager::GetInstance();
|
||||
|
|
|
|||
|
|
@ -1,174 +0,0 @@
|
|||
/* -*- 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 "ServiceWorkerShutdownBlocker.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "MainThreadUtils.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsError.h"
|
||||
#include "nsIWritablePropertyBag2.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_ISUPPORTS(ServiceWorkerShutdownBlocker, nsIAsyncShutdownBlocker)
|
||||
|
||||
NS_IMETHODIMP ServiceWorkerShutdownBlocker::GetName(nsAString& aNameOut) {
|
||||
aNameOut = NS_LITERAL_STRING(
|
||||
"ServiceWorkerShutdownBlocker: shutting down Service Workers");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ServiceWorkerShutdownBlocker::BlockShutdown(nsIAsyncShutdownClient* aClient) {
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(!mShutdownClient);
|
||||
|
||||
mShutdownClient = aClient;
|
||||
MaybeUnblockShutdown();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP ServiceWorkerShutdownBlocker::GetState(nsIPropertyBag** aBagOut) {
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aBagOut);
|
||||
|
||||
nsCOMPtr<nsIWritablePropertyBag2> propertyBag =
|
||||
do_CreateInstance("@mozilla.org/hash-property-bag;1");
|
||||
|
||||
if (NS_WARN_IF(!propertyBag)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nsresult rv = propertyBag->SetPropertyAsBool(
|
||||
NS_LITERAL_STRING("acceptingPromises"), IsAcceptingPromises());
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = propertyBag->SetPropertyAsUint32(NS_LITERAL_STRING("pendingPromises"),
|
||||
GetPendingPromises());
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
propertyBag.forget(aBagOut);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<ServiceWorkerShutdownBlocker>
|
||||
ServiceWorkerShutdownBlocker::CreateAndRegisterOn(
|
||||
nsIAsyncShutdownClient* aShutdownBarrier) {
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aShutdownBarrier);
|
||||
|
||||
RefPtr<ServiceWorkerShutdownBlocker> blocker =
|
||||
new ServiceWorkerShutdownBlocker();
|
||||
|
||||
nsresult rv = aShutdownBarrier->AddBlocker(
|
||||
blocker.get(), NS_LITERAL_STRING(__FILE__), __LINE__,
|
||||
NS_LITERAL_STRING("Service Workers shutdown"));
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return blocker.forget();
|
||||
}
|
||||
|
||||
void ServiceWorkerShutdownBlocker::WaitOnPromise(
|
||||
GenericNonExclusivePromise* aPromise) {
|
||||
AssertIsOnMainThread();
|
||||
MOZ_DIAGNOSTIC_ASSERT(IsAcceptingPromises());
|
||||
MOZ_ASSERT(aPromise);
|
||||
|
||||
++mState.as<AcceptingPromises>().mPendingPromises;
|
||||
|
||||
RefPtr<ServiceWorkerShutdownBlocker> self = this;
|
||||
|
||||
aPromise->Then(GetCurrentThreadSerialEventTarget(), __func__,
|
||||
[self = std::move(self)](
|
||||
const GenericNonExclusivePromise::ResolveOrRejectValue&) {
|
||||
if (!self->PromiseSettled()) {
|
||||
self->MaybeUnblockShutdown();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void ServiceWorkerShutdownBlocker::StopAcceptingPromises() {
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(IsAcceptingPromises());
|
||||
|
||||
mState = AsVariant(NotAcceptingPromises(mState.as<AcceptingPromises>()));
|
||||
}
|
||||
|
||||
ServiceWorkerShutdownBlocker::ServiceWorkerShutdownBlocker()
|
||||
: mState(VariantType<AcceptingPromises>()) {
|
||||
AssertIsOnMainThread();
|
||||
}
|
||||
|
||||
ServiceWorkerShutdownBlocker::~ServiceWorkerShutdownBlocker() {
|
||||
MOZ_ASSERT(!IsAcceptingPromises());
|
||||
MOZ_ASSERT(!GetPendingPromises());
|
||||
MOZ_ASSERT(!mShutdownClient);
|
||||
}
|
||||
|
||||
void ServiceWorkerShutdownBlocker::MaybeUnblockShutdown() {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (!mShutdownClient || IsAcceptingPromises() || GetPendingPromises()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mShutdownClient->RemoveBlocker(this);
|
||||
mShutdownClient = nullptr;
|
||||
}
|
||||
|
||||
uint32_t ServiceWorkerShutdownBlocker::PromiseSettled() {
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(GetPendingPromises());
|
||||
|
||||
if (IsAcceptingPromises()) {
|
||||
return --mState.as<AcceptingPromises>().mPendingPromises;
|
||||
}
|
||||
|
||||
return --mState.as<NotAcceptingPromises>().mPendingPromises;
|
||||
}
|
||||
|
||||
bool ServiceWorkerShutdownBlocker::IsAcceptingPromises() const {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
return mState.is<AcceptingPromises>();
|
||||
}
|
||||
|
||||
uint32_t ServiceWorkerShutdownBlocker::GetPendingPromises() const {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (IsAcceptingPromises()) {
|
||||
return mState.as<AcceptingPromises>().mPendingPromises;
|
||||
}
|
||||
|
||||
return mState.as<NotAcceptingPromises>().mPendingPromises;
|
||||
}
|
||||
|
||||
ServiceWorkerShutdownBlocker::NotAcceptingPromises::NotAcceptingPromises(
|
||||
AcceptingPromises aPreviousState)
|
||||
: mPendingPromises(aPreviousState.mPendingPromises) {
|
||||
AssertIsOnMainThread();
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
/* -*- 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_serviceworkershutdownblocker_h__
|
||||
#define mozilla_dom_serviceworkershutdownblocker_h__
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIAsyncShutdown.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
|
||||
#include "mozilla/MozPromise.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
/**
|
||||
* Main thread only.
|
||||
*/
|
||||
class ServiceWorkerShutdownBlocker final : public nsIAsyncShutdownBlocker {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIASYNCSHUTDOWNBLOCKER
|
||||
|
||||
/**
|
||||
* Returns the registered shutdown blocker if registration succeeded and
|
||||
* nullptr otherwise.
|
||||
*/
|
||||
static already_AddRefed<ServiceWorkerShutdownBlocker> CreateAndRegisterOn(
|
||||
nsIAsyncShutdownClient* aShutdownBarrier);
|
||||
|
||||
/**
|
||||
* Blocks shutdown until `aPromise` settles.
|
||||
*
|
||||
* Can be called multiple times, and shutdown will be blocked until all the
|
||||
* calls' promises settle, but all of these calls must happen before
|
||||
* `StopAcceptingPromises()` is called (assertions will enforce this).
|
||||
*/
|
||||
void WaitOnPromise(GenericNonExclusivePromise* aPromise);
|
||||
|
||||
/**
|
||||
* Once this is called, shutdown will be blocked until all promises
|
||||
* passed to `WaitOnPromise()` settle, and there must be no more calls to
|
||||
* `WaitOnPromise()` (assertions will enforce this).
|
||||
*/
|
||||
void StopAcceptingPromises();
|
||||
|
||||
private:
|
||||
ServiceWorkerShutdownBlocker();
|
||||
|
||||
~ServiceWorkerShutdownBlocker();
|
||||
|
||||
/**
|
||||
* No-op if any of the following are true:
|
||||
* 1) `BlockShutdown()` hasn't been called yet, or
|
||||
* 2) `StopAcceptingPromises()` hasn't been called yet, or
|
||||
* 3) `StopAcceptingPromises()` HAS been called, but there are still pending
|
||||
* promises.
|
||||
*/
|
||||
void MaybeUnblockShutdown();
|
||||
|
||||
/**
|
||||
* Returns the remaining pending promise count (i.e. excluding the promise
|
||||
* that just settled).
|
||||
*/
|
||||
uint32_t PromiseSettled();
|
||||
|
||||
bool IsAcceptingPromises() const;
|
||||
|
||||
uint32_t GetPendingPromises() const;
|
||||
|
||||
struct AcceptingPromises {
|
||||
uint32_t mPendingPromises = 0;
|
||||
};
|
||||
|
||||
struct NotAcceptingPromises {
|
||||
explicit NotAcceptingPromises(AcceptingPromises aPreviousState);
|
||||
|
||||
uint32_t mPendingPromises = 0;
|
||||
};
|
||||
|
||||
Variant<AcceptingPromises, NotAcceptingPromises> mState;
|
||||
|
||||
nsCOMPtr<nsIAsyncShutdownClient> mShutdownClient;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_serviceworkershutdownblocker_h__
|
||||
|
|
@ -9,13 +9,8 @@ with Files("**"):
|
|||
|
||||
# Public stuff.
|
||||
EXPORTS.mozilla.dom += [
|
||||
'FetchEventOpChild.h',
|
||||
'FetchEventOpParent.h',
|
||||
'FetchEventOpProxyChild.h',
|
||||
'FetchEventOpProxyParent.h',
|
||||
'ServiceWorker.h',
|
||||
'ServiceWorkerActors.h',
|
||||
'ServiceWorkerCloneData.h',
|
||||
'ServiceWorkerContainer.h',
|
||||
'ServiceWorkerDescriptor.h',
|
||||
'ServiceWorkerEvents.h',
|
||||
|
|
@ -25,8 +20,6 @@ EXPORTS.mozilla.dom += [
|
|||
'ServiceWorkerManager.h',
|
||||
'ServiceWorkerManagerChild.h',
|
||||
'ServiceWorkerManagerParent.h',
|
||||
'ServiceWorkerOp.h',
|
||||
'ServiceWorkerOpPromise.h',
|
||||
'ServiceWorkerRegistrar.h',
|
||||
'ServiceWorkerRegistration.h',
|
||||
'ServiceWorkerRegistrationDescriptor.h',
|
||||
|
|
@ -35,10 +28,6 @@ EXPORTS.mozilla.dom += [
|
|||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'FetchEventOpChild.cpp',
|
||||
'FetchEventOpParent.cpp',
|
||||
'FetchEventOpProxyChild.cpp',
|
||||
'FetchEventOpProxyParent.cpp',
|
||||
'RemoteServiceWorkerContainerImpl.cpp',
|
||||
'RemoteServiceWorkerImpl.cpp',
|
||||
'RemoteServiceWorkerRegistrationImpl.cpp',
|
||||
|
|
@ -62,10 +51,8 @@ UNIFIED_SOURCES += [
|
|||
'ServiceWorkerManagerChild.cpp',
|
||||
'ServiceWorkerManagerParent.cpp',
|
||||
'ServiceWorkerManagerService.cpp',
|
||||
'ServiceWorkerOp.cpp',
|
||||
'ServiceWorkerParent.cpp',
|
||||
'ServiceWorkerPrivate.cpp',
|
||||
'ServiceWorkerPrivateImpl.cpp',
|
||||
'ServiceWorkerProxy.cpp',
|
||||
'ServiceWorkerRegisterJob.cpp',
|
||||
'ServiceWorkerRegistrar.cpp',
|
||||
|
|
@ -77,7 +64,6 @@ UNIFIED_SOURCES += [
|
|||
'ServiceWorkerRegistrationParent.cpp',
|
||||
'ServiceWorkerRegistrationProxy.cpp',
|
||||
'ServiceWorkerScriptCache.cpp',
|
||||
'ServiceWorkerShutdownBlocker.cpp',
|
||||
'ServiceWorkerUnregisterCallback.cpp',
|
||||
'ServiceWorkerUnregisterJob.cpp',
|
||||
'ServiceWorkerUpdateJob.cpp',
|
||||
|
|
@ -89,14 +75,11 @@ UNIFIED_SOURCES += [
|
|||
IPDL_SOURCES += [
|
||||
'IPCServiceWorkerDescriptor.ipdlh',
|
||||
'IPCServiceWorkerRegistrationDescriptor.ipdlh',
|
||||
'PFetchEventOp.ipdl',
|
||||
'PFetchEventOpProxy.ipdl',
|
||||
'PServiceWorker.ipdl',
|
||||
'PServiceWorkerContainer.ipdl',
|
||||
'PServiceWorkerManager.ipdl',
|
||||
'PServiceWorkerRegistration.ipdl',
|
||||
'PServiceWorkerUpdater.ipdl',
|
||||
'ServiceWorkerOpArgs.ipdlh',
|
||||
'ServiceWorkerRegistrarTypes.ipdlh',
|
||||
]
|
||||
|
||||
|
|
@ -105,7 +88,6 @@ include('/ipc/chromium/chromium-config.mozbuild')
|
|||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'/extensions/permissions',
|
||||
'/js/xpconnect/loader',
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@
|
|||
#include "mozilla/dom/ErrorEventBinding.h"
|
||||
#include "mozilla/dom/RemoteWorkerChild.h"
|
||||
#include "mozilla/dom/ServiceWorkerManager.h"
|
||||
#include "mozilla/dom/ServiceWorkerUtils.h"
|
||||
#include "mozilla/dom/SimpleGlobalObject.h"
|
||||
#include "mozilla/dom/WorkerDebuggerGlobalScopeBinding.h"
|
||||
#include "mozilla/dom/WorkerGlobalScopeBinding.h"
|
||||
|
|
@ -81,28 +80,15 @@ class ReportErrorRunnable final : public WorkerDebuggeeRunnable {
|
|||
// worker error reporting will crash. Instead, pass the error to
|
||||
// the ServiceWorkerManager to report on any controlled documents.
|
||||
if (aWorkerPrivate->IsServiceWorker()) {
|
||||
if (ServiceWorkerParentInterceptEnabled()) {
|
||||
RefPtr<RemoteWorkerChild> actor(
|
||||
aWorkerPrivate->GetRemoteWorkerControllerWeakRef());
|
||||
|
||||
Unused << NS_WARN_IF(!actor);
|
||||
|
||||
if (actor) {
|
||||
actor->ErrorPropagationOnMainThread(nullptr, false);
|
||||
}
|
||||
|
||||
} else {
|
||||
RefPtr<ServiceWorkerManager> swm =
|
||||
ServiceWorkerManager::GetInstance();
|
||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
if (swm) {
|
||||
swm->HandleError(aCx, aWorkerPrivate->GetPrincipal(),
|
||||
aWorkerPrivate->ServiceWorkerScope(),
|
||||
aWorkerPrivate->ScriptURL(), EmptyString(),
|
||||
EmptyString(), EmptyString(), 0, 0, JSREPORT_ERROR,
|
||||
JSEXN_ERR);
|
||||
aWorkerPrivate->ScriptURL(), mReport->mMessage,
|
||||
mReport->mFilename, mReport->mLine,
|
||||
mReport->mLineNumber, mReport->mColumnNumber,
|
||||
mReport->mFlags, mReport->mExnType);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -173,17 +159,6 @@ class ReportGenericErrorRunnable final : public WorkerDebuggeeRunnable {
|
|||
}
|
||||
|
||||
if (aWorkerPrivate->IsServiceWorker()) {
|
||||
if (ServiceWorkerParentInterceptEnabled()) {
|
||||
RefPtr<RemoteWorkerChild> actor(
|
||||
aWorkerPrivate->GetRemoteWorkerControllerWeakRef());
|
||||
|
||||
Unused << NS_WARN_IF(!actor);
|
||||
|
||||
if (actor) {
|
||||
actor->ErrorPropagationOnMainThread(nullptr, false);
|
||||
}
|
||||
|
||||
} else {
|
||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
if (swm) {
|
||||
swm->HandleError(aCx, aWorkerPrivate->GetPrincipal(),
|
||||
|
|
@ -192,8 +167,6 @@ class ReportGenericErrorRunnable final : public WorkerDebuggeeRunnable {
|
|||
EmptyString(), EmptyString(), 0, 0, JSREPORT_ERROR,
|
||||
JSEXN_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@
|
|||
#include "mozilla/dom/PerformanceStorageWorker.h"
|
||||
#include "mozilla/dom/PromiseDebugging.h"
|
||||
#include "mozilla/dom/RemoteWorkerChild.h"
|
||||
#include "mozilla/dom/RemoteWorkerService.h"
|
||||
#include "mozilla/dom/TimeoutHandler.h"
|
||||
#include "mozilla/dom/WorkerBinding.h"
|
||||
#include "mozilla/StorageAccess.h"
|
||||
|
|
@ -54,7 +53,6 @@
|
|||
#include "nsIURI.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsProxyRelease.h"
|
||||
#include "nsQueryObject.h"
|
||||
#include "nsRFPService.h"
|
||||
#include "nsSandboxFlags.h"
|
||||
|
|
@ -4848,40 +4846,6 @@ RemoteWorkerChild* WorkerPrivate::GetRemoteWorkerController() {
|
|||
return mRemoteWorkerController;
|
||||
}
|
||||
|
||||
void WorkerPrivate::SetRemoteWorkerControllerWeakRef(
|
||||
ThreadSafeWeakPtr<RemoteWorkerChild> aWeakRef) {
|
||||
MOZ_ASSERT(aWeakRef);
|
||||
MOZ_ASSERT(!mRemoteWorkerControllerWeakRef);
|
||||
MOZ_ASSERT(IsServiceWorker());
|
||||
|
||||
mRemoteWorkerControllerWeakRef = std::move(aWeakRef);
|
||||
}
|
||||
|
||||
ThreadSafeWeakPtr<RemoteWorkerChild>
|
||||
WorkerPrivate::GetRemoteWorkerControllerWeakRef() {
|
||||
MOZ_ASSERT(IsServiceWorker());
|
||||
return mRemoteWorkerControllerWeakRef;
|
||||
}
|
||||
|
||||
RefPtr<GenericPromise> WorkerPrivate::SetServiceWorkerSkipWaitingFlag() {
|
||||
AssertIsOnWorkerThread();
|
||||
MOZ_ASSERT(IsServiceWorker());
|
||||
|
||||
RefPtr<RemoteWorkerChild> rwc(mRemoteWorkerControllerWeakRef);
|
||||
|
||||
if (!rwc) {
|
||||
return GenericPromise::CreateAndReject(NS_ERROR_DOM_ABORT_ERR, __func__);
|
||||
}
|
||||
|
||||
RefPtr<GenericPromise> promise =
|
||||
rwc->MaybeSendSetServiceWorkerSkipWaitingFlag();
|
||||
|
||||
NS_ProxyRelease("WorkerPrivate::mRemoteWorkerControllerWeakRef",
|
||||
RemoteWorkerService::Thread(), rwc.forget());
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
nsAString& WorkerPrivate::Id() {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
|
|
|
|||
|
|
@ -12,17 +12,14 @@
|
|||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/CondVar.h"
|
||||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
#include "mozilla/MozPromise.h"
|
||||
#include "mozilla/RelativeTimeline.h"
|
||||
#include "mozilla/StorageAccess.h"
|
||||
#include "mozilla/ThreadSafeWeakPtr.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIContentSecurityPolicy.h"
|
||||
#include "nsIEventTarget.h"
|
||||
#include "nsTObserverArray.h"
|
||||
|
||||
#include "js/ContextOptions.h"
|
||||
#include "mozilla/dom/RemoteWorkerChild.h"
|
||||
#include "mozilla/dom/Worker.h"
|
||||
#include "mozilla/dom/WorkerLoadInfo.h"
|
||||
#include "mozilla/dom/workerinternals/JSSettings.h"
|
||||
|
|
@ -46,6 +43,7 @@ class Function;
|
|||
class MessagePort;
|
||||
class MessagePortIdentifier;
|
||||
class PerformanceStorage;
|
||||
class RemoteWorkerChild;
|
||||
class TimeoutHandler;
|
||||
class WorkerControlRunnable;
|
||||
class WorkerCSPEventListener;
|
||||
|
|
@ -791,13 +789,6 @@ class WorkerPrivate : public RelativeTimeline {
|
|||
|
||||
void SetRemoteWorkerController(RemoteWorkerChild* aController);
|
||||
|
||||
void SetRemoteWorkerControllerWeakRef(
|
||||
ThreadSafeWeakPtr<RemoteWorkerChild> aWeakRef);
|
||||
|
||||
ThreadSafeWeakPtr<RemoteWorkerChild> GetRemoteWorkerControllerWeakRef();
|
||||
|
||||
RefPtr<GenericPromise> SetServiceWorkerSkipWaitingFlag();
|
||||
|
||||
// We can assume that an nsPIDOMWindow will be available for Freeze, Thaw
|
||||
// as these are only used for globals going in and out of the bfcache.
|
||||
bool Freeze(nsPIDOMWindowInner* aWindow);
|
||||
|
|
@ -1074,9 +1065,6 @@ class WorkerPrivate : public RelativeTimeline {
|
|||
// Only touched on the parent thread. This is set only if IsSharedWorker().
|
||||
RefPtr<RemoteWorkerChild> mRemoteWorkerController;
|
||||
|
||||
// This is set only if IsServiceWorker().
|
||||
ThreadSafeWeakPtr<RemoteWorkerChild> mRemoteWorkerControllerWeakRef;
|
||||
|
||||
JS::UniqueChars mDefaultLocale; // nulled during worker JSContext init
|
||||
TimeStamp mKillTime;
|
||||
WorkerStatus mParentStatus;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/PromiseWorkerProxy.h"
|
||||
#include "mozilla/dom/ServiceWorkerGlobalScopeBinding.h"
|
||||
#include "mozilla/dom/ServiceWorkerUtils.h"
|
||||
#include "mozilla/dom/SharedWorkerGlobalScopeBinding.h"
|
||||
#include "mozilla/dom/SimpleGlobalObject.h"
|
||||
#include "mozilla/dom/TimeoutHandler.h"
|
||||
|
|
@ -859,21 +858,6 @@ already_AddRefed<Promise> ServiceWorkerGlobalScope::SkipWaiting(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (ServiceWorkerParentInterceptEnabled()) {
|
||||
mWorkerPrivate->SetServiceWorkerSkipWaitingFlag()->Then(
|
||||
GetCurrentThreadSerialEventTarget(), __func__,
|
||||
[promise](bool aOk) {
|
||||
Unused << NS_WARN_IF(!aOk);
|
||||
promise->MaybeResolveWithUndefined();
|
||||
},
|
||||
[promise](nsresult aRv) {
|
||||
MOZ_ASSERT(NS_FAILED(aRv));
|
||||
promise->MaybeResolveWithUndefined();
|
||||
});
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
RefPtr<PromiseWorkerProxy> promiseProxy =
|
||||
PromiseWorkerProxy::Create(mWorkerPrivate, promise);
|
||||
if (!promiseProxy) {
|
||||
|
|
|
|||
|
|
@ -71,7 +71,6 @@ LOCAL_INCLUDES += [
|
|||
'/dom/base',
|
||||
'/dom/bindings',
|
||||
'/dom/system',
|
||||
'/dom/workers/remoteworkers',
|
||||
'/js/xpconnect/loader',
|
||||
'/netwerk/base',
|
||||
'/xpcom/build',
|
||||
|
|
|
|||
|
|
@ -3,10 +3,8 @@
|
|||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PBackground;
|
||||
include protocol PFetchEventOpProxy;
|
||||
|
||||
include DOMTypes;
|
||||
include ServiceWorkerOpArgs;
|
||||
include RemoteWorkerTypes;
|
||||
|
||||
namespace mozilla {
|
||||
|
|
@ -60,8 +58,6 @@ protocol PRemoteWorker
|
|||
{
|
||||
manager PBackground;
|
||||
|
||||
manages PFetchEventOpProxy;
|
||||
|
||||
parent:
|
||||
async Created(bool aStatus);
|
||||
|
||||
|
|
@ -69,17 +65,10 @@ parent:
|
|||
|
||||
async Close();
|
||||
|
||||
async SetServiceWorkerSkipWaitingFlag() returns (bool aOk);
|
||||
|
||||
child:
|
||||
async PFetchEventOpProxy(ServiceWorkerFetchEventOpArgs aArgs);
|
||||
|
||||
async __delete__();
|
||||
|
||||
async ExecOp(RemoteWorkerOp op);
|
||||
|
||||
async ExecServiceWorkerOp(ServiceWorkerOpArgs aArgs)
|
||||
returns (ServiceWorkerOpResult aResult);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
|||
|
|
@ -1,42 +0,0 @@
|
|||
/* 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 protocol PBackground;
|
||||
include protocol PFetchEventOp;
|
||||
|
||||
include RemoteWorkerTypes;
|
||||
include ServiceWorkerOpArgs;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
protocol PRemoteWorkerController {
|
||||
manager PBackground;
|
||||
|
||||
manages PFetchEventOp;
|
||||
|
||||
child:
|
||||
async CreationFailed();
|
||||
|
||||
async CreationSucceeded();
|
||||
|
||||
async ErrorReceived(ErrorValue aError);
|
||||
|
||||
async Terminated();
|
||||
|
||||
async SetServiceWorkerSkipWaitingFlag() returns (bool aOk);
|
||||
|
||||
parent:
|
||||
async PFetchEventOp(ServiceWorkerFetchEventOpArgs aArgs);
|
||||
|
||||
async __delete__();
|
||||
|
||||
async Shutdown() returns (bool aOk);
|
||||
|
||||
async ExecServiceWorkerOp(ServiceWorkerOpArgs aArgs)
|
||||
returns (ServiceWorkerOpResult aResult);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -7,157 +7,114 @@
|
|||
#ifndef mozilla_dom_RemoteWorkerChild_h
|
||||
#define mozilla_dom_RemoteWorkerChild_h
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
#include "mozilla/DataMutex.h"
|
||||
#include "mozilla/MozPromise.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/ThreadBound.h"
|
||||
#include "mozilla/ThreadSafeWeakPtr.h"
|
||||
#include "mozilla/dom/PRemoteWorkerChild.h"
|
||||
#include "mozilla/dom/ServiceWorkerOpArgs.h"
|
||||
#include "mozilla/DataMutex.h"
|
||||
#include "mozilla/ThreadBound.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
|
||||
class nsISerialEventTarget;
|
||||
class nsIConsoleReportCollector;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class ErrorValue;
|
||||
class FetchEventOpProxyChild;
|
||||
class RemoteWorkerData;
|
||||
class ServiceWorkerOp;
|
||||
class WeakWorkerRef;
|
||||
class WorkerErrorReport;
|
||||
class WorkerPrivate;
|
||||
class OptionalMessagePortIdentifier;
|
||||
|
||||
class RemoteWorkerChild final
|
||||
: public SupportsThreadSafeWeakPtr<RemoteWorkerChild>,
|
||||
public PRemoteWorkerChild {
|
||||
friend class FetchEventOpProxyChild;
|
||||
class RemoteWorkerChild final : public PRemoteWorkerChild {
|
||||
friend class PRemoteWorkerChild;
|
||||
friend class ServiceWorkerOp;
|
||||
|
||||
public:
|
||||
MOZ_DECLARE_THREADSAFEWEAKREFERENCE_TYPENAME(RemoteWorkerChild)
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RemoteWorkerChild)
|
||||
|
||||
MOZ_DECLARE_REFCOUNTED_TYPENAME(RemoteWorkerChild)
|
||||
|
||||
explicit RemoteWorkerChild(const RemoteWorkerData& aData);
|
||||
|
||||
~RemoteWorkerChild();
|
||||
|
||||
nsISerialEventTarget* GetOwningEventTarget() const;
|
||||
RemoteWorkerChild();
|
||||
|
||||
void ExecWorker(const RemoteWorkerData& aData);
|
||||
|
||||
void ErrorPropagationOnMainThread(const WorkerErrorReport* aReport,
|
||||
bool aIsErrorEvent);
|
||||
void InitializeOnWorker(WorkerPrivate* aWorkerPrivate);
|
||||
|
||||
void FlushReportsOnMainThread(nsIConsoleReportCollector* aReporter);
|
||||
void ShutdownOnWorker();
|
||||
|
||||
void AddPortIdentifier(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
|
||||
const MessagePortIdentifier& aPortIdentifier);
|
||||
|
||||
RefPtr<GenericNonExclusivePromise> GetTerminationPromise();
|
||||
void ErrorPropagationOnMainThread(const WorkerErrorReport* aReport,
|
||||
bool aIsErrorEvent);
|
||||
|
||||
RefPtr<GenericPromise> MaybeSendSetServiceWorkerSkipWaitingFlag();
|
||||
void CloseWorkerOnMainThread();
|
||||
|
||||
void FlushReportsOnMainThread(nsIConsoleReportCollector* aReporter);
|
||||
|
||||
private:
|
||||
class InitializeWorkerRunnable;
|
||||
|
||||
class Op;
|
||||
class SharedWorkerOp;
|
||||
~RemoteWorkerChild();
|
||||
|
||||
struct Pending {
|
||||
nsTArray<RefPtr<Op>> mPendingOps;
|
||||
};
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
struct PendingTerminated {};
|
||||
mozilla::ipc::IPCResult RecvExecOp(const RemoteWorkerOp& aOp);
|
||||
|
||||
struct Running {
|
||||
~Running();
|
||||
// This member is a function template because DataMutex<SharedData>::AutoLock
|
||||
// is private, yet it must be passed by const reference into ExecuteOperation.
|
||||
// There should only be one instantiation of this template.
|
||||
template <typename T>
|
||||
mozilla::ipc::IPCResult ExecuteOperation(const RemoteWorkerOp&,
|
||||
const T& aLock);
|
||||
|
||||
RefPtr<WorkerPrivate> mWorkerPrivate;
|
||||
RefPtr<WeakWorkerRef> mWorkerRef;
|
||||
};
|
||||
void RecvExecOpOnMainThread(const RemoteWorkerOp& aOp);
|
||||
|
||||
struct Terminated {};
|
||||
|
||||
using State = Variant<Pending, Running, PendingTerminated, Terminated>;
|
||||
|
||||
DataMutex<State> mState;
|
||||
|
||||
class Op {
|
||||
public:
|
||||
NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
|
||||
|
||||
virtual ~Op() = default;
|
||||
|
||||
virtual bool MaybeStart(RemoteWorkerChild* aOwner, State& aState) = 0;
|
||||
|
||||
virtual void Cancel() = 0;
|
||||
};
|
||||
|
||||
void ActorDestroy(ActorDestroyReason) override;
|
||||
|
||||
mozilla::ipc::IPCResult RecvExecOp(RemoteWorkerOp&& aOp);
|
||||
|
||||
mozilla::ipc::IPCResult RecvExecServiceWorkerOp(
|
||||
ServiceWorkerOpArgs&& aArgs, ExecServiceWorkerOpResolver&& aResolve);
|
||||
|
||||
PFetchEventOpProxyChild* AllocPFetchEventOpProxyChild(
|
||||
const ServiceWorkerFetchEventOpArgs& aArgs);
|
||||
|
||||
mozilla::ipc::IPCResult RecvPFetchEventOpProxyConstructor(
|
||||
PFetchEventOpProxyChild* aActor,
|
||||
const ServiceWorkerFetchEventOpArgs& aArgs) override;
|
||||
|
||||
bool DeallocPFetchEventOpProxyChild(PFetchEventOpProxyChild* aActor);
|
||||
|
||||
nsresult ExecWorkerOnMainThread(RemoteWorkerData&& aData);
|
||||
|
||||
void InitializeOnWorker(already_AddRefed<WorkerPrivate> aWorkerPrivate);
|
||||
|
||||
void ShutdownOnWorker();
|
||||
|
||||
void CreationSucceededOnAnyThread();
|
||||
|
||||
void CreationFailedOnAnyThread();
|
||||
|
||||
void CreationSucceededOrFailedOnAnyThread(bool aDidCreationSucceed);
|
||||
|
||||
void CloseWorkerOnMainThread(State& aState);
|
||||
nsresult ExecWorkerOnMainThread(const RemoteWorkerData& aData);
|
||||
|
||||
void ErrorPropagation(const ErrorValue& aValue);
|
||||
|
||||
void ErrorPropagationDispatch(nsresult aError);
|
||||
|
||||
void TransitionStateToPendingTerminated(State& aState);
|
||||
void CreationSucceededOnAnyThread();
|
||||
|
||||
void TransitionStateToRunning(already_AddRefed<WorkerPrivate> aWorkerPrivate,
|
||||
already_AddRefed<WeakWorkerRef> aWorkerRef);
|
||||
void CreationSucceeded();
|
||||
|
||||
void TransitionStateToTerminated();
|
||||
void CreationFailedOnAnyThread();
|
||||
|
||||
void TransitionStateToTerminated(State& aState);
|
||||
void CreationFailed();
|
||||
|
||||
void CancelAllPendingOps(State& aState);
|
||||
|
||||
void MaybeStartOp(RefPtr<Op>&& aOp);
|
||||
|
||||
MozPromiseHolder<GenericNonExclusivePromise> mTerminationPromise;
|
||||
|
||||
const bool mIsServiceWorker;
|
||||
const nsCOMPtr<nsISerialEventTarget> mOwningEventTarget;
|
||||
void WorkerTerminated();
|
||||
|
||||
// Touched on main-thread only.
|
||||
nsTArray<uint64_t> mWindowIDs;
|
||||
|
||||
RefPtr<WeakWorkerRef> mWorkerRef;
|
||||
bool mIPCActive;
|
||||
|
||||
enum WorkerState {
|
||||
// CreationSucceeded/CreationFailed not called yet.
|
||||
ePending,
|
||||
|
||||
// The worker is not created yet, but we want to terminate as soon as
|
||||
// possible.
|
||||
ePendingTerminated,
|
||||
|
||||
// Worker up and running.
|
||||
eRunning,
|
||||
|
||||
// Worker terminated.
|
||||
eTerminated,
|
||||
};
|
||||
|
||||
struct SharedData {
|
||||
SharedData();
|
||||
|
||||
RefPtr<WorkerPrivate> mWorkerPrivate;
|
||||
WorkerState mWorkerState;
|
||||
};
|
||||
|
||||
DataMutex<SharedData> mSharedData;
|
||||
|
||||
// Touched only on the owning thread (Worker Launcher).
|
||||
struct LauncherBoundData {
|
||||
bool mIPCActive = true;
|
||||
nsTArray<RemoteWorkerOp> mPendingOps;
|
||||
};
|
||||
|
||||
ThreadBound<LauncherBoundData> mLauncherData;
|
||||
|
|
|
|||
|
|
@ -4,20 +4,10 @@
|
|||
* 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 "RemoteWorkerController.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "nsDebug.h"
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
#include "mozilla/dom/MessagePort.h"
|
||||
#include "mozilla/dom/MessagePortParent.h"
|
||||
#include "mozilla/dom/RemoteWorkerTypes.h"
|
||||
#include "mozilla/dom/ServiceWorkerCloneData.h"
|
||||
#include "mozilla/ipc/BackgroundParent.h"
|
||||
#include "RemoteWorkerControllerParent.h"
|
||||
#include "RemoteWorkerController.h"
|
||||
#include "RemoteWorkerManager.h"
|
||||
#include "RemoteWorkerParent.h"
|
||||
|
||||
|
|
@ -31,12 +21,12 @@ namespace dom {
|
|||
already_AddRefed<RemoteWorkerController> RemoteWorkerController::Create(
|
||||
const RemoteWorkerData& aData, RemoteWorkerObserver* aObserver,
|
||||
base::ProcessId aProcessId) {
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(aObserver);
|
||||
|
||||
RefPtr<RemoteWorkerController> controller =
|
||||
new RemoteWorkerController(aData, aObserver);
|
||||
new RemoteWorkerController(aObserver);
|
||||
|
||||
RefPtr<RemoteWorkerManager> manager = RemoteWorkerManager::GetOrCreate();
|
||||
MOZ_ASSERT(manager);
|
||||
|
|
@ -46,44 +36,26 @@ already_AddRefed<RemoteWorkerController> RemoteWorkerController::Create(
|
|||
return controller.forget();
|
||||
}
|
||||
|
||||
RemoteWorkerController::RemoteWorkerController(const RemoteWorkerData& aData,
|
||||
RemoteWorkerObserver* aObserver)
|
||||
: mObserver(aObserver),
|
||||
mState(ePending),
|
||||
mIsServiceWorker(aData.serviceWorkerData().type() ==
|
||||
OptionalServiceWorkerData::TServiceWorkerData) {
|
||||
AssertIsInMainProcess();
|
||||
RemoteWorkerController::RemoteWorkerController(RemoteWorkerObserver* aObserver)
|
||||
: mObserver(aObserver), mState(ePending) {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
}
|
||||
|
||||
RemoteWorkerController::~RemoteWorkerController() {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_DIAGNOSTIC_ASSERT(mPendingOps.IsEmpty());
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
}
|
||||
|
||||
void RemoteWorkerController::SetWorkerActor(RemoteWorkerParent* aActor) {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(!mActor);
|
||||
MOZ_ASSERT(aActor);
|
||||
|
||||
mActor = aActor;
|
||||
}
|
||||
|
||||
void RemoteWorkerController::NoteDeadWorkerActor() {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(mActor);
|
||||
|
||||
// The actor has been destroyed without a proper close() notification. Let's
|
||||
// inform the observer.
|
||||
if (mState == eReady) {
|
||||
mObserver->Terminated();
|
||||
}
|
||||
|
||||
mActor = nullptr;
|
||||
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void RemoteWorkerController::CreationFailed() {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
|
@ -96,13 +68,13 @@ void RemoteWorkerController::CreationFailed() {
|
|||
return;
|
||||
}
|
||||
|
||||
NoteDeadWorker();
|
||||
|
||||
Shutdown();
|
||||
mObserver->CreationFailed();
|
||||
}
|
||||
|
||||
void RemoteWorkerController::CreationSucceeded() {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(mState == ePending || mState == eTerminated);
|
||||
|
||||
if (mState == eTerminated) {
|
||||
|
|
@ -117,347 +89,238 @@ void RemoteWorkerController::CreationSucceeded() {
|
|||
|
||||
mObserver->CreationSucceeded();
|
||||
|
||||
auto pendingOps = std::move(mPendingOps);
|
||||
for (UniquePtr<Op>& op : mPendingOps) {
|
||||
switch (op->mType) {
|
||||
case Op::eTerminate:
|
||||
Terminate();
|
||||
break;
|
||||
|
||||
for (auto& op : pendingOps) {
|
||||
DebugOnly<bool> started = op->MaybeStart(this);
|
||||
MOZ_ASSERT(started);
|
||||
case Op::eSuspend:
|
||||
Suspend();
|
||||
break;
|
||||
|
||||
case Op::eResume:
|
||||
Resume();
|
||||
break;
|
||||
|
||||
case Op::eFreeze:
|
||||
Freeze();
|
||||
break;
|
||||
|
||||
case Op::eThaw:
|
||||
Thaw();
|
||||
break;
|
||||
|
||||
case Op::ePortIdentifier:
|
||||
AddPortIdentifier(op->mPortIdentifier);
|
||||
break;
|
||||
|
||||
case Op::eAddWindowID:
|
||||
AddWindowID(op->mWindowID);
|
||||
break;
|
||||
|
||||
case Op::eRemoveWindowID:
|
||||
RemoveWindowID(op->mWindowID);
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Unknown op.");
|
||||
}
|
||||
|
||||
op->Completed();
|
||||
}
|
||||
|
||||
mPendingOps.Clear();
|
||||
}
|
||||
|
||||
void RemoteWorkerController::ErrorPropagation(const ErrorValue& aValue) {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
mObserver->ErrorReceived(aValue);
|
||||
}
|
||||
|
||||
void RemoteWorkerController::WorkerTerminated() {
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
NoteDeadWorker();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(mState == eReady);
|
||||
|
||||
mObserver->Terminated();
|
||||
}
|
||||
|
||||
void RemoteWorkerController::CancelAllPendingOps() {
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
auto pendingOps = std::move(mPendingOps);
|
||||
|
||||
for (auto& op : pendingOps) {
|
||||
op->Cancel();
|
||||
}
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void RemoteWorkerController::Shutdown() {
|
||||
AssertIsOnBackgroundThread();
|
||||
Unused << NS_WARN_IF(mIsServiceWorker && !mPendingOps.IsEmpty());
|
||||
|
||||
if (mState == eTerminated) {
|
||||
MOZ_ASSERT(mPendingOps.IsEmpty());
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(mState == ePending || mState == eReady);
|
||||
|
||||
mState = eTerminated;
|
||||
|
||||
CancelAllPendingOps();
|
||||
|
||||
if (!mActor) {
|
||||
return;
|
||||
}
|
||||
mPendingOps.Clear();
|
||||
|
||||
if (mActor) {
|
||||
mActor->SetController(nullptr);
|
||||
|
||||
/**
|
||||
* The "non-remote-side" of the Service Worker will have ensured that the
|
||||
* remote worker is terminated before calling `Shutdown().`
|
||||
*/
|
||||
if (mIsServiceWorker) {
|
||||
mActor->MaybeSendDelete();
|
||||
} else {
|
||||
Unused << mActor->SendExecOp(RemoteWorkerTerminateOp());
|
||||
}
|
||||
|
||||
mActor = nullptr;
|
||||
}
|
||||
|
||||
void RemoteWorkerController::NoteDeadWorker() {
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
CancelAllPendingOps();
|
||||
|
||||
/**
|
||||
* The "non-remote-side" of the Service Worker will initiate `Shutdown()`
|
||||
* once it's notified that all dispatched operations have either completed
|
||||
* or canceled. That is, it'll explicitly call `Shutdown()` later.
|
||||
*/
|
||||
if (!mIsServiceWorker) {
|
||||
Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void RemoteWorkerController::MaybeStartSharedWorkerOp(Args&&... aArgs) {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(!mIsServiceWorker);
|
||||
|
||||
UniquePtr<PendingSharedWorkerOp> op =
|
||||
MakeUnique<PendingSharedWorkerOp>(std::forward<Args>(aArgs)...);
|
||||
|
||||
if (!op->MaybeStart(this)) {
|
||||
mPendingOps.AppendElement(std::move(op));
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteWorkerController::AddWindowID(uint64_t aWindowID) {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(aWindowID);
|
||||
|
||||
MaybeStartSharedWorkerOp(PendingSharedWorkerOp::eAddWindowID, aWindowID);
|
||||
if (mState == ePending) {
|
||||
mPendingOps.AppendElement(new Op(Op::eAddWindowID, aWindowID));
|
||||
return;
|
||||
}
|
||||
|
||||
if (mState == eTerminated) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mState == eReady);
|
||||
Unused << mActor->SendExecOp(RemoteWorkerAddWindowIDOp(aWindowID));
|
||||
}
|
||||
|
||||
void RemoteWorkerController::RemoveWindowID(uint64_t aWindowID) {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(aWindowID);
|
||||
|
||||
MaybeStartSharedWorkerOp(PendingSharedWorkerOp::eRemoveWindowID, aWindowID);
|
||||
if (mState == ePending) {
|
||||
mPendingOps.AppendElement(new Op(Op::eRemoveWindowID, aWindowID));
|
||||
return;
|
||||
}
|
||||
|
||||
if (mState == eTerminated) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mState == eReady);
|
||||
Unused << mActor->SendExecOp(RemoteWorkerRemoveWindowIDOp(aWindowID));
|
||||
}
|
||||
|
||||
void RemoteWorkerController::AddPortIdentifier(
|
||||
const MessagePortIdentifier& aPortIdentifier) {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
MaybeStartSharedWorkerOp(aPortIdentifier);
|
||||
if (mState == ePending) {
|
||||
mPendingOps.AppendElement(new Op(aPortIdentifier));
|
||||
return;
|
||||
}
|
||||
|
||||
if (mState == eTerminated) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mState == eReady);
|
||||
Unused << mActor->SendExecOp(RemoteWorkerPortIdentifierOp(aPortIdentifier));
|
||||
}
|
||||
|
||||
void RemoteWorkerController::ForgetActorAndTerminate() {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
// The actor has been destroyed without a proper close() notification. Let's
|
||||
// inform the observer.
|
||||
if (mState == eReady) {
|
||||
mObserver->Terminated();
|
||||
}
|
||||
|
||||
mActor = nullptr;
|
||||
Terminate();
|
||||
}
|
||||
|
||||
void RemoteWorkerController::Terminate() {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
MaybeStartSharedWorkerOp(PendingSharedWorkerOp::eTerminate);
|
||||
if (mState == eTerminated) {
|
||||
return;
|
||||
}
|
||||
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void RemoteWorkerController::Suspend() {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
MaybeStartSharedWorkerOp(PendingSharedWorkerOp::eSuspend);
|
||||
if (mState == ePending) {
|
||||
mPendingOps.AppendElement(new Op(Op::eSuspend));
|
||||
return;
|
||||
}
|
||||
|
||||
if (mState == eTerminated) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mState == eReady);
|
||||
Unused << mActor->SendExecOp(RemoteWorkerSuspendOp());
|
||||
}
|
||||
|
||||
void RemoteWorkerController::Resume() {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
MaybeStartSharedWorkerOp(PendingSharedWorkerOp::eResume);
|
||||
if (mState == ePending) {
|
||||
mPendingOps.AppendElement(new Op(Op::eResume));
|
||||
return;
|
||||
}
|
||||
|
||||
if (mState == eTerminated) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mState == eReady);
|
||||
Unused << mActor->SendExecOp(RemoteWorkerResumeOp());
|
||||
}
|
||||
|
||||
void RemoteWorkerController::Freeze() {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
MaybeStartSharedWorkerOp(PendingSharedWorkerOp::eFreeze);
|
||||
if (mState == ePending) {
|
||||
mPendingOps.AppendElement(new Op(Op::eFreeze));
|
||||
return;
|
||||
}
|
||||
|
||||
if (mState == eTerminated) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mState == eReady);
|
||||
Unused << mActor->SendExecOp(RemoteWorkerFreezeOp());
|
||||
}
|
||||
|
||||
void RemoteWorkerController::Thaw() {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
MaybeStartSharedWorkerOp(PendingSharedWorkerOp::eThaw);
|
||||
}
|
||||
|
||||
RefPtr<ServiceWorkerOpPromise> RemoteWorkerController::ExecServiceWorkerOp(
|
||||
ServiceWorkerOpArgs&& aArgs) {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(mIsServiceWorker);
|
||||
|
||||
RefPtr<ServiceWorkerOpPromise::Private> promise =
|
||||
new ServiceWorkerOpPromise::Private(__func__);
|
||||
|
||||
UniquePtr<PendingServiceWorkerOp> op =
|
||||
MakeUnique<PendingServiceWorkerOp>(std::move(aArgs), promise);
|
||||
|
||||
if (!op->MaybeStart(this)) {
|
||||
mPendingOps.AppendElement(std::move(op));
|
||||
if (mState == ePending) {
|
||||
mPendingOps.AppendElement(new Op(Op::eThaw));
|
||||
return;
|
||||
}
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
RefPtr<GenericPromise> RemoteWorkerController::SetServiceWorkerSkipWaitingFlag()
|
||||
const {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(mObserver);
|
||||
|
||||
RefPtr<GenericPromise::Private> promise =
|
||||
new GenericPromise::Private(__func__);
|
||||
|
||||
static_cast<RemoteWorkerControllerParent*>(mObserver.get())
|
||||
->MaybeSendSetServiceWorkerSkipWaitingFlag(
|
||||
[promise](bool aOk) { promise->Resolve(aOk, __func__); });
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
RemoteWorkerController::PendingSharedWorkerOp::PendingSharedWorkerOp(
|
||||
Type aType, uint64_t aWindowID)
|
||||
: mType(aType), mWindowID(aWindowID) {
|
||||
AssertIsOnBackgroundThread();
|
||||
}
|
||||
|
||||
RemoteWorkerController::PendingSharedWorkerOp::PendingSharedWorkerOp(
|
||||
const MessagePortIdentifier& aPortIdentifier)
|
||||
: mType(ePortIdentifier), mPortIdentifier(aPortIdentifier) {
|
||||
AssertIsOnBackgroundThread();
|
||||
}
|
||||
|
||||
RemoteWorkerController::PendingSharedWorkerOp::~PendingSharedWorkerOp() {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_DIAGNOSTIC_ASSERT(mCompleted);
|
||||
}
|
||||
|
||||
bool RemoteWorkerController::PendingSharedWorkerOp::MaybeStart(
|
||||
RemoteWorkerController* const aOwner) {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(!mCompleted);
|
||||
MOZ_ASSERT(aOwner);
|
||||
|
||||
if (aOwner->mState == RemoteWorkerController::eTerminated) {
|
||||
Cancel();
|
||||
return true;
|
||||
if (mState == eTerminated) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aOwner->mState == RemoteWorkerController::ePending &&
|
||||
mType != eTerminate) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (mType) {
|
||||
case eTerminate:
|
||||
aOwner->Shutdown();
|
||||
break;
|
||||
case eSuspend:
|
||||
Unused << aOwner->mActor->SendExecOp(RemoteWorkerSuspendOp());
|
||||
break;
|
||||
case eResume:
|
||||
Unused << aOwner->mActor->SendExecOp(RemoteWorkerResumeOp());
|
||||
break;
|
||||
case eFreeze:
|
||||
Unused << aOwner->mActor->SendExecOp(RemoteWorkerFreezeOp());
|
||||
break;
|
||||
case eThaw:
|
||||
Unused << aOwner->mActor->SendExecOp(RemoteWorkerThawOp());
|
||||
break;
|
||||
case ePortIdentifier:
|
||||
Unused << aOwner->mActor->SendExecOp(
|
||||
RemoteWorkerPortIdentifierOp(mPortIdentifier));
|
||||
break;
|
||||
case eAddWindowID:
|
||||
Unused << aOwner->mActor->SendExecOp(
|
||||
RemoteWorkerAddWindowIDOp(mWindowID));
|
||||
break;
|
||||
case eRemoveWindowID:
|
||||
Unused << aOwner->mActor->SendExecOp(
|
||||
RemoteWorkerRemoveWindowIDOp(mWindowID));
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Unknown op.");
|
||||
}
|
||||
|
||||
mCompleted = true;
|
||||
|
||||
return true;
|
||||
MOZ_ASSERT(mState == eReady);
|
||||
Unused << mActor->SendExecOp(RemoteWorkerThawOp());
|
||||
}
|
||||
|
||||
void RemoteWorkerController::PendingSharedWorkerOp::Cancel() {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(!mCompleted);
|
||||
RemoteWorkerController::Op::~Op() {
|
||||
MOZ_COUNT_DTOR(Op);
|
||||
|
||||
// We don't want to leak the port if the operation has not been processed.
|
||||
if (mType == ePortIdentifier) {
|
||||
if (!mCompleted && mType == ePortIdentifier) {
|
||||
MessagePortParent::ForceClose(mPortIdentifier.uuid(),
|
||||
mPortIdentifier.destinationUuid(),
|
||||
mPortIdentifier.sequenceId());
|
||||
}
|
||||
|
||||
mCompleted = true;
|
||||
}
|
||||
|
||||
RemoteWorkerController::PendingServiceWorkerOp::PendingServiceWorkerOp(
|
||||
ServiceWorkerOpArgs&& aArgs,
|
||||
RefPtr<ServiceWorkerOpPromise::Private> aPromise)
|
||||
: mArgs(std::move(aArgs)), mPromise(std::move(aPromise)) {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(mPromise);
|
||||
}
|
||||
|
||||
RemoteWorkerController::PendingServiceWorkerOp::~PendingServiceWorkerOp() {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_DIAGNOSTIC_ASSERT(!mPromise);
|
||||
}
|
||||
|
||||
bool RemoteWorkerController::PendingServiceWorkerOp::MaybeStart(
|
||||
RemoteWorkerController* const aOwner) {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(mPromise);
|
||||
MOZ_ASSERT(aOwner);
|
||||
|
||||
if (NS_WARN_IF(aOwner->mState == RemoteWorkerController::eTerminated)) {
|
||||
mPromise->Reject(NS_ERROR_DOM_ABORT_ERR, __func__);
|
||||
mPromise = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
// The target content process must still be starting up.
|
||||
if (!aOwner->mActor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow termination operations to pass through while pending because the
|
||||
* remote Service Worker can be terminated while still starting up.
|
||||
*/
|
||||
if (aOwner->mState == RemoteWorkerController::ePending &&
|
||||
mArgs.type() !=
|
||||
ServiceWorkerOpArgs::TServiceWorkerTerminateWorkerOpArgs) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mArgs.type() == ServiceWorkerOpArgs::TServiceWorkerMessageEventOpArgs) {
|
||||
auto& args = mArgs.get_ServiceWorkerMessageEventOpArgs();
|
||||
|
||||
ServiceWorkerMessageEventOpArgs copyArgs;
|
||||
copyArgs.clientInfoAndState() = std::move(args.clientInfoAndState());
|
||||
|
||||
RefPtr<ServiceWorkerCloneData> copyData = new ServiceWorkerCloneData();
|
||||
copyData->StealFromClonedMessageDataForBackgroundParent(args.clonedData());
|
||||
|
||||
if (!copyData->BuildClonedMessageDataForBackgroundParent(
|
||||
aOwner->mActor->Manager(), copyArgs.clonedData())) {
|
||||
mPromise->Reject(NS_ERROR_DOM_DATA_CLONE_ERR, __func__);
|
||||
mPromise = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
mArgs = std::move(copyArgs);
|
||||
}
|
||||
|
||||
aOwner->mActor->SendExecServiceWorkerOp(mArgs)->Then(
|
||||
GetCurrentThreadSerialEventTarget(), __func__,
|
||||
[promise = std::move(mPromise)](
|
||||
PRemoteWorkerParent::ExecServiceWorkerOpPromise::
|
||||
ResolveOrRejectValue&& aResult) {
|
||||
if (NS_WARN_IF(aResult.IsReject())) {
|
||||
promise->Reject(NS_ERROR_DOM_ABORT_ERR, __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
promise->Resolve(std::move(aResult.ResolveValue()), __func__);
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RemoteWorkerController::PendingServiceWorkerOp::Cancel() {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(mPromise);
|
||||
|
||||
mPromise->Reject(NS_ERROR_DOM_ABORT_ERR, __func__);
|
||||
mPromise = nullptr;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
|||
|
|
@ -8,13 +8,6 @@
|
|||
#define mozilla_dom_RemoteWorkerController_h
|
||||
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/dom/DOMTypes.h"
|
||||
#include "mozilla/dom/ServiceWorkerOpArgs.h"
|
||||
#include "mozilla/dom/ServiceWorkerOpPromise.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
|
@ -86,8 +79,7 @@ namespace dom {
|
|||
*/
|
||||
|
||||
class ErrorValue;
|
||||
class RemoteWorkerControllerParent;
|
||||
class RemoteWorkerData;
|
||||
class MessagePortIdentifier;
|
||||
class RemoteWorkerManager;
|
||||
class RemoteWorkerParent;
|
||||
|
||||
|
|
@ -105,7 +97,6 @@ class RemoteWorkerObserver {
|
|||
};
|
||||
|
||||
class RemoteWorkerController final {
|
||||
friend class RemoteWorkerControllerParent;
|
||||
friend class RemoteWorkerManager;
|
||||
friend class RemoteWorkerParent;
|
||||
|
||||
|
|
@ -132,38 +123,24 @@ class RemoteWorkerController final {
|
|||
|
||||
void Thaw();
|
||||
|
||||
RefPtr<ServiceWorkerOpPromise> ExecServiceWorkerOp(
|
||||
ServiceWorkerOpArgs&& aArgs);
|
||||
|
||||
RefPtr<GenericPromise> SetServiceWorkerSkipWaitingFlag() const;
|
||||
|
||||
private:
|
||||
RemoteWorkerController(const RemoteWorkerData& aData,
|
||||
RemoteWorkerObserver* aObserver);
|
||||
|
||||
explicit RemoteWorkerController(RemoteWorkerObserver* aObserver);
|
||||
~RemoteWorkerController();
|
||||
|
||||
void SetWorkerActor(RemoteWorkerParent* aActor);
|
||||
|
||||
void NoteDeadWorkerActor();
|
||||
|
||||
void ErrorPropagation(const ErrorValue& aValue);
|
||||
|
||||
void WorkerTerminated();
|
||||
|
||||
void ForgetActorAndTerminate();
|
||||
|
||||
void Shutdown();
|
||||
|
||||
void CreationFailed();
|
||||
|
||||
void CreationSucceeded();
|
||||
|
||||
void CancelAllPendingOps();
|
||||
|
||||
template <typename... Args>
|
||||
void MaybeStartSharedWorkerOp(Args&&... aArgs);
|
||||
|
||||
void NoteDeadWorker();
|
||||
|
||||
RefPtr<RemoteWorkerObserver> mObserver;
|
||||
RefPtr<RemoteWorkerParent> mActor;
|
||||
|
||||
|
|
@ -173,35 +150,7 @@ class RemoteWorkerController final {
|
|||
eTerminated,
|
||||
} mState;
|
||||
|
||||
const bool mIsServiceWorker;
|
||||
|
||||
/**
|
||||
* `PendingOp` is responsible for encapsulating logic for starting and
|
||||
* canceling pending remote worker operations, as this logic may vary
|
||||
* depending on the type of the remote worker and the type of the operation.
|
||||
*/
|
||||
class PendingOp {
|
||||
public:
|
||||
PendingOp() = default;
|
||||
|
||||
PendingOp(const PendingOp&) = delete;
|
||||
|
||||
PendingOp& operator=(const PendingOp&) = delete;
|
||||
|
||||
virtual ~PendingOp() = default;
|
||||
|
||||
/**
|
||||
* Returns `true` if execution has started and `false` otherwise.
|
||||
*
|
||||
* Starting execution may depend the state of `aOwner.`
|
||||
*/
|
||||
virtual bool MaybeStart(RemoteWorkerController* const aOwner) = 0;
|
||||
|
||||
virtual void Cancel() = 0;
|
||||
};
|
||||
|
||||
class PendingSharedWorkerOp final : public PendingOp {
|
||||
public:
|
||||
struct Op {
|
||||
enum Type {
|
||||
eTerminate,
|
||||
eSuspend,
|
||||
|
|
@ -213,41 +162,34 @@ class RemoteWorkerController final {
|
|||
eRemoveWindowID,
|
||||
};
|
||||
|
||||
explicit PendingSharedWorkerOp(Type aType, uint64_t aWindowID = 0);
|
||||
explicit Op(Type aType, uint64_t aWindowID = 0)
|
||||
: mType(aType), mWindowID(aWindowID), mCompleted(false) {
|
||||
MOZ_COUNT_CTOR(Op);
|
||||
}
|
||||
|
||||
explicit PendingSharedWorkerOp(
|
||||
const MessagePortIdentifier& aPortIdentifier);
|
||||
explicit Op(const MessagePortIdentifier& aPortIdentifier)
|
||||
: mType(ePortIdentifier),
|
||||
mPortIdentifier(aPortIdentifier),
|
||||
mCompleted(false) {
|
||||
MOZ_COUNT_CTOR(Op);
|
||||
}
|
||||
|
||||
~PendingSharedWorkerOp();
|
||||
// This object cannot be copied.
|
||||
Op(Op const&) = delete;
|
||||
Op& operator=(Op const&) = delete;
|
||||
|
||||
bool MaybeStart(RemoteWorkerController* const aOwner) override;
|
||||
~Op();
|
||||
|
||||
void Cancel() override;
|
||||
void Completed() { mCompleted = true; }
|
||||
|
||||
private:
|
||||
const Type mType;
|
||||
const MessagePortIdentifier mPortIdentifier;
|
||||
const uint64_t mWindowID = 0;
|
||||
bool mCompleted = false;
|
||||
Type mType;
|
||||
|
||||
MessagePortIdentifier mPortIdentifier;
|
||||
uint64_t mWindowID;
|
||||
bool mCompleted;
|
||||
};
|
||||
|
||||
class PendingServiceWorkerOp final : public PendingOp {
|
||||
public:
|
||||
PendingServiceWorkerOp(ServiceWorkerOpArgs&& aArgs,
|
||||
RefPtr<ServiceWorkerOpPromise::Private> aPromise);
|
||||
|
||||
~PendingServiceWorkerOp();
|
||||
|
||||
bool MaybeStart(RemoteWorkerController* const aOwner) override;
|
||||
|
||||
void Cancel() override;
|
||||
|
||||
private:
|
||||
ServiceWorkerOpArgs mArgs;
|
||||
RefPtr<ServiceWorkerOpPromise::Private> mPromise;
|
||||
};
|
||||
|
||||
nsTArray<UniquePtr<PendingOp>> mPendingOps;
|
||||
nsTArray<UniquePtr<Op>> mPendingOps;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
|||
|
|
@ -1,149 +0,0 @@
|
|||
/* -*- 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 "RemoteWorkerControllerChild.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "MainThreadUtils.h"
|
||||
#include "nsError.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
#include "ServiceWorkerPrivateImpl.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/dom/PFetchEventOpChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
using ipc::IPCResult;
|
||||
|
||||
namespace dom {
|
||||
|
||||
RemoteWorkerControllerChild::RemoteWorkerControllerChild(
|
||||
RefPtr<RemoteWorkerObserver> aObserver)
|
||||
: mObserver(std::move(aObserver)) {
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(mObserver);
|
||||
}
|
||||
|
||||
PFetchEventOpChild* RemoteWorkerControllerChild::AllocPFetchEventOpChild(
|
||||
const ServiceWorkerFetchEventOpArgs& aArgs) {
|
||||
MOZ_CRASH("PFetchEventOpChild actors must be manually constructed!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool RemoteWorkerControllerChild::DeallocPFetchEventOpChild(
|
||||
PFetchEventOpChild* aActor) {
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aActor);
|
||||
|
||||
delete aActor;
|
||||
return true;
|
||||
}
|
||||
|
||||
void RemoteWorkerControllerChild::ActorDestroy(ActorDestroyReason aReason) {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
mIPCActive = false;
|
||||
|
||||
if (NS_WARN_IF(mObserver)) {
|
||||
mObserver->ErrorReceived(NS_ERROR_DOM_ABORT_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
IPCResult RemoteWorkerControllerChild::RecvCreationFailed() {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (mObserver) {
|
||||
mObserver->CreationFailed();
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
IPCResult RemoteWorkerControllerChild::RecvCreationSucceeded() {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (mObserver) {
|
||||
mObserver->CreationSucceeded();
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
IPCResult RemoteWorkerControllerChild::RecvErrorReceived(
|
||||
const ErrorValue& aError) {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (mObserver) {
|
||||
mObserver->ErrorReceived(aError);
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
IPCResult RemoteWorkerControllerChild::RecvTerminated() {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (mObserver) {
|
||||
mObserver->Terminated();
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
IPCResult RemoteWorkerControllerChild::RecvSetServiceWorkerSkipWaitingFlag(
|
||||
SetServiceWorkerSkipWaitingFlagResolver&& aResolve) {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (mObserver) {
|
||||
static_cast<ServiceWorkerPrivateImpl*>(mObserver.get())
|
||||
->SetSkipWaitingFlag()
|
||||
->Then(GetCurrentThreadSerialEventTarget(), __func__,
|
||||
[resolve = std::move(aResolve)](
|
||||
const GenericPromise::ResolveOrRejectValue& aResult) {
|
||||
resolve(aResult.IsResolve() ? aResult.ResolveValue() : false);
|
||||
});
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
aResolve(false);
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void RemoteWorkerControllerChild::RevokeObserver(
|
||||
RemoteWorkerObserver* aObserver) {
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aObserver);
|
||||
MOZ_ASSERT(aObserver == mObserver);
|
||||
|
||||
mObserver = nullptr;
|
||||
}
|
||||
|
||||
void RemoteWorkerControllerChild::MaybeSendDelete() {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (!mIPCActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<RemoteWorkerControllerChild> self = this;
|
||||
|
||||
SendShutdown()->Then(
|
||||
GetCurrentThreadSerialEventTarget(), __func__,
|
||||
[self = std::move(self)](const ShutdownPromise::ResolveOrRejectValue&) {
|
||||
if (self->mIPCActive) {
|
||||
Unused << self->Send__delete__(self);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
/* -*- 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_remoteworkercontrollerchild_h__
|
||||
#define mozilla_dom_remoteworkercontrollerchild_h__
|
||||
|
||||
#include "nsISupportsImpl.h"
|
||||
|
||||
#include "RemoteWorkerController.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/dom/PRemoteWorkerControllerChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class RemoteWorkerControllerChild final : public PRemoteWorkerControllerChild {
|
||||
friend class PRemoteWorkerControllerChild;
|
||||
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(RemoteWorkerControllerChild)
|
||||
|
||||
explicit RemoteWorkerControllerChild(RefPtr<RemoteWorkerObserver> aObserver);
|
||||
|
||||
void Initialize();
|
||||
|
||||
void RevokeObserver(RemoteWorkerObserver* aObserver);
|
||||
|
||||
void MaybeSendDelete();
|
||||
|
||||
private:
|
||||
~RemoteWorkerControllerChild() = default;
|
||||
|
||||
PFetchEventOpChild* AllocPFetchEventOpChild(
|
||||
const ServiceWorkerFetchEventOpArgs& aArgs);
|
||||
|
||||
bool DeallocPFetchEventOpChild(PFetchEventOpChild* aActor);
|
||||
|
||||
void ActorDestroy(ActorDestroyReason aReason) override;
|
||||
|
||||
mozilla::ipc::IPCResult RecvCreationFailed();
|
||||
|
||||
mozilla::ipc::IPCResult RecvCreationSucceeded();
|
||||
|
||||
mozilla::ipc::IPCResult RecvErrorReceived(const ErrorValue& aError);
|
||||
|
||||
mozilla::ipc::IPCResult RecvTerminated();
|
||||
|
||||
mozilla::ipc::IPCResult RecvSetServiceWorkerSkipWaitingFlag(
|
||||
SetServiceWorkerSkipWaitingFlagResolver&& aResolve);
|
||||
|
||||
RefPtr<RemoteWorkerObserver> mObserver;
|
||||
|
||||
bool mIPCActive = true;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_remoteworkercontrollerchild_h__
|
||||
|
|
@ -1,198 +0,0 @@
|
|||
/* -*- 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 "RemoteWorkerControllerParent.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsError.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/dom/FetchEventOpParent.h"
|
||||
#include "mozilla/dom/ServiceWorkerOpPromise.h"
|
||||
#include "mozilla/ipc/BackgroundParent.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
using namespace ipc;
|
||||
|
||||
namespace dom {
|
||||
|
||||
RemoteWorkerControllerParent::RemoteWorkerControllerParent(
|
||||
const RemoteWorkerData& aRemoteWorkerData)
|
||||
: mRemoteWorkerController(RemoteWorkerController::Create(
|
||||
aRemoteWorkerData, this, 0 /* random process ID */)) {
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(mRemoteWorkerController);
|
||||
}
|
||||
|
||||
RefPtr<RemoteWorkerParent> RemoteWorkerControllerParent::GetRemoteWorkerParent()
|
||||
const {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(mRemoteWorkerController);
|
||||
|
||||
return mRemoteWorkerController->mActor;
|
||||
}
|
||||
|
||||
void RemoteWorkerControllerParent::MaybeSendSetServiceWorkerSkipWaitingFlag(
|
||||
std::function<void(bool)>&& aCallback) {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aCallback);
|
||||
|
||||
if (!mIPCActive) {
|
||||
aCallback(false);
|
||||
return;
|
||||
}
|
||||
|
||||
SendSetServiceWorkerSkipWaitingFlag()->Then(
|
||||
GetCurrentThreadSerialEventTarget(), __func__,
|
||||
[callback = std::move(aCallback)](
|
||||
const SetServiceWorkerSkipWaitingFlagPromise::ResolveOrRejectValue&
|
||||
aResult) {
|
||||
callback(aResult.IsResolve() ? aResult.ResolveValue() : false);
|
||||
});
|
||||
}
|
||||
|
||||
RemoteWorkerControllerParent::~RemoteWorkerControllerParent() {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(!mIPCActive);
|
||||
MOZ_ASSERT(!mRemoteWorkerController);
|
||||
}
|
||||
|
||||
PFetchEventOpParent* RemoteWorkerControllerParent::AllocPFetchEventOpParent(
|
||||
const ServiceWorkerFetchEventOpArgs& aArgs) {
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
RefPtr<FetchEventOpParent> actor = new FetchEventOpParent();
|
||||
return actor.forget().take();
|
||||
}
|
||||
|
||||
IPCResult RemoteWorkerControllerParent::RecvPFetchEventOpConstructor(
|
||||
PFetchEventOpParent* aActor, const ServiceWorkerFetchEventOpArgs& aArgs) {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aActor);
|
||||
|
||||
(static_cast<FetchEventOpParent*>(aActor))->Initialize(aArgs);
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
bool RemoteWorkerControllerParent::DeallocPFetchEventOpParent(
|
||||
PFetchEventOpParent* aActor) {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aActor);
|
||||
|
||||
RefPtr<FetchEventOpParent> actor =
|
||||
dont_AddRef(static_cast<FetchEventOpParent*>(aActor));
|
||||
return true;
|
||||
}
|
||||
|
||||
IPCResult RemoteWorkerControllerParent::RecvExecServiceWorkerOp(
|
||||
ServiceWorkerOpArgs&& aArgs, ExecServiceWorkerOpResolver&& aResolve) {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(mIPCActive);
|
||||
MOZ_ASSERT(mRemoteWorkerController);
|
||||
|
||||
mRemoteWorkerController->ExecServiceWorkerOp(std::move(aArgs))
|
||||
->Then(GetCurrentThreadSerialEventTarget(), __func__,
|
||||
[resolve = std::move(aResolve)](
|
||||
ServiceWorkerOpPromise::ResolveOrRejectValue&& aResult) {
|
||||
if (NS_WARN_IF(aResult.IsReject())) {
|
||||
MOZ_ASSERT(NS_FAILED(aResult.RejectValue()));
|
||||
resolve(aResult.RejectValue());
|
||||
return;
|
||||
}
|
||||
|
||||
resolve(aResult.ResolveValue());
|
||||
});
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
IPCResult RemoteWorkerControllerParent::RecvShutdown(
|
||||
ShutdownResolver&& aResolve) {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(mIPCActive);
|
||||
MOZ_ASSERT(mRemoteWorkerController);
|
||||
|
||||
mIPCActive = false;
|
||||
|
||||
mRemoteWorkerController->Shutdown();
|
||||
mRemoteWorkerController = nullptr;
|
||||
|
||||
aResolve(true);
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
IPCResult RemoteWorkerControllerParent::Recv__delete__() {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(!mIPCActive);
|
||||
MOZ_ASSERT(!mRemoteWorkerController);
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void RemoteWorkerControllerParent::ActorDestroy(ActorDestroyReason aReason) {
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
if (NS_WARN_IF(mIPCActive)) {
|
||||
mIPCActive = false;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(mRemoteWorkerController)) {
|
||||
mRemoteWorkerController->Shutdown();
|
||||
mRemoteWorkerController = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteWorkerControllerParent::CreationFailed() {
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
if (!mIPCActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
Unused << SendCreationFailed();
|
||||
}
|
||||
|
||||
void RemoteWorkerControllerParent::CreationSucceeded() {
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
if (!mIPCActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
Unused << SendCreationSucceeded();
|
||||
}
|
||||
|
||||
void RemoteWorkerControllerParent::ErrorReceived(const ErrorValue& aValue) {
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
if (!mIPCActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
Unused << SendErrorReceived(aValue);
|
||||
}
|
||||
|
||||
void RemoteWorkerControllerParent::Terminated() {
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
if (!mIPCActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
Unused << SendTerminated();
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
/* -*- 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_remoteworkercontrollerparent_h__
|
||||
#define mozilla_dom_remoteworkercontrollerparent_h__
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "nsISupportsImpl.h"
|
||||
|
||||
#include "RemoteWorkerController.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/dom/PRemoteWorkerControllerParent.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class RemoteWorkerControllerParent final : public PRemoteWorkerControllerParent,
|
||||
public RemoteWorkerObserver {
|
||||
friend class PRemoteWorkerControllerParent;
|
||||
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(RemoteWorkerControllerParent, override)
|
||||
|
||||
explicit RemoteWorkerControllerParent(
|
||||
const RemoteWorkerData& aRemoteWorkerData);
|
||||
|
||||
// Returns the corresponding RemoteWorkerParent (if any).
|
||||
RefPtr<RemoteWorkerParent> GetRemoteWorkerParent() const;
|
||||
|
||||
void MaybeSendSetServiceWorkerSkipWaitingFlag(
|
||||
std::function<void(bool)>&& aCallback);
|
||||
|
||||
private:
|
||||
~RemoteWorkerControllerParent();
|
||||
|
||||
PFetchEventOpParent* AllocPFetchEventOpParent(
|
||||
const ServiceWorkerFetchEventOpArgs& aArgs);
|
||||
|
||||
mozilla::ipc::IPCResult RecvPFetchEventOpConstructor(
|
||||
PFetchEventOpParent* aActor,
|
||||
const ServiceWorkerFetchEventOpArgs& aArgs) override;
|
||||
|
||||
bool DeallocPFetchEventOpParent(PFetchEventOpParent* aActor);
|
||||
|
||||
mozilla::ipc::IPCResult RecvExecServiceWorkerOp(
|
||||
ServiceWorkerOpArgs&& aArgs, ExecServiceWorkerOpResolver&& aResolve);
|
||||
|
||||
mozilla::ipc::IPCResult RecvShutdown(ShutdownResolver&& aResolve);
|
||||
|
||||
mozilla::ipc::IPCResult Recv__delete__() override;
|
||||
|
||||
void ActorDestroy(ActorDestroyReason aReason) override;
|
||||
|
||||
void CreationFailed() override;
|
||||
|
||||
void CreationSucceeded() override;
|
||||
|
||||
void ErrorReceived(const ErrorValue& aValue) override;
|
||||
|
||||
void Terminated() override;
|
||||
|
||||
RefPtr<RemoteWorkerController> mRemoteWorkerController;
|
||||
|
||||
bool mIPCActive = true;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_remoteworkercontrollerparent_h__
|
||||
|
|
@ -6,19 +6,11 @@
|
|||
|
||||
#include "RemoteWorkerManager.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
#include "mozilla/SystemGroup.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/RemoteWorkerParent.h"
|
||||
#include "mozilla/ipc/BackgroundParent.h"
|
||||
#include "mozilla/ipc/PBackgroundParent.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIXULRuntime.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "RemoteWorkerServiceParent.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
|
@ -33,17 +25,12 @@ namespace {
|
|||
// actors.
|
||||
RemoteWorkerManager* sRemoteWorkerManager;
|
||||
|
||||
bool IsServiceWorker(const RemoteWorkerData& aData) {
|
||||
return aData.serviceWorkerData().type() ==
|
||||
OptionalServiceWorkerData::TServiceWorkerData;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
/* static */
|
||||
already_AddRefed<RemoteWorkerManager> RemoteWorkerManager::GetOrCreate() {
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
if (!sRemoteWorkerManager) {
|
||||
sRemoteWorkerManager = new RemoteWorkerManager();
|
||||
|
|
@ -54,21 +41,21 @@ already_AddRefed<RemoteWorkerManager> RemoteWorkerManager::GetOrCreate() {
|
|||
}
|
||||
|
||||
RemoteWorkerManager::RemoteWorkerManager() : mParentActor(nullptr) {
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(!sRemoteWorkerManager);
|
||||
}
|
||||
|
||||
RemoteWorkerManager::~RemoteWorkerManager() {
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(sRemoteWorkerManager == this);
|
||||
sRemoteWorkerManager = nullptr;
|
||||
}
|
||||
|
||||
void RemoteWorkerManager::RegisterActor(RemoteWorkerServiceParent* aActor) {
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(aActor);
|
||||
|
||||
if (!BackgroundParent::IsOtherProcessActor(aActor->Manager())) {
|
||||
|
|
@ -96,8 +83,8 @@ void RemoteWorkerManager::RegisterActor(RemoteWorkerServiceParent* aActor) {
|
|||
}
|
||||
|
||||
void RemoteWorkerManager::UnregisterActor(RemoteWorkerServiceParent* aActor) {
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(aActor);
|
||||
|
||||
if (aActor == mParentActor) {
|
||||
|
|
@ -111,8 +98,8 @@ void RemoteWorkerManager::UnregisterActor(RemoteWorkerServiceParent* aActor) {
|
|||
void RemoteWorkerManager::Launch(RemoteWorkerController* aController,
|
||||
const RemoteWorkerData& aData,
|
||||
base::ProcessId aProcessId) {
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
RemoteWorkerServiceParent* targetActor = SelectTargetActor(aData, aProcessId);
|
||||
|
||||
|
|
@ -133,20 +120,14 @@ void RemoteWorkerManager::Launch(RemoteWorkerController* aController,
|
|||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a target actor for a Service Worker has been selected, the actor has
|
||||
* already been registered with the corresponding ContentParent (see
|
||||
* `SelectTargetActorForServiceWorker()`).
|
||||
*/
|
||||
LaunchInternal(aController, targetActor, aData, IsServiceWorker(aData));
|
||||
LaunchInternal(aController, targetActor, aData);
|
||||
}
|
||||
|
||||
void RemoteWorkerManager::LaunchInternal(
|
||||
RemoteWorkerController* aController,
|
||||
RemoteWorkerServiceParent* aTargetActor, const RemoteWorkerData& aData,
|
||||
bool aRemoteWorkerAlreadyRegistered) {
|
||||
AssertIsInMainProcess();
|
||||
RemoteWorkerServiceParent* aTargetActor, const RemoteWorkerData& aData) {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(aController);
|
||||
MOZ_ASSERT(aTargetActor);
|
||||
MOZ_ASSERT(aTargetActor == mParentActor ||
|
||||
|
|
@ -159,7 +140,7 @@ void RemoteWorkerManager::LaunchInternal(
|
|||
return;
|
||||
}
|
||||
|
||||
workerActor->Initialize(aRemoteWorkerAlreadyRegistered);
|
||||
workerActor->Initialize();
|
||||
|
||||
// This makes the link better the 2 actors.
|
||||
aController->SetWorkerActor(workerActor);
|
||||
|
|
@ -176,75 +157,10 @@ void RemoteWorkerManager::AsyncCreationFailed(
|
|||
NS_DispatchToCurrentThread(r.forget());
|
||||
}
|
||||
|
||||
/**
|
||||
* Service Workers can spawn even when their registering page/script isn't
|
||||
* active (e.g. push notifications), so we don't attempt to spawn the worker
|
||||
* in its registering script's process. We search linearly and choose the
|
||||
* search's starting position randomly.
|
||||
*
|
||||
* Spawning the workers in a random process makes the process selection criteria
|
||||
* a little tricky, as a candidate process may imminently shutdown due to a
|
||||
* remove worker actor unregistering
|
||||
* (see `ContentParent::UnregisterRemoveWorkerActor`).
|
||||
*
|
||||
* In `ContentParent::MaybeAsyncSendShutDownMessage` we only dispatch a runnable
|
||||
* to call `ContentParent::ShutDownProcess` if there are no registered remote
|
||||
* worker actors, and we ensure that the check for the number of registered
|
||||
* actors and the dispatching of the runnable are atomic. That happens on the
|
||||
* main thread, so here on the background thread, while
|
||||
* `ContentParent::mRemoteWorkerActorData` is locked, if `mCount` > 0, we can
|
||||
* register a remote worker actor "early" and guarantee that the corresponding
|
||||
* content process will not shutdown.
|
||||
*/
|
||||
RemoteWorkerServiceParent*
|
||||
RemoteWorkerManager::SelectTargetActorForServiceWorker() const {
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(!mChildActors.IsEmpty());
|
||||
|
||||
nsTArray<RefPtr<ContentParent>> contentParents;
|
||||
|
||||
auto scopeExit = MakeScopeExit([&] {
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
|
||||
__func__,
|
||||
[doomed = std::move(contentParents)]() mutable { doomed.Clear(); });
|
||||
|
||||
SystemGroup::Dispatch(TaskCategory::Other, r.forget());
|
||||
});
|
||||
|
||||
uint32_t random = uint32_t(rand() % mChildActors.Length());
|
||||
uint32_t i = random;
|
||||
|
||||
do {
|
||||
auto actor = mChildActors[i];
|
||||
PBackgroundParent* bgParent = actor->Manager();
|
||||
MOZ_ASSERT(bgParent);
|
||||
|
||||
RefPtr<ContentParent> contentParent =
|
||||
BackgroundParent::GetContentParent(bgParent);
|
||||
|
||||
auto scopeExit = MakeScopeExit(
|
||||
[&] { contentParents.AppendElement(std::move(contentParent)); });
|
||||
|
||||
if (contentParent->GetRemoteType().EqualsLiteral(DEFAULT_REMOTE_TYPE)) {
|
||||
auto lock = contentParent->mRemoteWorkerActorData.Lock();
|
||||
|
||||
if (lock->mCount || !lock->mShutdownStarted) {
|
||||
++lock->mCount;
|
||||
return actor;
|
||||
}
|
||||
}
|
||||
|
||||
i = (++i % mChildActors.Length());
|
||||
} while (i != random);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RemoteWorkerServiceParent* RemoteWorkerManager::SelectTargetActor(
|
||||
const RemoteWorkerData& aData, base::ProcessId aProcessId) {
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
// System principal workers should run on the parent process.
|
||||
if (aData.principalInfo().type() == PrincipalInfo::TSystemPrincipalInfo) {
|
||||
|
|
@ -265,10 +181,6 @@ RemoteWorkerServiceParent* RemoteWorkerManager::SelectTargetActor(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (IsServiceWorker(aData)) {
|
||||
return SelectTargetActorForServiceWorker();
|
||||
}
|
||||
|
||||
for (RemoteWorkerServiceParent* actor : mChildActors) {
|
||||
// Let's execute the RemoteWorker on the same process.
|
||||
if (actor->OtherPid() == aProcessId) {
|
||||
|
|
@ -282,8 +194,8 @@ RemoteWorkerServiceParent* RemoteWorkerManager::SelectTargetActor(
|
|||
}
|
||||
|
||||
void RemoteWorkerManager::LaunchNewContentProcess() {
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
// This runnable will spawn a new process if it doesn't exist yet.
|
||||
nsCOMPtr<nsIRunnable> r =
|
||||
|
|
|
|||
|
|
@ -39,12 +39,9 @@ class RemoteWorkerManager final {
|
|||
RemoteWorkerServiceParent* SelectTargetActor(const RemoteWorkerData& aData,
|
||||
base::ProcessId aProcessId);
|
||||
|
||||
RemoteWorkerServiceParent* SelectTargetActorForServiceWorker() const;
|
||||
|
||||
void LaunchInternal(RemoteWorkerController* aController,
|
||||
RemoteWorkerServiceParent* aTargetActor,
|
||||
const RemoteWorkerData& aData,
|
||||
bool aRemoteWorkerAlreadyRegistered = false);
|
||||
const RemoteWorkerData& aData);
|
||||
|
||||
void LaunchNewContentProcess();
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
#include "RemoteWorkerParent.h"
|
||||
#include "RemoteWorkerController.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/PFetchEventOpProxyParent.h"
|
||||
#include "mozilla/ipc/BackgroundParent.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsProxyRelease.h"
|
||||
|
|
@ -53,14 +52,12 @@ RemoteWorkerParent::~RemoteWorkerParent() {
|
|||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
}
|
||||
|
||||
void RemoteWorkerParent::Initialize(bool aAlreadyRegistered) {
|
||||
void RemoteWorkerParent::Initialize() {
|
||||
RefPtr<ContentParent> parent = BackgroundParent::GetContentParent(Manager());
|
||||
|
||||
// Parent is null if the child actor runs on the parent process.
|
||||
if (parent) {
|
||||
if (!aAlreadyRegistered) {
|
||||
parent->RegisterRemoteWorkerActor();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target =
|
||||
SystemGroup::EventTargetFor(TaskCategory::Other);
|
||||
|
|
@ -70,22 +67,6 @@ void RemoteWorkerParent::Initialize(bool aAlreadyRegistered) {
|
|||
}
|
||||
}
|
||||
|
||||
PFetchEventOpProxyParent* RemoteWorkerParent::AllocPFetchEventOpProxyParent(
|
||||
const ServiceWorkerFetchEventOpArgs& aArgs) {
|
||||
MOZ_CRASH("PFetchEventOpProxyParent actors must be manually constructed!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool RemoteWorkerParent::DeallocPFetchEventOpProxyParent(
|
||||
PFetchEventOpProxyParent* aActor) {
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aActor);
|
||||
|
||||
delete aActor;
|
||||
return true;
|
||||
}
|
||||
|
||||
void RemoteWorkerParent::ActorDestroy(IProtocol::ActorDestroyReason) {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
|
@ -103,7 +84,7 @@ void RemoteWorkerParent::ActorDestroy(IProtocol::ActorDestroyReason) {
|
|||
}
|
||||
|
||||
if (mController) {
|
||||
mController->NoteDeadWorkerActor();
|
||||
mController->ForgetActorAndTerminate();
|
||||
mController = nullptr;
|
||||
}
|
||||
}
|
||||
|
|
@ -136,17 +117,6 @@ IPCResult RemoteWorkerParent::RecvError(const ErrorValue& aValue) {
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
void RemoteWorkerParent::MaybeSendDelete() {
|
||||
if (mDeleteSent) {
|
||||
return;
|
||||
}
|
||||
|
||||
// For some reason, if the following two lines are swapped, ASan says there's
|
||||
// a UAF...
|
||||
mDeleteSent = true;
|
||||
Unused << Send__delete__(this);
|
||||
}
|
||||
|
||||
IPCResult RemoteWorkerParent::RecvClose() {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
|
@ -155,8 +125,7 @@ IPCResult RemoteWorkerParent::RecvClose() {
|
|||
mController->WorkerTerminated();
|
||||
}
|
||||
|
||||
MaybeSendDelete();
|
||||
|
||||
Unused << Send__delete__(this);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
|
@ -167,22 +136,5 @@ void RemoteWorkerParent::SetController(RemoteWorkerController* aController) {
|
|||
mController = aController;
|
||||
}
|
||||
|
||||
IPCResult RemoteWorkerParent::RecvSetServiceWorkerSkipWaitingFlag(
|
||||
SetServiceWorkerSkipWaitingFlagResolver&& aResolve) {
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
if (mController) {
|
||||
mController->SetServiceWorkerSkipWaitingFlag()->Then(
|
||||
GetCurrentThreadSerialEventTarget(), __func__,
|
||||
[resolve = aResolve](bool /* unused */) { resolve(true); },
|
||||
[resolve = aResolve](nsresult /* unused */) { resolve(false); });
|
||||
} else {
|
||||
aResolve(false);
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
|||
|
|
@ -22,20 +22,13 @@ class RemoteWorkerParent final : public PRemoteWorkerParent {
|
|||
|
||||
RemoteWorkerParent();
|
||||
|
||||
void Initialize(bool aAlreadyRegistered = false);
|
||||
void Initialize();
|
||||
|
||||
void SetController(RemoteWorkerController* aController);
|
||||
|
||||
void MaybeSendDelete();
|
||||
|
||||
private:
|
||||
~RemoteWorkerParent();
|
||||
|
||||
PFetchEventOpProxyParent* AllocPFetchEventOpProxyParent(
|
||||
const ServiceWorkerFetchEventOpArgs& aArgs);
|
||||
|
||||
bool DeallocPFetchEventOpProxyParent(PFetchEventOpProxyParent* aActor);
|
||||
|
||||
void ActorDestroy(mozilla::ipc::IProtocol::ActorDestroyReason) override;
|
||||
|
||||
mozilla::ipc::IPCResult RecvError(const ErrorValue& aValue);
|
||||
|
|
@ -44,10 +37,6 @@ class RemoteWorkerParent final : public PRemoteWorkerParent {
|
|||
|
||||
mozilla::ipc::IPCResult RecvCreated(const bool& aStatus);
|
||||
|
||||
mozilla::ipc::IPCResult RecvSetServiceWorkerSkipWaitingFlag(
|
||||
SetServiceWorkerSkipWaitingFlagResolver&& aResolve);
|
||||
|
||||
bool mDeleteSent = false;
|
||||
RefPtr<RemoteWorkerController> mController;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3,37 +3,16 @@
|
|||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include ClientIPCTypes;
|
||||
include IPCServiceWorkerDescriptor;
|
||||
include IPCServiceWorkerRegistrationDescriptor;
|
||||
include PBackgroundSharedTypes;
|
||||
include URIParams;
|
||||
include DOMTypes;
|
||||
|
||||
using struct IPC::Permission from "mozilla/net/NeckoMessageUtils.h";
|
||||
using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
|
||||
using mozilla::StorageAccess from "mozilla/dom/ClientIPCUtils.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
struct KeyAndPermissions {
|
||||
nsCString key;
|
||||
Permission[] permissions;
|
||||
};
|
||||
|
||||
struct ServiceWorkerData {
|
||||
KeyAndPermissions[] permissionsByKey;
|
||||
IPCServiceWorkerDescriptor descriptor;
|
||||
IPCServiceWorkerRegistrationDescriptor registrationDescriptor;
|
||||
nsString cacheName;
|
||||
uint32_t loadFlags;
|
||||
};
|
||||
|
||||
union OptionalServiceWorkerData {
|
||||
void_t;
|
||||
ServiceWorkerData;
|
||||
};
|
||||
|
||||
struct RemoteWorkerData
|
||||
{
|
||||
// This should only be used for devtools.
|
||||
|
|
@ -66,7 +45,7 @@ struct RemoteWorkerData
|
|||
|
||||
StorageAccess storageAccess;
|
||||
|
||||
OptionalServiceWorkerData serviceWorkerData;
|
||||
bool isSharedWorker;
|
||||
};
|
||||
|
||||
// ErrorData/ErrorDataNote correspond to WorkerErrorReport/WorkerErrorNote
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@
|
|||
EXPORTS.mozilla.dom += [
|
||||
'RemoteWorkerChild.h',
|
||||
'RemoteWorkerController.h',
|
||||
'RemoteWorkerControllerChild.h',
|
||||
'RemoteWorkerControllerParent.h',
|
||||
'RemoteWorkerParent.h',
|
||||
'RemoteWorkerService.h',
|
||||
'RemoteWorkerServiceChild.h',
|
||||
|
|
@ -18,8 +16,6 @@ EXPORTS.mozilla.dom += [
|
|||
UNIFIED_SOURCES += [
|
||||
'RemoteWorkerChild.cpp',
|
||||
'RemoteWorkerController.cpp',
|
||||
'RemoteWorkerControllerChild.cpp',
|
||||
'RemoteWorkerControllerParent.cpp',
|
||||
'RemoteWorkerManager.cpp',
|
||||
'RemoteWorkerParent.cpp',
|
||||
'RemoteWorkerService.cpp',
|
||||
|
|
@ -28,13 +24,11 @@ UNIFIED_SOURCES += [
|
|||
]
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'/dom/serviceworkers',
|
||||
'/xpcom/build',
|
||||
]
|
||||
|
||||
IPDL_SOURCES += [
|
||||
'PRemoteWorker.ipdl',
|
||||
'PRemoteWorkerController.ipdl',
|
||||
'PRemoteWorkerService.ipdl',
|
||||
'RemoteWorkerTypes.ipdlh',
|
||||
]
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ already_AddRefed<SharedWorker> SharedWorker::Constructor(
|
|||
nsString(aScriptURL), baseURL, resolvedScriptURL, name,
|
||||
loadingPrincipalInfo, principalInfo, storagePrincipalInfo,
|
||||
loadInfo.mDomain, isSecureContext, ipcClientInfo, loadInfo.mReferrerInfo,
|
||||
storageAllowed, void_t() /* OptionalServiceWorkerData */);
|
||||
storageAllowed, true /* sharedWorker */);
|
||||
|
||||
PSharedWorkerChild* pActor = actorChild->SendPSharedWorkerConstructor(
|
||||
remoteWorkerData, loadInfo.mWindowID, portIdentifier);
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@
|
|||
#include "mozilla/dom/IPCBlobUtils.h"
|
||||
#include "mozilla/dom/quota/PQuotaChild.h"
|
||||
#include "mozilla/dom/RemoteWorkerChild.h"
|
||||
#include "mozilla/dom/RemoteWorkerControllerChild.h"
|
||||
#include "mozilla/dom/RemoteWorkerServiceChild.h"
|
||||
#include "mozilla/dom/SharedWorkerChild.h"
|
||||
#include "mozilla/dom/StorageIPC.h"
|
||||
|
|
@ -325,7 +324,7 @@ bool BackgroundChildImpl::DeallocPPendingIPCBlobChild(
|
|||
|
||||
dom::PRemoteWorkerChild* BackgroundChildImpl::AllocPRemoteWorkerChild(
|
||||
const RemoteWorkerData& aData) {
|
||||
RefPtr<dom::RemoteWorkerChild> agent = new dom::RemoteWorkerChild(aData);
|
||||
RefPtr<dom::RemoteWorkerChild> agent = new dom::RemoteWorkerChild();
|
||||
return agent.forget().take();
|
||||
}
|
||||
|
||||
|
|
@ -343,23 +342,6 @@ bool BackgroundChildImpl::DeallocPRemoteWorkerChild(
|
|||
return true;
|
||||
}
|
||||
|
||||
dom::PRemoteWorkerControllerChild*
|
||||
BackgroundChildImpl::AllocPRemoteWorkerControllerChild(
|
||||
const dom::RemoteWorkerData& aRemoteWorkerData) {
|
||||
MOZ_CRASH(
|
||||
"PRemoteWorkerControllerChild actors must be manually constructed!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool BackgroundChildImpl::DeallocPRemoteWorkerControllerChild(
|
||||
dom::PRemoteWorkerControllerChild* aActor) {
|
||||
MOZ_ASSERT(aActor);
|
||||
|
||||
RefPtr<dom::RemoteWorkerControllerChild> actor =
|
||||
dont_AddRef(static_cast<dom::RemoteWorkerControllerChild*>(aActor));
|
||||
return true;
|
||||
}
|
||||
|
||||
dom::PRemoteWorkerServiceChild*
|
||||
BackgroundChildImpl::AllocPRemoteWorkerServiceChild() {
|
||||
RefPtr<dom::RemoteWorkerServiceChild> agent =
|
||||
|
|
|
|||
|
|
@ -141,13 +141,6 @@ class BackgroundChildImpl : public PBackgroundChild {
|
|||
virtual bool DeallocPRemoteWorkerChild(
|
||||
mozilla::dom::PRemoteWorkerChild* aActor) override;
|
||||
|
||||
virtual mozilla::dom::PRemoteWorkerControllerChild*
|
||||
AllocPRemoteWorkerControllerChild(
|
||||
const mozilla::dom::RemoteWorkerData& aRemoteWorkerData) override;
|
||||
|
||||
virtual bool DeallocPRemoteWorkerControllerChild(
|
||||
mozilla::dom::PRemoteWorkerControllerChild* aActor) override;
|
||||
|
||||
virtual mozilla::dom::PRemoteWorkerServiceChild*
|
||||
AllocPRemoteWorkerServiceChild() override;
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@
|
|||
#include "mozilla/dom/quota/ActorsParent.h"
|
||||
#include "mozilla/dom/simpledb/ActorsParent.h"
|
||||
#include "mozilla/dom/RemoteWorkerParent.h"
|
||||
#include "mozilla/dom/RemoteWorkerControllerParent.h"
|
||||
#include "mozilla/dom/RemoteWorkerServiceParent.h"
|
||||
#include "mozilla/dom/ReportingHeader.h"
|
||||
#include "mozilla/dom/SharedWorkerParent.h"
|
||||
|
|
@ -498,29 +497,6 @@ bool BackgroundParentImpl::DeallocPRemoteWorkerParent(
|
|||
return true;
|
||||
}
|
||||
|
||||
dom::PRemoteWorkerControllerParent*
|
||||
BackgroundParentImpl::AllocPRemoteWorkerControllerParent(
|
||||
const dom::RemoteWorkerData& aRemoteWorkerData) {
|
||||
RefPtr<dom::RemoteWorkerControllerParent> actor =
|
||||
new dom::RemoteWorkerControllerParent(aRemoteWorkerData);
|
||||
return actor.forget().take();
|
||||
}
|
||||
|
||||
IPCResult BackgroundParentImpl::RecvPRemoteWorkerControllerConstructor(
|
||||
dom::PRemoteWorkerControllerParent* aActor,
|
||||
const dom::RemoteWorkerData& aRemoteWorkerData) {
|
||||
MOZ_ASSERT(aActor);
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
bool BackgroundParentImpl::DeallocPRemoteWorkerControllerParent(
|
||||
dom::PRemoteWorkerControllerParent* aActor) {
|
||||
RefPtr<dom::RemoteWorkerControllerParent> actor =
|
||||
dont_AddRef(static_cast<dom::RemoteWorkerControllerParent*>(aActor));
|
||||
return true;
|
||||
}
|
||||
|
||||
mozilla::dom::PRemoteWorkerServiceParent*
|
||||
BackgroundParentImpl::AllocPRemoteWorkerServiceParent() {
|
||||
return new mozilla::dom::RemoteWorkerServiceParent();
|
||||
|
|
|
|||
|
|
@ -171,17 +171,6 @@ class BackgroundParentImpl : public PBackgroundParent {
|
|||
|
||||
virtual bool DeallocPRemoteWorkerParent(PRemoteWorkerParent* aActor) override;
|
||||
|
||||
virtual mozilla::dom::PRemoteWorkerControllerParent*
|
||||
AllocPRemoteWorkerControllerParent(
|
||||
const mozilla::dom::RemoteWorkerData& aRemoteWorkerData) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvPRemoteWorkerControllerConstructor(
|
||||
mozilla::dom::PRemoteWorkerControllerParent* aActor,
|
||||
const mozilla::dom::RemoteWorkerData& aRemoteWorkerData) override;
|
||||
|
||||
virtual bool DeallocPRemoteWorkerControllerParent(
|
||||
mozilla::dom::PRemoteWorkerControllerParent* aActor) override;
|
||||
|
||||
virtual mozilla::dom::PRemoteWorkerServiceParent*
|
||||
AllocPRemoteWorkerServiceParent() override;
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
#include "IPCStreamSource.h"
|
||||
#include "BackgroundParent.h" // for AssertIsOnBackgroundThread
|
||||
#include "mozilla/dom/RemoteWorkerService.h"
|
||||
#include "mozilla/webrender/WebRenderTypes.h"
|
||||
#include "nsIAsyncInputStream.h"
|
||||
#include "nsICancelableRunnable.h"
|
||||
|
|
@ -114,12 +113,11 @@ bool IPCStreamSource::Initialize() {
|
|||
}
|
||||
|
||||
// A source can be used on any thread, but we only support IPCStream on
|
||||
// main thread, Workers, Worker Launcher, and PBackground thread right now.
|
||||
// This is due to the requirement that the thread be guaranteed to live long
|
||||
// enough to receive messages. We can enforce this guarantee with a
|
||||
// StrongWorkerRef on worker threads, but not other threads. Main-thread,
|
||||
// PBackground, and Worker Launcher threads do not need anything special in
|
||||
// order to be kept alive.
|
||||
// main thread, Workers and PBackground thread right now. This is due
|
||||
// to the requirement that the thread be guaranteed to live long enough to
|
||||
// receive messages. We can enforce this guarantee with a StrongWorkerRef on
|
||||
// worker threads, but not other threads. Main-thread and PBackground thread
|
||||
// do not need anything special in order to be kept alive.
|
||||
if (!NS_IsMainThread()) {
|
||||
if (const auto workerPrivate = dom::GetCurrentThreadWorkerPrivate()) {
|
||||
RefPtr<dom::StrongWorkerRef> workerRef =
|
||||
|
|
@ -131,9 +129,7 @@ bool IPCStreamSource::Initialize() {
|
|||
|
||||
mWorkerRef = std::move(workerRef);
|
||||
} else {
|
||||
MOZ_DIAGNOSTIC_ASSERT(
|
||||
IsOnBackgroundThread() ||
|
||||
dom::RemoteWorkerService::Thread()->IsOnCurrentThread());
|
||||
AssertIsOnBackgroundThread();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -243,13 +239,6 @@ void IPCStreamSource::OnStreamReady(Callback* aCallback) {
|
|||
MOZ_ASSERT(aCallback == mCallback);
|
||||
mCallback->ClearSource();
|
||||
mCallback = nullptr;
|
||||
|
||||
// Possibly closed if this callback is (indirectly) called by
|
||||
// IPCStreamSourceParent::RecvRequestClose().
|
||||
if (mState == eClosed) {
|
||||
return;
|
||||
}
|
||||
|
||||
DoRead();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ include protocol PIPCBlobInputStream;
|
|||
include protocol PMediaTransport;
|
||||
include protocol PPendingIPCBlob;
|
||||
include protocol PRemoteWorker;
|
||||
include protocol PRemoteWorkerController;
|
||||
include protocol PRemoteWorkerService;
|
||||
include protocol PSharedWorker;
|
||||
include protocol PTemporaryIPCBlob;
|
||||
|
|
@ -95,7 +94,6 @@ sync protocol PBackground
|
|||
manages PMediaTransport;
|
||||
manages PPendingIPCBlob;
|
||||
manages PRemoteWorker;
|
||||
manages PRemoteWorkerController;
|
||||
manages PRemoteWorkerService;
|
||||
manages PSharedWorker;
|
||||
manages PTemporaryIPCBlob;
|
||||
|
|
@ -218,8 +216,6 @@ parent:
|
|||
|
||||
async PServiceWorker(IPCServiceWorkerDescriptor aDescriptor);
|
||||
|
||||
async PRemoteWorkerController(RemoteWorkerData aData);
|
||||
|
||||
async PRemoteWorkerService();
|
||||
|
||||
async PServiceWorkerContainer();
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
#include "nsStreamUtils.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsIClassInfoImpl.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
#include <algorithm>
|
||||
|
||||
|
|
@ -39,7 +38,6 @@ static struct {
|
|||
#endif
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
using mozilla::DebugOnly;
|
||||
using mozilla::Maybe;
|
||||
using mozilla::MutexAutoLock;
|
||||
using mozilla::Nothing;
|
||||
|
|
@ -278,16 +276,7 @@ NS_IMPL_CLASSINFO(nsBufferedInputStream, nullptr, nsIClassInfo::THREADSAFE,
|
|||
NS_BUFFEREDINPUTSTREAM_CID)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsBufferedInputStream)
|
||||
// Unfortunately there isn't a macro that combines ambiguous and conditional,
|
||||
// and as far as I can tell, no other class would need such a macro.
|
||||
if (mIsAsyncInputStream && aIID.Equals(NS_GET_IID(nsIInputStream))) {
|
||||
foundInterface =
|
||||
static_cast<nsIInputStream*>(static_cast<nsIAsyncInputStream*>(this));
|
||||
} else if (!mIsAsyncInputStream && aIID.Equals(NS_GET_IID(nsIInputStream))) {
|
||||
foundInterface = static_cast<nsIInputStream*>(
|
||||
static_cast<nsIBufferedInputStream*>(this));
|
||||
} else
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIBufferedInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIInputStream, nsIBufferedInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIBufferedInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIStreamBufferAccess)
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIIPCSerializableInputStream,
|
||||
|
|
@ -359,19 +348,6 @@ nsBufferedInputStream::Init(nsIInputStream* stream, uint32_t bufferSize) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIInputStream> nsBufferedInputStream::GetInputStream() {
|
||||
// A non-null mStream implies Init() has been called.
|
||||
MOZ_ASSERT(mStream);
|
||||
|
||||
nsIInputStream* out = nullptr;
|
||||
DebugOnly<nsresult> rv = QueryInterface(NS_GET_IID(nsIInputStream),
|
||||
reinterpret_cast<void**>(&out));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
MOZ_ASSERT(out);
|
||||
|
||||
return already_AddRefed<nsIInputStream>(out);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBufferedInputStream::Close() {
|
||||
nsresult rv1 = NS_OK, rv2;
|
||||
|
|
@ -788,9 +764,7 @@ nsBufferedInputStream::Clone(nsIInputStream** aResult) {
|
|||
rv = bis->Init(clonedStream, mBufferSize);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*aResult =
|
||||
static_cast<nsBufferedInputStream*>(bis.get())->GetInputStream().take();
|
||||
|
||||
bis.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -92,22 +92,6 @@ class nsBufferedInputStream final : public nsBufferedStream,
|
|||
|
||||
nsIInputStream* Source() { return (nsIInputStream*)mStream.get(); }
|
||||
|
||||
/**
|
||||
* If there's a reference/pointer to an nsBufferedInputStream BEFORE calling
|
||||
* Init() AND the intent is to ultimately convert/assign that
|
||||
* reference/pointer to an nsIInputStream, DO NOT use that initial
|
||||
* reference/pointer. Instead, use the value of QueryInterface-ing to an
|
||||
* nsIInputStream (and, again, the QueryInterface must be performed after
|
||||
* Init()). This is because nsBufferedInputStream has multiple underlying
|
||||
* nsIInputStreams (one from nsIBufferedInputStream and one from
|
||||
* nsIAsyncInputStream), and the correct base nsIInputStream to use will be
|
||||
* unknown until the final value of mIsAsyncInputStream is set in Init().
|
||||
*
|
||||
* This method, however, does just that but also hides the QI details and
|
||||
* will assert if called before Init().
|
||||
*/
|
||||
already_AddRefed<nsIInputStream> GetInputStream();
|
||||
|
||||
protected:
|
||||
virtual ~nsBufferedInputStream() = default;
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
#include "nsIAuthPrompt2.h"
|
||||
#include "nsIAuthPromptAdapterFactory.h"
|
||||
#include "nsIBufferedStreams.h"
|
||||
#include "nsBufferedStreams.h"
|
||||
#include "nsIChannelEventSink.h"
|
||||
#include "nsIContentSniffer.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
|
|
@ -1270,9 +1269,7 @@ MOZ_MUST_USE nsresult NS_NewBufferedInputStream(
|
|||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = in->Init(inputStream, aBufferSize);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
*aResult = static_cast<nsBufferedInputStream*>(in.get())
|
||||
->GetInputStream()
|
||||
.take();
|
||||
in.forget(aResult);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
|
|
|
|||
|
|
@ -37,12 +37,6 @@ struct Permission {
|
|||
capability(aCapability),
|
||||
expireType(aExpireType),
|
||||
expireTime(aExpireTime) {}
|
||||
|
||||
bool operator==(const Permission& aOther) const {
|
||||
return aOther.origin == origin && aOther.type == type &&
|
||||
aOther.capability == capability && aOther.expireType == expireType &&
|
||||
aOther.expireTime == expireTime;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
|
|
|
|||
|
|
@ -1 +1,8 @@
|
|||
[multiple-update.https.html]
|
||||
disabled:
|
||||
if sw-e10s: https://bugzilla.mozilla.org/show_bug.cgi?id=1543316
|
||||
|
||||
[Trigger multiple updates.]
|
||||
expected:
|
||||
if sw-e10s: TIMEOUT
|
||||
|
||||
|
|
|
|||
|
|
@ -3,3 +3,11 @@
|
|||
if (os == "android") and not e10s: https://bugzilla.mozilla.org/show_bug.cgi?id=1499972
|
||||
if (os == "android") and e10s: bug 1550895 (frequently fails on geckoview)
|
||||
expected: ERROR
|
||||
[ServiceWorkerRegistration.update() from active service worker succeeds while installing service worker.]
|
||||
expected:
|
||||
if sw-e10s: TIMEOUT
|
||||
FAIL
|
||||
|
||||
[ServiceWorkerRegistration.update() from client succeeds while installing service worker.]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
|||
|
|
@ -14,9 +14,6 @@ addEventListener('install', event => {
|
|||
});
|
||||
|
||||
addEventListener('message', event => {
|
||||
let resolveWaitUntil;
|
||||
event.waitUntil(new Promise(resolve => { resolveWaitUntil = resolve; }));
|
||||
|
||||
// Use a dedicated MessageChannel for every request so senders can wait for
|
||||
// individual requests to finish, and concurrent requests (to different
|
||||
// workers) don't cause race conditions.
|
||||
|
|
@ -26,13 +23,13 @@ addEventListener('message', event => {
|
|||
case 'awaitInstallEvent':
|
||||
installEventFired.then(() => {
|
||||
port.postMessage('installEventFired');
|
||||
}).finally(resolveWaitUntil);
|
||||
});
|
||||
break;
|
||||
|
||||
case 'finishInstall':
|
||||
installFinished.then(() => {
|
||||
port.postMessage('installFinished');
|
||||
}).finally(resolveWaitUntil);
|
||||
});
|
||||
finishInstall();
|
||||
break;
|
||||
|
||||
|
|
@ -47,14 +44,13 @@ addEventListener('message', event => {
|
|||
success: false,
|
||||
exception: exception.name,
|
||||
});
|
||||
}).finally(resolveWaitUntil);
|
||||
});
|
||||
port.postMessage(channel.port1, [channel.port1]);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
port.postMessage('Unexpected command ' + event.data);
|
||||
resolveWaitUntil();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue