Bug 1562663 - P3 - Have agent cluster Ids for workers; r=perry,nika

Dedicated workers should be in the same  agent cluster with its parent/creator.
The other workers (ShareWorker/ServiceWorker/ChromeWorker) create another agent
cluster when they are created from the creator.

Differential Revision: https://phabricator.services.mozilla.com/D43241

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Tom Tung 2019-09-23 09:57:23 +00:00
parent 752128922c
commit 699c7a419a
12 changed files with 76 additions and 4 deletions

View File

@ -6908,6 +6908,16 @@ nsresult nsContentUtils::GenerateUUIDInPlace(nsID& aUUID) {
return NS_OK;
}
nsID nsContentUtils::GenerateUUID() {
MOZ_DIAGNOSTIC_ASSERT(sUUIDGenerator);
nsID uuid;
nsresult rv = sUUIDGenerator->GenerateUUIDInPlace(&uuid);
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
return uuid;
}
bool nsContentUtils::PrefetchPreloadEnabled(nsIDocShell* aDocShell) {
//
// SECURITY CHECK: disable prefetching and preloading from mailnews!

View File

@ -1152,6 +1152,11 @@ class nsContentUtils {
*/
static nsresult GenerateUUIDInPlace(nsID& aUUID);
/**
* Infallable (with an assertion) helper function that generates a UUID.
*/
static nsID GenerateUUID();
static bool PrefetchPreloadEnabled(nsIDocShell* aDocShell);
static void ExtractErrorValues(JSContext* aCx, JS::Handle<JS::Value> aValue,

View File

@ -1746,6 +1746,8 @@ nsresult ServiceWorkerPrivate::SpawnWorkerIfNeeded(WakeUpReason aWhy,
return rv;
}
info.mAgentClusterId = reg->AgentClusterId();
AutoJSAPI jsapi;
jsapi.Init();
ErrorResult error;

View File

@ -348,6 +348,8 @@ nsresult ServiceWorkerPrivateImpl::Initialize() {
mRemoteWorkerData.storageAccess() = storageAccess;
mRemoteWorkerData.serviceWorkerData() = std::move(serviceWorkerData);
mRemoteWorkerData.agentClusterId() = regInfo->AgentClusterId();
// This fills in the rest of mRemoteWorkerData.serviceWorkerData().
rv = RefreshRemoteWorkerData(regInfo);

View File

@ -786,6 +786,10 @@ void ServiceWorkerRegistrationInfo::ClearWhenIdle() {
});
}
const nsID& ServiceWorkerRegistrationInfo::AgentClusterId() const {
return mAgentClusterId;
}
// static
uint64_t ServiceWorkerRegistrationInfo::GetNextId() {
MOZ_ASSERT(NS_IsMainThread());

View File

@ -37,6 +37,8 @@ class ServiceWorkerRegistrationInfo final
};
nsTArray<UniquePtr<VersionEntry>> mVersionList;
const nsID mAgentClusterId = nsContentUtils::GenerateUUID();
uint32_t mControlledClientsCounter;
uint32_t mDelayMultiplier;
@ -209,6 +211,8 @@ class ServiceWorkerRegistrationInfo final
void ClearWhenIdle();
const nsID& AgentClusterId() const;
private:
// Roughly equivalent to [[Update Registration State algorithm]]. Make sure
// this is called *before* updating SW instances' state, otherwise they

View File

@ -113,6 +113,8 @@ struct WorkerLoadInfoData {
Maybe<ServiceWorkerDescriptor> mParentController;
nsID mAgentClusterId;
ChannelInfo mChannelInfo;
nsLoadFlags mLoadFlags;

View File

@ -2116,7 +2116,8 @@ WorkerPrivate::WorkerPrivate(WorkerPrivate* aParent,
WorkerType aWorkerType,
const nsAString& aWorkerName,
const nsACString& aServiceWorkerScope,
WorkerLoadInfo& aLoadInfo, nsString&& aId)
WorkerLoadInfo& aLoadInfo, nsString&& aId,
const nsID& aAgentClusterId)
: mMutex("WorkerPrivate Mutex"),
mCondVar(mMutex, "WorkerPrivate CondVar"),
mParent(aParent),
@ -2137,6 +2138,7 @@ WorkerPrivate::WorkerPrivate(WorkerPrivate* aParent,
mLoadingWorkerScript(false),
mCreationTimeStamp(TimeStamp::Now()),
mCreationTimeHighRes((double)PR_Now() / PR_USEC_PER_MSEC),
mAgentClusterId(aAgentClusterId),
mWorkerThreadAccessible(aParent),
mPostSyncLoopOperations(0),
mParentWindowPaused(false),
@ -2308,9 +2310,34 @@ already_AddRefed<WorkerPrivate> WorkerPrivate::Constructor(
MOZ_ASSERT(runtimeService);
nsID agentClusterId;
if (parent) {
MOZ_ASSERT(aWorkerType == WorkerType::WorkerTypeDedicated);
agentClusterId = parent->AgentClusterId();
} else {
AssertIsOnMainThread();
if (aWorkerType == WorkerType::WorkerTypeService ||
aWorkerType == WorkerType::WorkerTypeShared) {
agentClusterId = aLoadInfo->mAgentClusterId;
} else if (aLoadInfo->mWindow) {
Document* doc = aLoadInfo->mWindow->GetExtantDoc();
MOZ_DIAGNOSTIC_ASSERT(doc);
RefPtr<DocGroup> docGroup = doc->GetDocGroup();
agentClusterId = docGroup ? docGroup->AgentClusterId()
: nsContentUtils::GenerateUUID();
} else {
// If the window object was failed to be set into the WorkerLoadInfo, we
// make the worker into another agent cluster group instead of failures.
agentClusterId = nsContentUtils::GenerateUUID();
}
}
RefPtr<WorkerPrivate> worker = new WorkerPrivate(
parent, aScriptURL, aIsChromeWorker, aWorkerType, aWorkerName,
aServiceWorkerScope, *aLoadInfo, std::move(aId));
aServiceWorkerScope, *aLoadInfo, std::move(aId), agentClusterId);
// Gecko contexts always have an explicitly-set default locale (set by
// XPJSRuntime::Initialize for the main thread, set by
@ -2957,6 +2984,8 @@ bool WorkerPrivate::EnsureClientSource() {
type, mWorkerHybridEventTarget, GetPrincipalInfo());
MOZ_DIAGNOSTIC_ASSERT(data->mClientSource);
data->mClientSource->SetAgentClusterId(mAgentClusterId);
if (data->mFrozen) {
data->mClientSource->Freeze();
}

View File

@ -896,7 +896,8 @@ class WorkerPrivate : public RelativeTimeline {
bool aIsChromeWorker, WorkerType aWorkerType,
const nsAString& aWorkerName,
const nsACString& aServiceWorkerScope,
WorkerLoadInfo& aLoadInfo, nsString&& aId);
WorkerLoadInfo& aLoadInfo, nsString&& aId,
const nsID& aAgentClusterId);
~WorkerPrivate();
@ -985,6 +986,8 @@ class WorkerPrivate : public RelativeTimeline {
// executed.
void DispatchCancelingRunnable();
const nsID& AgentClusterId() const { return mAgentClusterId; }
class EventTarget;
friend class EventTarget;
friend class AutoSyncLoopHolder;
@ -1101,6 +1104,10 @@ class WorkerPrivate : public RelativeTimeline {
TimeStamp mCreationTimeStamp;
DOMHighResTimeStamp mCreationTimeHighRes;
// This is created while creating the WorkerPrivate, so it's safe to be
// touched on any thread.
const nsID mAgentClusterId;
// Things touched on worker thread only.
struct WorkerThreadAccessible {
explicit WorkerThreadAccessible(WorkerPrivate* aParent);

View File

@ -442,6 +442,8 @@ nsresult RemoteWorkerChild::ExecWorkerOnMainThread(RemoteWorkerData&& aData) {
}
}
info.mAgentClusterId = aData.agentClusterId();
AutoJSAPI jsapi;
jsapi.Init();

View File

@ -8,6 +8,7 @@ include IPCServiceWorkerRegistrationDescriptor;
include PBackgroundSharedTypes;
include URIParams;
include DOMTypes;
include ProtocolTypes;
using struct IPC::Permission from "mozilla/net/NeckoMessageUtils.h";
using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
@ -68,6 +69,8 @@ struct RemoteWorkerData
StorageAccess storageAccess;
OptionalServiceWorkerData serviceWorkerData;
nsID agentClusterId;
};
// ErrorData/ErrorDataNote correspond to WorkerErrorReport/WorkerErrorNote

View File

@ -191,11 +191,13 @@ already_AddRefed<SharedWorker> SharedWorker::Constructor(
ipcClientInfo.emplace(clientInfo.value().ToIPC());
}
nsID agentClusterId = nsContentUtils::GenerateUUID();
RemoteWorkerData remoteWorkerData(
nsString(aScriptURL), baseURL, resolvedScriptURL, name,
loadingPrincipalInfo, principalInfo, storagePrincipalInfo,
loadInfo.mDomain, isSecureContext, ipcClientInfo, loadInfo.mReferrerInfo,
storageAllowed, void_t() /* OptionalServiceWorkerData */);
storageAllowed, void_t() /* OptionalServiceWorkerData */, agentClusterId);
PSharedWorkerChild* pActor = actorChild->SendPSharedWorkerConstructor(
remoteWorkerData, loadInfo.mWindowID, portIdentifier);