mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-26 20:30:41 +00:00
Bug 1620594 - Part 7: Remove TabGroup and SystemGroup. r=nika,bas
TabGroup never really made any difference in which thread something go dispatched to. This was the intended use, but development of TabGroups with abstract main threads never made it that far. The good thing is that thish makes it safe to also remove to the SystemGroup and instead switch all SystemGroup dispatches to dispatches to main thread. Timers for setTimeout and workers were the sole users of wrapped and throttled event targets, that those throttled queues have been moved to the BrowsingContextGroup and are now accessed explicitly. The SchedulerEventTarget has been removed, since there are no longer a separate event target for every TaskCategory. Instead a LabellingEventTarget has been added to DocGroup to handle the case where an event is dispatched do DocGroup or when an AbstractThread is created using a DocGroup. This means that we'll actually label more events correctly with the DocGroup that they belong to. DocGroups have also been moved to BrowsingContextGroup. Depends on D67636 Differential Revision: https://phabricator.services.mozilla.com/D65936 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
b529c76594
commit
25ca8d7890
@ -8,6 +8,7 @@
|
||||
#include "mozilla/dom/BrowsingContextBinding.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/DocGroup.h"
|
||||
#include "mozilla/StaticPrefs_dom.h"
|
||||
#include "mozilla/ThrottledEventQueue.h"
|
||||
#include "nsFocusManager.h"
|
||||
@ -21,6 +22,12 @@ BrowsingContextGroup::BrowsingContextGroup() {
|
||||
} else {
|
||||
ContentParent::HoldBrowsingContextGroup(this);
|
||||
}
|
||||
|
||||
mTimerEventQueue = ThrottledEventQueue::Create(
|
||||
GetMainThreadSerialEventTarget(), "BrowsingContextGroup timer queue");
|
||||
|
||||
mWorkerEventQueue = ThrottledEventQueue::Create(
|
||||
GetMainThreadSerialEventTarget(), "BrowsingContextGroup worker queue");
|
||||
}
|
||||
|
||||
bool BrowsingContextGroup::Contains(BrowsingContext* aBrowsingContext) {
|
||||
@ -40,6 +47,7 @@ void BrowsingContextGroup::Unregister(BrowsingContext* aBrowsingContext) {
|
||||
// There are no browsing context still referencing this group. We can clear
|
||||
// all subscribers.
|
||||
UnsubscribeAllContentParents();
|
||||
|
||||
if (XRE_IsContentProcess()) {
|
||||
ContentChild::GetSingleton()->ReleaseBrowsingContextGroup(this);
|
||||
} else {
|
||||
@ -219,27 +227,42 @@ BrowsingContextGroup* BrowsingContextGroup::GetChromeGroup() {
|
||||
}
|
||||
|
||||
void BrowsingContextGroup::GetDocGroups(nsTArray<DocGroup*>& aDocGroups) {
|
||||
nsTHashtable<nsRefPtrHashKey<DocGroup>> docGroups;
|
||||
for (auto& toplevel : mToplevels) {
|
||||
toplevel->PreOrderWalk([&](BrowsingContext* aContext) {
|
||||
if (nsDocShell* docShell = nsDocShell::Cast(aContext->GetDocShell())) {
|
||||
if (!docShell->HasContentViewer()) {
|
||||
return;
|
||||
}
|
||||
if (Document* document = docShell->GetDocument()) {
|
||||
docGroups.PutEntry(document->GetDocGroup());
|
||||
}
|
||||
}
|
||||
});
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
for (auto iter = mDocGroups.ConstIter(); !iter.Done(); iter.Next()) {
|
||||
aDocGroups.AppendElement(iter.Data());
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<DocGroup> BrowsingContextGroup::AddDocument(
|
||||
const nsACString& aKey, Document* aDocument) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
RefPtr<DocGroup>& docGroup = mDocGroups.GetOrInsert(aKey);
|
||||
if (!docGroup) {
|
||||
docGroup = DocGroup::Create(this, aKey);
|
||||
}
|
||||
|
||||
for (auto iter = docGroups.ConstIter(); !iter.Done(); iter.Next()) {
|
||||
aDocGroups.AppendElement(iter.Get()->GetKey());
|
||||
docGroup->AddDocument(aDocument);
|
||||
return do_AddRef(docGroup);
|
||||
}
|
||||
|
||||
void BrowsingContextGroup::RemoveDocument(const nsACString& aKey,
|
||||
Document* aDocument) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
RefPtr<DocGroup> docGroup = aDocument->GetDocGroup();
|
||||
// Removing the last document in DocGroup might decrement the
|
||||
// DocGroup BrowsingContextGroup's refcount to 0.
|
||||
RefPtr<BrowsingContextGroup> kungFuDeathGrip(this);
|
||||
docGroup->RemoveDocument(aDocument);
|
||||
|
||||
if (docGroup->IsEmpty()) {
|
||||
mDocGroups.Remove(aKey);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(BrowsingContextGroup, mContexts,
|
||||
mToplevels, mSubscribers, mCachedContexts)
|
||||
mToplevels, mSubscribers, mCachedContexts,
|
||||
mTimerEventQueue, mWorkerEventQueue)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(BrowsingContextGroup, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(BrowsingContextGroup, Release)
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define mozilla_dom_BrowsingContextGroup_h
|
||||
|
||||
#include "mozilla/dom/BrowsingContext.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsTHashtable.h"
|
||||
@ -23,9 +24,7 @@ class BrowsingContext;
|
||||
class ContentParent;
|
||||
|
||||
// A BrowsingContextGroup represents the Unit of Related Browsing Contexts in
|
||||
// the standard. This object currently serves roughly the same purpose as the
|
||||
// TabGroup class which already exists, and at some point will likely merge with
|
||||
// it.
|
||||
// the standard.
|
||||
//
|
||||
// A BrowsingContext may not hold references to other BrowsingContext objects
|
||||
// which are not in the same BrowsingContextGroup.
|
||||
@ -119,6 +118,23 @@ class BrowsingContextGroup final : public nsWrapperCache {
|
||||
|
||||
void GetDocGroups(nsTArray<DocGroup*>& aDocGroups);
|
||||
|
||||
// Called by Document when a Document needs to be added to a DocGroup.
|
||||
already_AddRefed<DocGroup> AddDocument(const nsACString& aKey,
|
||||
Document* aDocument);
|
||||
|
||||
// Called by Document when a Document needs to be removed to a DocGroup.
|
||||
void RemoveDocument(const nsACString& aKey, Document* aDocument);
|
||||
|
||||
auto DocGroups() const { return mDocGroups.ConstIter(); }
|
||||
|
||||
mozilla::ThrottledEventQueue* GetTimerEventQueue() const {
|
||||
return mTimerEventQueue;
|
||||
}
|
||||
|
||||
mozilla::ThrottledEventQueue* GetWorkerEventQueue() const {
|
||||
return mWorkerEventQueue;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class CanonicalBrowsingContext;
|
||||
|
||||
@ -134,6 +150,12 @@ class BrowsingContextGroup final : public nsWrapperCache {
|
||||
// The set of toplevel browsing contexts in the current BrowsingContextGroup.
|
||||
BrowsingContext::Children mToplevels;
|
||||
|
||||
// DocGroups are thread-safe, and not able to be cycle collected,
|
||||
// but we still keep strong pointers. When all Documents are removed
|
||||
// from DocGroup (by the BrowsingContextGroup), the DocGroup is
|
||||
// removed from here.
|
||||
nsRefPtrHashtable<nsCStringHashKey, DocGroup> mDocGroups;
|
||||
|
||||
ContentParents mSubscribers;
|
||||
|
||||
// Map of cached contexts that need to stay alive due to bfcache.
|
||||
@ -142,6 +164,9 @@ class BrowsingContextGroup final : public nsWrapperCache {
|
||||
// A queue to store postMessage events during page load, the queue will be
|
||||
// flushed once the page is loaded
|
||||
RefPtr<mozilla::ThrottledEventQueue> mPostMessageEventQueue;
|
||||
|
||||
RefPtr<mozilla::ThrottledEventQueue> mTimerEventQueue;
|
||||
RefPtr<mozilla::ThrottledEventQueue> mWorkerEventQueue;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/PresShell.h"
|
||||
#include "mozilla/ResultExtensions.h"
|
||||
#include "mozilla/SchedulerGroup.h"
|
||||
#include "mozilla/ScrollTypes.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/StaticPrefs_browser.h"
|
||||
@ -66,7 +67,6 @@
|
||||
#include "mozilla/dom/ServiceWorkerUtils.h"
|
||||
#include "mozilla/dom/SessionStorageManager.h"
|
||||
#include "mozilla/dom/BrowserChild.h"
|
||||
#include "mozilla/dom/TabGroup.h"
|
||||
#include "mozilla/dom/ToJSValue.h"
|
||||
#include "mozilla/dom/UserActivation.h"
|
||||
#include "mozilla/dom/ChildSHistory.h"
|
||||
@ -1018,12 +1018,11 @@ void nsDocShell::FirePageHideNotificationInternal(
|
||||
}
|
||||
}
|
||||
|
||||
nsresult nsDocShell::DispatchToTabGroup(
|
||||
TaskCategory aCategory, already_AddRefed<nsIRunnable>&& aRunnable) {
|
||||
// Hold the ref so we won't forget to release it.
|
||||
nsresult nsDocShell::Dispatch(TaskCategory aCategory,
|
||||
already_AddRefed<nsIRunnable>&& aRunnable) {
|
||||
nsCOMPtr<nsIRunnable> runnable(aRunnable);
|
||||
nsCOMPtr<nsPIDOMWindowOuter> win = GetWindow();
|
||||
if (!win) {
|
||||
if (NS_WARN_IF(!win)) {
|
||||
// Window should only be unavailable after destroyed.
|
||||
MOZ_ASSERT(mIsBeingDestroyed);
|
||||
return NS_ERROR_FAILURE;
|
||||
@ -1038,7 +1037,7 @@ nsresult nsDocShell::DispatchToTabGroup(
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::DispatchLocationChangeEvent() {
|
||||
return DispatchToTabGroup(
|
||||
return Dispatch(
|
||||
TaskCategory::Other,
|
||||
NewRunnableMethod("nsDocShell::FireDummyOnLocationChange", this,
|
||||
&nsDocShell::FireDummyOnLocationChange));
|
||||
@ -6459,12 +6458,12 @@ nsresult nsDocShell::EnsureContentViewer() {
|
||||
doc->SetIsInitialDocument(true);
|
||||
|
||||
// Documents created using EnsureContentViewer may be transient
|
||||
// placeholders created by framescripts before content has a chance to
|
||||
// load. In some cases, window.open(..., "noopener") will create such a
|
||||
// document (in a new TabGroup) and then synchronously tear it down, firing
|
||||
// a "pagehide" event. Doing so violates our assertions about
|
||||
// DocGroups. It's easier to silence the assertion here than to avoid
|
||||
// creating the extra document.
|
||||
// placeholders created by framescripts before content has a
|
||||
// chance to load. In some cases, window.open(..., "noopener")
|
||||
// will create such a document and then synchronously tear it
|
||||
// down, firing a "pagehide" event. Doing so violates our
|
||||
// assertions about DocGroups. It's easier to silence the
|
||||
// assertion here than to avoid creating the extra document.
|
||||
doc->IgnoreDocGroupMismatches();
|
||||
}
|
||||
|
||||
@ -7057,8 +7056,7 @@ nsresult nsDocShell::RestorePresentation(nsISHEntry* aSHEntry,
|
||||
mRestorePresentationEvent.Revoke();
|
||||
|
||||
RefPtr<RestorePresentationEvent> evt = new RestorePresentationEvent(this);
|
||||
nsresult rv = DispatchToTabGroup(
|
||||
TaskCategory::Other, RefPtr<RestorePresentationEvent>(evt).forget());
|
||||
nsresult rv = Dispatch(TaskCategory::Other, do_AddRef(evt));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mRestorePresentationEvent = evt.get();
|
||||
// The rest of the restore processing will happen on our event
|
||||
@ -8873,7 +8871,7 @@ nsresult nsDocShell::InternalLoad(nsDocShellLoadState* aLoadState,
|
||||
|
||||
// Do this asynchronously
|
||||
nsCOMPtr<nsIRunnable> ev = new InternalLoadEvent(this, aLoadState);
|
||||
return DispatchToTabGroup(TaskCategory::Other, ev.forget());
|
||||
return Dispatch(TaskCategory::Other, ev.forget());
|
||||
}
|
||||
|
||||
// Just ignore this load attempt
|
||||
@ -12231,7 +12229,7 @@ nsresult nsDocShell::OnLinkClick(
|
||||
this, aContent, aURI, target, aFileName, aPostDataStream,
|
||||
aHeadersDataStream, noOpenerImplied, aIsUserTriggered, aIsTrusted,
|
||||
aTriggeringPrincipal, aCsp);
|
||||
return DispatchToTabGroup(TaskCategory::UI, ev.forget());
|
||||
return Dispatch(TaskCategory::UI, ev.forget());
|
||||
}
|
||||
|
||||
static bool IsElementAnchorOrArea(nsIContent* aContent) {
|
||||
|
@ -1000,9 +1000,8 @@ class nsDocShell final : public nsDocLoader,
|
||||
void FirePageHideNotificationInternal(bool aIsUnload,
|
||||
bool aSkipCheckingDynEntries);
|
||||
|
||||
// Dispatch a runnable to the TabGroup associated to this docshell.
|
||||
nsresult DispatchToTabGroup(mozilla::TaskCategory aCategory,
|
||||
already_AddRefed<nsIRunnable>&& aRunnable);
|
||||
nsresult Dispatch(mozilla::TaskCategory aCategory,
|
||||
already_AddRefed<nsIRunnable>&& aRunnable);
|
||||
|
||||
void SetupReferrerInfoFromChannel(nsIChannel* aChannel);
|
||||
void SetReferrerInfo(nsIReferrerInfo* aReferrerInfo);
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozilla/dom/TabGroup.h"
|
||||
#include "nsIWebNavigation.h"
|
||||
#include "nsDocShellLoadTypes.h"
|
||||
#include "base/process.h"
|
||||
|
@ -16,12 +16,10 @@ class nsISerialEventTarget;
|
||||
namespace mozilla {
|
||||
class AbstractThread;
|
||||
namespace dom {
|
||||
class TabGroup;
|
||||
|
||||
// This trait should be attached to classes like nsIGlobalObject and Document
|
||||
// that have a DocGroup or TabGroup attached to them. The methods here should
|
||||
// delegate to the DocGroup or TabGroup. We can't use the Dispatcher class
|
||||
// directly because it inherits from nsISupports.
|
||||
// This trait should be attached to classes like nsIGlobalObject and
|
||||
// Document that have a DocGroup attached to them. The methods here
|
||||
// should delegate to the DocGroup. We can't use the
|
||||
// Dispatcher class directly because it inherits from nsISupports.
|
||||
class DispatcherTrait {
|
||||
public:
|
||||
// This method may or may not be safe off of the main thread. For Document it
|
||||
|
@ -7,9 +7,9 @@
|
||||
#include "mozilla/dom/DocGroup.h"
|
||||
#include "mozilla/dom/DOMTypes.h"
|
||||
#include "mozilla/dom/JSExecutionManager.h"
|
||||
#include "mozilla/dom/TabGroup.h"
|
||||
#include "mozilla/AbstractThread.h"
|
||||
#include "mozilla/PerformanceUtils.h"
|
||||
#include "mozilla/SchedulerGroup.h"
|
||||
#include "mozilla/ThrottledEventQueue.h"
|
||||
#include "mozilla/StaticPrefs_dom.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
@ -21,11 +21,91 @@
|
||||
# include <unistd.h> // for getpid()
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
namespace {
|
||||
|
||||
#define NS_LABELLINGEVENTTARGET_IID \
|
||||
{ \
|
||||
0x6087fa50, 0xe387, 0x45c8, { \
|
||||
0xab, 0x72, 0xd2, 0x1f, 0x69, 0xee, 0xd3, 0x15 \
|
||||
} \
|
||||
}
|
||||
|
||||
// LabellingEventTarget labels all dispatches with the DocGroup that
|
||||
// created it.
|
||||
class LabellingEventTarget final : public nsISerialEventTarget {
|
||||
// This creates a cycle with DocGroup. Therefore, when DocGroup
|
||||
// looses its last Document, the DocGroup of the
|
||||
// LabellingEventTarget needs to be cleared.
|
||||
RefPtr<mozilla::dom::DocGroup> mDocGroup;
|
||||
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_LABELLINGEVENTTARGET_IID)
|
||||
|
||||
explicit LabellingEventTarget(mozilla::dom::DocGroup* aDocGroup)
|
||||
: mDocGroup(aDocGroup) {}
|
||||
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIEVENTTARGET_FULL
|
||||
|
||||
void ClearDocGroup() { mDocGroup = nullptr; }
|
||||
|
||||
private:
|
||||
~LabellingEventTarget() = default;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(LabellingEventTarget, NS_LABELLINGEVENTTARGET_IID)
|
||||
|
||||
} // namespace
|
||||
|
||||
NS_IMETHODIMP
|
||||
LabellingEventTarget::DispatchFromScript(nsIRunnable* aRunnable,
|
||||
uint32_t aFlags) {
|
||||
return Dispatch(do_AddRef(aRunnable), aFlags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
LabellingEventTarget::Dispatch(already_AddRefed<nsIRunnable> aRunnable,
|
||||
uint32_t aFlags) {
|
||||
if (NS_WARN_IF(aFlags != NS_DISPATCH_NORMAL)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
return mozilla::SchedulerGroup::DispatchWithDocGroup(
|
||||
mozilla::TaskCategory::Other, std::move(aRunnable), mDocGroup);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
LabellingEventTarget::DelayedDispatch(already_AddRefed<nsIRunnable>, uint32_t) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
LabellingEventTarget::IsOnCurrentThread(bool* aIsOnCurrentThread) {
|
||||
*aIsOnCurrentThread = NS_IsMainThread();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
LabellingEventTarget::IsOnCurrentThreadInfallible() {
|
||||
return NS_IsMainThread();
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(LabellingEventTarget, LabellingEventTarget, nsIEventTarget,
|
||||
nsISerialEventTarget)
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
AutoTArray<RefPtr<DocGroup>, 2>* DocGroup::sPendingDocGroups = nullptr;
|
||||
|
||||
/* static */
|
||||
already_AddRefed<DocGroup> DocGroup::Create(
|
||||
BrowsingContextGroup* aBrowsingContextGroup, const nsACString& aKey) {
|
||||
RefPtr<DocGroup> docGroup = new DocGroup(aBrowsingContextGroup, aKey);
|
||||
docGroup->mEventTarget = new LabellingEventTarget(docGroup);
|
||||
return docGroup.forget();
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsresult DocGroup::GetKey(nsIPrincipal* aPrincipal, nsACString& aKey) {
|
||||
// Use GetBaseDomain() to handle things like file URIs, IP address URIs,
|
||||
@ -47,17 +127,34 @@ void DocGroup::SetExecutionManager(JSExecutionManager* aManager) {
|
||||
mExecutionManager = aManager;
|
||||
}
|
||||
|
||||
void DocGroup::AddDocument(Document* aDocument) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!mDocuments.Contains(aDocument));
|
||||
MOZ_ASSERT(mBrowsingContextGroup);
|
||||
mDocuments.AppendElement(aDocument);
|
||||
}
|
||||
|
||||
void DocGroup::RemoveDocument(Document* aDocument) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mDocuments.Contains(aDocument));
|
||||
mDocuments.RemoveElement(aDocument);
|
||||
|
||||
if (mDocuments.IsEmpty()) {
|
||||
mBrowsingContextGroup = nullptr;
|
||||
nsCOMPtr<LabellingEventTarget> target = do_QueryInterface(mEventTarget);
|
||||
// This clears the cycle DocGroup has with LabellingEventTarget.
|
||||
target->ClearDocGroup();
|
||||
}
|
||||
}
|
||||
|
||||
DocGroup::DocGroup(TabGroup* aTabGroup, const nsACString& aKey,
|
||||
const nsID& aAgentClusterId)
|
||||
: mKey(aKey), mTabGroup(aTabGroup), mAgentClusterId(aAgentClusterId) {
|
||||
// This method does not add itself to mTabGroup->mDocGroups as the caller does
|
||||
// it for us.
|
||||
DocGroup::DocGroup(BrowsingContextGroup* aBrowsingContextGroup,
|
||||
const nsACString& aKey)
|
||||
: mKey(aKey),
|
||||
mBrowsingContextGroup(aBrowsingContextGroup),
|
||||
mAgentClusterId(nsContentUtils::GenerateUUID()) {
|
||||
// This method does not add itself to
|
||||
// mBrowsingContextGroup->mDocGroups as the caller does it for us.
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (StaticPrefs::dom_arena_allocator_enabled_AtStartup()) {
|
||||
mArena = new mozilla::dom::DOMArena();
|
||||
}
|
||||
@ -67,15 +164,15 @@ DocGroup::DocGroup(TabGroup* aTabGroup, const nsACString& aKey,
|
||||
}
|
||||
|
||||
DocGroup::~DocGroup() {
|
||||
MOZ_ASSERT(mDocuments.IsEmpty());
|
||||
MOZ_RELEASE_ASSERT(mDocuments.IsEmpty());
|
||||
MOZ_RELEASE_ASSERT(!mBrowsingContextGroup);
|
||||
|
||||
if (!NS_IsMainThread()) {
|
||||
nsIEventTarget* target = EventTargetFor(TaskCategory::Other);
|
||||
NS_ProxyRelease("DocGroup::mReactionsStack", target,
|
||||
mReactionsStack.forget());
|
||||
}
|
||||
|
||||
mTabGroup->mDocGroups.RemoveEntry(mKey);
|
||||
|
||||
if (mIframePostMessageQueue) {
|
||||
FlushIframePostMessageQueue();
|
||||
}
|
||||
@ -175,19 +272,32 @@ nsresult DocGroup::Dispatch(TaskCategory aCategory,
|
||||
if (mPerformanceCounter) {
|
||||
mPerformanceCounter->IncrementDispatchCounter(DispatchCategory(aCategory));
|
||||
}
|
||||
return mTabGroup->DispatchWithDocGroup(aCategory, std::move(aRunnable), this);
|
||||
return SchedulerGroup::DispatchWithDocGroup(aCategory, std::move(aRunnable),
|
||||
this);
|
||||
}
|
||||
|
||||
nsISerialEventTarget* DocGroup::EventTargetFor(TaskCategory aCategory) const {
|
||||
return mTabGroup->EventTargetFor(aCategory);
|
||||
MOZ_ASSERT(!mDocuments.IsEmpty());
|
||||
// Here we have the same event target for every TaskCategory. The
|
||||
// reason for that is that currently TaskCategory isn't used, and
|
||||
// it's unsure if it ever will be (See Bug 1624819).
|
||||
return mEventTarget;
|
||||
}
|
||||
|
||||
AbstractThread* DocGroup::AbstractMainThreadFor(TaskCategory aCategory) {
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
return mTabGroup->AbstractMainThreadFor(aCategory);
|
||||
}
|
||||
MOZ_ASSERT(!mDocuments.IsEmpty());
|
||||
// Here we have the same thread for every TaskCategory. The reason
|
||||
// for that is that currently TaskCategory isn't used, and it's
|
||||
// unsure if it ever will be (See Bug 1624819).
|
||||
if (!mAbstractThread) {
|
||||
mAbstractThread = AbstractThread::CreateEventTargetWrapper(
|
||||
mEventTarget,
|
||||
/* aRequireTailDispatch = */ true);
|
||||
}
|
||||
|
||||
bool* DocGroup::GetValidAccessPtr() { return mTabGroup->GetValidAccessPtr(); }
|
||||
return mAbstractThread;
|
||||
}
|
||||
|
||||
void DocGroup::SignalSlotChange(HTMLSlotElement& aSlot) {
|
||||
MOZ_ASSERT(!mSignalSlotList.Contains(&aSlot));
|
||||
@ -219,10 +329,10 @@ nsresult DocGroup::QueueIframePostMessages(
|
||||
MOZ_ALWAYS_SUCCEEDS(rv);
|
||||
}
|
||||
|
||||
// Ensure the queue is disabled. Unlike the postMessageEvent queue in
|
||||
// TabGroup, this postMessage queue should always be paused, because if
|
||||
// we leave it open, the postMessage may get dispatched to an unloaded
|
||||
// iframe
|
||||
// Ensure the queue is disabled. Unlike the postMessageEvent queue
|
||||
// in BrowsingContextGroup, this postMessage queue should always
|
||||
// be paused, because if we leave it open, the postMessage may get
|
||||
// dispatched to an unloaded iframe
|
||||
MOZ_ASSERT(mIframePostMessageQueue);
|
||||
MOZ_ASSERT(mIframePostMessageQueue->IsPaused());
|
||||
|
||||
@ -272,5 +382,10 @@ bool DocGroup::IsActive() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void DocGroup::ClearEventTarget() {
|
||||
nsCOMPtr<LabellingEventTarget> target = do_QueryInterface(mEventTarget);
|
||||
target->ClearDocGroup();
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -11,9 +11,8 @@
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsTHashtable.h"
|
||||
#include "nsString.h"
|
||||
|
||||
#include "mozilla/dom/TabGroup.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/dom/BrowsingContextGroup.h"
|
||||
#include "mozilla/dom/CustomElementRegistry.h"
|
||||
#include "mozilla/dom/HTMLSlotElement.h"
|
||||
#include "mozilla/PerformanceCounter.h"
|
||||
@ -25,26 +24,25 @@ namespace dom {
|
||||
|
||||
// Two browsing contexts are considered "related" if they are reachable from one
|
||||
// another through window.opener, window.parent, or window.frames. This is the
|
||||
// spec concept of a "unit of related browsing contexts"
|
||||
// spec concept of a browsing context group.
|
||||
//
|
||||
// Two browsing contexts are considered "similar-origin" if they can be made to
|
||||
// have the same origin by setting document.domain. This is the spec concept of
|
||||
// a "unit of similar-origin related browsing contexts"
|
||||
//
|
||||
// A TabGroup is a set of browsing contexts which are all "related". Within a
|
||||
// TabGroup, browsing contexts are broken into "similar-origin" DocGroups. In
|
||||
// more detail, a DocGroup is actually a collection of documents, and a
|
||||
// TabGroup is a collection of DocGroups. A TabGroup typically will contain
|
||||
// (through its DocGroups) the documents from one or more tabs related by
|
||||
// window.opener. A DocGroup is a member of exactly one TabGroup.
|
||||
|
||||
// A BrowsingContextGroup is a set of browsing contexts which are all
|
||||
// "related". Within a BrowsingContextGroup, browsing contexts are
|
||||
// broken into "similar-origin" DocGroups. A DocGroup is a member
|
||||
// of exactly one BrowsingContextGroup.
|
||||
class DocGroup final {
|
||||
public:
|
||||
typedef nsTArray<Document*>::iterator Iterator;
|
||||
friend class TabGroup;
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DocGroup)
|
||||
|
||||
static already_AddRefed<DocGroup> Create(
|
||||
BrowsingContextGroup* aBrowsingContextGroup, const nsACString& aKey);
|
||||
|
||||
// Returns NS_ERROR_FAILURE and sets |aString| to an empty string if the TLD
|
||||
// service isn't available. Returns NS_OK on success, but may still set
|
||||
// |aString| may still be set to an empty string.
|
||||
@ -53,6 +51,8 @@ class DocGroup final {
|
||||
|
||||
bool MatchesKey(const nsACString& aKey) { return aKey == mKey; }
|
||||
|
||||
const nsACString& GetKey() const { return mKey; }
|
||||
|
||||
PerformanceCounter* GetPerformanceCounter() { return mPerformanceCounter; }
|
||||
|
||||
JSExecutionManager* GetExecutionManager() const { return mExecutionManager; }
|
||||
@ -60,7 +60,9 @@ class DocGroup final {
|
||||
|
||||
RefPtr<PerformanceInfoPromise> ReportPerformanceInfo();
|
||||
|
||||
TabGroup* GetTabGroup() { return mTabGroup; }
|
||||
BrowsingContextGroup* GetBrowsingContextGroup() const {
|
||||
return mBrowsingContextGroup;
|
||||
}
|
||||
|
||||
mozilla::dom::DOMArena* ArenaAllocator() { return mArena; }
|
||||
|
||||
@ -72,7 +74,16 @@ class DocGroup final {
|
||||
|
||||
return mReactionsStack;
|
||||
}
|
||||
void RemoveDocument(Document* aWindow);
|
||||
|
||||
// Adding documents to a DocGroup should be done through
|
||||
// BrowsingContextGroup::AddDocument (which in turn calls
|
||||
// DocGroup::AddDocument).
|
||||
void AddDocument(Document* aDocument);
|
||||
|
||||
// Removing documents from a DocGroup should be done through
|
||||
// BrowsingContextGroup::RemoveDocument(which in turn calls
|
||||
// DocGroup::RemoveDocument).
|
||||
void RemoveDocument(Document* aDocument);
|
||||
|
||||
// Iterators for iterating over every document within the DocGroup
|
||||
Iterator begin() {
|
||||
@ -117,21 +128,26 @@ class DocGroup final {
|
||||
|
||||
const nsID& AgentClusterId() const { return mAgentClusterId; }
|
||||
|
||||
bool IsEmpty() const { return mDocuments.IsEmpty(); }
|
||||
|
||||
void ClearEventTarget();
|
||||
|
||||
private:
|
||||
DocGroup(TabGroup* aTabGroup, const nsACString& aKey,
|
||||
const nsID& aAgentClusterId);
|
||||
DocGroup(BrowsingContextGroup* aBrowsingContextGroup, const nsACString& aKey);
|
||||
|
||||
~DocGroup();
|
||||
|
||||
void FlushIframePostMessageQueue();
|
||||
nsCString mKey;
|
||||
RefPtr<TabGroup> mTabGroup;
|
||||
nsTArray<Document*> mDocuments;
|
||||
RefPtr<mozilla::dom::CustomElementReactionsStack> mReactionsStack;
|
||||
nsTArray<RefPtr<HTMLSlotElement>> mSignalSlotList;
|
||||
RefPtr<mozilla::PerformanceCounter> mPerformanceCounter;
|
||||
|
||||
RefPtr<BrowsingContextGroup> mBrowsingContextGroup;
|
||||
RefPtr<mozilla::ThrottledEventQueue> mIframePostMessageQueue;
|
||||
nsTHashtable<nsUint64HashKey> mIframesUsedPostMessageQueue;
|
||||
nsCOMPtr<nsISerialEventTarget> mEventTarget;
|
||||
RefPtr<AbstractThread> mAbstractThread;
|
||||
|
||||
// non-null if the JS execution for this docgroup is regulated with regards
|
||||
// to worker threads. This should only be used when we are forcing serialized
|
||||
|
@ -310,7 +310,6 @@
|
||||
#include "mozilla/dom/SVGDocument.h"
|
||||
#include "mozilla/dom/SVGSVGElement.h"
|
||||
#include "mozilla/dom/DocGroup.h"
|
||||
#include "mozilla/dom/TabGroup.h"
|
||||
#include "mozilla/dom/ChromeObserver.h"
|
||||
#ifdef MOZ_XUL
|
||||
# include "mozilla/dom/XULBroadcastManager.h"
|
||||
@ -2021,7 +2020,9 @@ Document::~Document() {
|
||||
}
|
||||
|
||||
if (mDocGroup) {
|
||||
mDocGroup->RemoveDocument(this);
|
||||
MOZ_ASSERT(mDocGroup->GetBrowsingContextGroup());
|
||||
mDocGroup->GetBrowsingContextGroup()->RemoveDocument(mDocGroup->GetKey(),
|
||||
this);
|
||||
}
|
||||
|
||||
UnlinkOriginalDocumentIfStatic();
|
||||
@ -3764,7 +3765,6 @@ void Document::AssertDocGroupMatchesKey() const {
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
MOZ_ASSERT(mDocGroup->MatchesKey(docGroupKey));
|
||||
}
|
||||
// XXX: Check that the TabGroup is correct as well!
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -6796,15 +6796,10 @@ DocGroup* Document::GetDocGroupOrCreate() {
|
||||
if (!mDocGroup) {
|
||||
nsAutoCString docGroupKey;
|
||||
nsresult rv = mozilla::dom::DocGroup::GetKey(NodePrincipal(), docGroupKey);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (mDocumentContainer) {
|
||||
nsPIDOMWindowOuter* window = mDocumentContainer->GetWindow();
|
||||
if (window) {
|
||||
TabGroup* tabgroup = window->MaybeTabGroup();
|
||||
if (tabgroup) {
|
||||
mDocGroup = tabgroup->AddDocument(docGroupKey, this);
|
||||
}
|
||||
}
|
||||
if (NS_SUCCEEDED(rv) && mDocumentContainer) {
|
||||
BrowsingContextGroup* group = GetBrowsingContext()->Group();
|
||||
if (group) {
|
||||
mDocGroup = group->AddDocument(docGroupKey, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6817,29 +6812,30 @@ void Document::SetScopeObject(nsIGlobalObject* aGlobal) {
|
||||
mHasHadScriptHandlingObject = true;
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal);
|
||||
if (window) {
|
||||
// We want to get the tabgroup unconditionally, such that we can make
|
||||
// certain that it is cached in the inner window early enough.
|
||||
mozilla::dom::TabGroup* tabgroup = window->TabGroup();
|
||||
// We should already have the principal, and now that we have been added
|
||||
// to a window, we should be able to join a DocGroup!
|
||||
nsAutoCString docGroupKey;
|
||||
nsresult rv =
|
||||
mozilla::dom::DocGroup::GetKey(NodePrincipal(), docGroupKey);
|
||||
if (mDocGroup) {
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
MOZ_RELEASE_ASSERT(mDocGroup->MatchesKey(docGroupKey));
|
||||
}
|
||||
MOZ_RELEASE_ASSERT(mDocGroup->GetTabGroup() == tabgroup);
|
||||
} else {
|
||||
mDocGroup = tabgroup->AddDocument(docGroupKey, this);
|
||||
MOZ_ASSERT(mDocGroup);
|
||||
}
|
||||
|
||||
MOZ_ASSERT_IF(
|
||||
mNodeInfoManager->GetArenaAllocator(),
|
||||
mNodeInfoManager->GetArenaAllocator() == mDocGroup->ArenaAllocator());
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
BrowsingContextGroup* browsingContextGroup = window->GetBrowsingContextGroup();
|
||||
|
||||
// We should already have the principal, and now that we have been added
|
||||
// to a window, we should be able to join a DocGroup!
|
||||
nsAutoCString docGroupKey;
|
||||
nsresult rv = mozilla::dom::DocGroup::GetKey(NodePrincipal(), docGroupKey);
|
||||
if (mDocGroup) {
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
MOZ_RELEASE_ASSERT(mDocGroup->MatchesKey(docGroupKey));
|
||||
}
|
||||
MOZ_RELEASE_ASSERT(mDocGroup->GetBrowsingContextGroup() ==
|
||||
browsingContextGroup);
|
||||
} else {
|
||||
mDocGroup = browsingContextGroup->AddDocument(docGroupKey, this);
|
||||
|
||||
MOZ_ASSERT(mDocGroup);
|
||||
}
|
||||
|
||||
MOZ_ASSERT_IF(
|
||||
mNodeInfoManager->GetArenaAllocator(),
|
||||
mNodeInfoManager->GetArenaAllocator() == mDocGroup->ArenaAllocator());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,213 +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 "mozilla/dom/TabGroup.h"
|
||||
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/BrowserChild.h"
|
||||
#include "mozilla/dom/DocGroup.h"
|
||||
#include "mozilla/dom/TimeoutManager.h"
|
||||
#include "mozilla/AbstractThread.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/ThrottledEventQueue.h"
|
||||
#include "nsIDocShell.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
static StaticRefPtr<TabGroup> sChromeTabGroup;
|
||||
|
||||
LinkedList<TabGroup>* TabGroup::sTabGroups = nullptr;
|
||||
|
||||
TabGroup::TabGroup(bool aIsChrome)
|
||||
: mLastWindowLeft(false),
|
||||
mThrottledQueuesInitialized(false),
|
||||
mIsChrome(aIsChrome) {
|
||||
if (!sTabGroups) {
|
||||
sTabGroups = new LinkedList<TabGroup>();
|
||||
}
|
||||
sTabGroups->insertBack(this);
|
||||
|
||||
CreateEventTargets(/* aNeedValidation = */ !aIsChrome);
|
||||
|
||||
// Do not throttle runnables from chrome windows. In theory we should
|
||||
// not have abuse issues from these windows and many browser chrome
|
||||
// tests have races that fail if we do throttle chrome runnables.
|
||||
if (aIsChrome) {
|
||||
MOZ_ASSERT(!sChromeTabGroup);
|
||||
return;
|
||||
}
|
||||
|
||||
// This constructor can be called from the IPC I/O thread. In that case, we
|
||||
// won't actually use the TabGroup on the main thread until GetFromWindowActor
|
||||
// is called, so we initialize the throttled queues there.
|
||||
if (NS_IsMainThread()) {
|
||||
EnsureThrottledEventQueues();
|
||||
}
|
||||
}
|
||||
|
||||
TabGroup::~TabGroup() {
|
||||
MOZ_ASSERT(mDocGroups.IsEmpty());
|
||||
MOZ_ASSERT(mWindows.IsEmpty());
|
||||
MOZ_RELEASE_ASSERT(mLastWindowLeft || mIsChrome);
|
||||
|
||||
LinkedListElement<TabGroup>* listElement =
|
||||
static_cast<LinkedListElement<TabGroup>*>(this);
|
||||
listElement->remove();
|
||||
|
||||
if (sTabGroups->isEmpty()) {
|
||||
delete sTabGroups;
|
||||
sTabGroups = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void TabGroup::EnsureThrottledEventQueues() {
|
||||
if (mThrottledQueuesInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
mThrottledQueuesInitialized = true;
|
||||
|
||||
for (size_t i = 0; i < size_t(TaskCategory::Count); i++) {
|
||||
TaskCategory category = static_cast<TaskCategory>(i);
|
||||
if (category == TaskCategory::Worker) {
|
||||
mEventTargets[i] = ThrottledEventQueue::Create(mEventTargets[i],
|
||||
"TabGroup worker queue");
|
||||
} else if (category == TaskCategory::Timer) {
|
||||
mEventTargets[i] =
|
||||
ThrottledEventQueue::Create(mEventTargets[i], "TabGroup timer queue");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
TabGroup* TabGroup::GetChromeTabGroup() {
|
||||
if (!sChromeTabGroup) {
|
||||
sChromeTabGroup = new TabGroup(true /* chrome tab group */);
|
||||
ClearOnShutdown(&sChromeTabGroup);
|
||||
}
|
||||
return sChromeTabGroup;
|
||||
}
|
||||
|
||||
/* static */
|
||||
TabGroup* TabGroup::GetFromWindow(mozIDOMWindowProxy* aWindow) {
|
||||
if (BrowserChild* browserChild = BrowserChild::GetFrom(aWindow)) {
|
||||
return browserChild->TabGroup();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* static */
|
||||
TabGroup* TabGroup::GetFromActor(BrowserChild* aBrowserChild) {
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target =
|
||||
aBrowserChild->Manager()->GetEventTargetFor(aBrowserChild);
|
||||
if (!target) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// We have an event target. We assume the IPC code created it via
|
||||
// TabGroup::CreateEventTarget.
|
||||
RefPtr<SchedulerGroup> group = SchedulerGroup::FromEventTarget(target);
|
||||
MOZ_RELEASE_ASSERT(group);
|
||||
auto tabGroup = group->AsTabGroup();
|
||||
MOZ_RELEASE_ASSERT(tabGroup);
|
||||
|
||||
// We delay creating the event targets until now since the TabGroup
|
||||
// constructor ran off the main thread.
|
||||
tabGroup->EnsureThrottledEventQueues();
|
||||
|
||||
return tabGroup;
|
||||
}
|
||||
|
||||
already_AddRefed<DocGroup> TabGroup::GetDocGroup(const nsACString& aKey) {
|
||||
RefPtr<DocGroup> docGroup(mDocGroups.GetEntry(aKey)->mDocGroup);
|
||||
return docGroup.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DocGroup> TabGroup::AddDocument(const nsACString& aKey,
|
||||
Document* aDocument) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
HashEntry* entry = mDocGroups.PutEntry(aKey);
|
||||
RefPtr<DocGroup> docGroup;
|
||||
if (entry->mDocGroup) {
|
||||
docGroup = entry->mDocGroup;
|
||||
} else {
|
||||
const nsID agentClusterId = nsContentUtils::GenerateUUID();
|
||||
|
||||
docGroup = new DocGroup(this, aKey, agentClusterId);
|
||||
entry->mDocGroup = docGroup;
|
||||
}
|
||||
|
||||
// Make sure that the hashtable was updated and now contains the correct value
|
||||
MOZ_ASSERT(RefPtr<DocGroup>(GetDocGroup(aKey)) == docGroup);
|
||||
|
||||
docGroup->mDocuments.AppendElement(aDocument);
|
||||
|
||||
return docGroup.forget();
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<TabGroup> TabGroup::Join(nsPIDOMWindowOuter* aWindow,
|
||||
TabGroup* aTabGroup) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
RefPtr<TabGroup> tabGroup = aTabGroup;
|
||||
if (!tabGroup) {
|
||||
tabGroup = new TabGroup();
|
||||
}
|
||||
MOZ_RELEASE_ASSERT(!tabGroup->mLastWindowLeft);
|
||||
MOZ_ASSERT(!tabGroup->mWindows.Contains(aWindow));
|
||||
tabGroup->mWindows.AppendElement(aWindow);
|
||||
|
||||
return tabGroup.forget();
|
||||
}
|
||||
|
||||
void TabGroup::Leave(nsPIDOMWindowOuter* aWindow) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mWindows.Contains(aWindow));
|
||||
mWindows.RemoveElement(aWindow);
|
||||
|
||||
MaybeDestroy();
|
||||
}
|
||||
|
||||
void TabGroup::MaybeDestroy() {
|
||||
// The Chrome TabGroup doesn't have cyclical references through mEventTargets
|
||||
// to itself, meaning that we don't have to worry about nulling mEventTargets
|
||||
// out after the last window leaves.
|
||||
if (!mIsChrome && !mLastWindowLeft && mWindows.IsEmpty()) {
|
||||
mLastWindowLeft = true;
|
||||
Shutdown(false);
|
||||
}
|
||||
}
|
||||
|
||||
TabGroup::HashEntry::HashEntry(const nsACString* aKey)
|
||||
: nsCStringHashKey(aKey), mDocGroup(nullptr) {}
|
||||
|
||||
nsISerialEventTarget* TabGroup::EventTargetFor(TaskCategory aCategory) const {
|
||||
if (aCategory == TaskCategory::Worker || aCategory == TaskCategory::Timer) {
|
||||
MOZ_RELEASE_ASSERT(mThrottledQueuesInitialized || mIsChrome);
|
||||
}
|
||||
return SchedulerGroup::EventTargetFor(aCategory);
|
||||
}
|
||||
|
||||
AbstractThread* TabGroup::AbstractMainThreadForImpl(TaskCategory aCategory) {
|
||||
// The mEventTargets of the chrome TabGroup are all set to do_GetMainThread().
|
||||
// We could just return AbstractThread::MainThread() without a wrapper.
|
||||
// Once we've disconnected everything, we still allow people to dispatch.
|
||||
// We'll just go directly to the main thread.
|
||||
if (this == sChromeTabGroup || NS_WARN_IF(mLastWindowLeft)) {
|
||||
return AbstractThread::MainThread();
|
||||
}
|
||||
|
||||
return SchedulerGroup::AbstractMainThreadForImpl(aCategory);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
@ -1,131 +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 TabGroup_h
|
||||
#define TabGroup_h
|
||||
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsTHashtable.h"
|
||||
#include "nsString.h"
|
||||
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/SchedulerGroup.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
class mozIDOMWindowProxy;
|
||||
class nsIDocShellTreeItem;
|
||||
class nsPIDOMWindowOuter;
|
||||
|
||||
namespace mozilla {
|
||||
class AbstractThread;
|
||||
class ThrottledEventQueue;
|
||||
namespace dom {
|
||||
class Document;
|
||||
class BrowserChild;
|
||||
|
||||
// Two browsing contexts are considered "related" if they are reachable from one
|
||||
// another through window.opener, window.parent, or window.frames. This is the
|
||||
// spec concept of a "unit of related browsing contexts"
|
||||
//
|
||||
// Two browsing contexts are considered "similar-origin" if they can be made to
|
||||
// have the same origin by setting document.domain. This is the spec concept of
|
||||
// a "unit of similar-origin related browsing contexts"
|
||||
//
|
||||
// A TabGroup is a set of browsing contexts which are all "related". Within a
|
||||
// TabGroup, browsing contexts are broken into "similar-origin" DocGroups. In
|
||||
// more detail, a DocGroup is actually a collection of documents, and a
|
||||
// TabGroup is a collection of DocGroups. A TabGroup typically will contain
|
||||
// (through its DocGroups) the documents from one or more tabs related by
|
||||
// window.opener. A DocGroup is a member of exactly one TabGroup.
|
||||
|
||||
class DocGroup;
|
||||
class BrowserChild;
|
||||
|
||||
class TabGroup final : public SchedulerGroup,
|
||||
public LinkedListElement<TabGroup> {
|
||||
private:
|
||||
class HashEntry : public nsCStringHashKey {
|
||||
public:
|
||||
// NOTE: Weak reference. The DocGroup destructor removes itself from its
|
||||
// owning TabGroup.
|
||||
DocGroup* mDocGroup;
|
||||
explicit HashEntry(const nsACString* aKey);
|
||||
};
|
||||
|
||||
typedef nsTHashtable<HashEntry> DocGroupMap;
|
||||
|
||||
public:
|
||||
typedef DocGroupMap::Iterator Iterator;
|
||||
|
||||
friend class DocGroup;
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TabGroup, override)
|
||||
|
||||
static TabGroup* GetChromeTabGroup();
|
||||
|
||||
// Checks if the BrowserChild already has a TabGroup assigned to it in
|
||||
// IPDL. Returns this TabGroup if it does. This could happen if the parent
|
||||
// process created the PBrowser and we needed to assign a TabGroup immediately
|
||||
// upon receiving the IPDL message. This method is main thread only.
|
||||
static TabGroup* GetFromActor(BrowserChild* aBrowserChild);
|
||||
|
||||
static TabGroup* GetFromWindow(mozIDOMWindowProxy* aWindow);
|
||||
|
||||
explicit TabGroup(bool aIsChrome = false);
|
||||
|
||||
// Get the docgroup for the corresponding doc group key.
|
||||
// Returns null if the given key hasn't been seen yet.
|
||||
already_AddRefed<DocGroup> GetDocGroup(const nsACString& aKey);
|
||||
|
||||
already_AddRefed<DocGroup> AddDocument(const nsACString& aKey,
|
||||
Document* aDocument);
|
||||
|
||||
// Join the specified TabGroup, returning a reference to it. If aTabGroup is
|
||||
// nullptr, create a new tabgroup to join.
|
||||
static already_AddRefed<TabGroup> Join(nsPIDOMWindowOuter* aWindow,
|
||||
TabGroup* aTabGroup);
|
||||
|
||||
void Leave(nsPIDOMWindowOuter* aWindow);
|
||||
|
||||
void MaybeDestroy();
|
||||
|
||||
Iterator Iter() { return mDocGroups.Iter(); }
|
||||
|
||||
const nsTArray<nsPIDOMWindowOuter*>& GetWindows() { return mWindows; }
|
||||
|
||||
// This method is always safe to call off the main thread. The nsIEventTarget
|
||||
// can always be used off the main thread.
|
||||
nsISerialEventTarget* EventTargetFor(TaskCategory aCategory) const override;
|
||||
|
||||
static LinkedList<TabGroup>* GetTabGroupList() { return sTabGroups; }
|
||||
|
||||
private:
|
||||
virtual AbstractThread* AbstractMainThreadForImpl(
|
||||
TaskCategory aCategory) override;
|
||||
|
||||
TabGroup* AsTabGroup() override { return this; }
|
||||
|
||||
void EnsureThrottledEventQueues();
|
||||
|
||||
~TabGroup();
|
||||
|
||||
// Thread-safe members
|
||||
Atomic<bool> mLastWindowLeft;
|
||||
Atomic<bool> mThrottledQueuesInitialized;
|
||||
const bool mIsChrome;
|
||||
|
||||
// Main thread only
|
||||
DocGroupMap mDocGroups;
|
||||
nsTArray<nsPIDOMWindowOuter*> mWindows;
|
||||
|
||||
static LinkedList<TabGroup>* sTabGroups;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // defined(TabGroup_h)
|
@ -16,7 +16,6 @@
|
||||
#include "nsINamed.h"
|
||||
#include "mozilla/dom/DocGroup.h"
|
||||
#include "mozilla/dom/PopupBlocker.h"
|
||||
#include "mozilla/dom/TabGroup.h"
|
||||
#include "mozilla/dom/TimeoutHandler.h"
|
||||
#include "TimeoutExecutor.h"
|
||||
#include "TimeoutBudgetManager.h"
|
||||
@ -1343,5 +1342,5 @@ void TimeoutManager::EndSyncOperation() {
|
||||
}
|
||||
|
||||
nsIEventTarget* TimeoutManager::EventTarget() {
|
||||
return mWindow.EventTargetFor(TaskCategory::Timer);
|
||||
return mWindow.GetBrowsingContextGroup()->GetTimerEventQueue();
|
||||
}
|
||||
|
@ -241,7 +241,6 @@ EXPORTS.mozilla.dom += [
|
||||
'StyleSheetList.h',
|
||||
'SubtleCrypto.h',
|
||||
'SyncMessageSender.h',
|
||||
'TabGroup.h',
|
||||
'Text.h',
|
||||
'Timeout.h',
|
||||
'TimeoutHandler.h',
|
||||
@ -412,7 +411,6 @@ UNIFIED_SOURCES += [
|
||||
'StyledRange.cpp',
|
||||
'StyleSheetList.cpp',
|
||||
'SubtleCrypto.cpp',
|
||||
'TabGroup.cpp',
|
||||
'Text.cpp',
|
||||
'TextInputProcessor.cpp',
|
||||
'ThirdPartyUtil.cpp',
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include "nsContentUtils.h"
|
||||
#include "mozilla/dom/nsMixedContentBlocker.h"
|
||||
#include "nsIContentSecurityPolicy.h"
|
||||
#include "mozilla/dom/TabGroup.h"
|
||||
#include "mozilla/TaskCategory.h"
|
||||
|
||||
class nsIDOMWindow;
|
||||
|
@ -244,7 +244,6 @@
|
||||
#include "mozilla/BloomFilter.h"
|
||||
#include "BrowserChild.h"
|
||||
#include "mozilla/dom/DocGroup.h"
|
||||
#include "mozilla/dom/TabGroup.h"
|
||||
#include "nsIWebNavigationInfo.h"
|
||||
#include "nsPluginHost.h"
|
||||
#include "nsIBrowser.h"
|
||||
@ -9874,21 +9873,7 @@ already_AddRefed<nsISerialEventTarget> nsContentUtils::GetEventTargetByLoadInfo(
|
||||
target = group->EventTargetFor(aCategory);
|
||||
}
|
||||
} else {
|
||||
// There's no document yet, but this might be a top-level load where we can
|
||||
// find a TabGroup.
|
||||
uint64_t outerWindowId;
|
||||
if (NS_FAILED(aLoadInfo->GetOuterWindowID(&outerWindowId))) {
|
||||
// No window. This might be an add-on XHR, a service worker request, or
|
||||
// something else.
|
||||
return nullptr;
|
||||
}
|
||||
RefPtr<nsGlobalWindowOuter> window =
|
||||
nsGlobalWindowOuter::GetOuterWindowWithId(outerWindowId);
|
||||
if (!window) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
target = window->TabGroup()->EventTargetFor(aCategory);
|
||||
target = GetMainThreadSerialEventTarget();
|
||||
}
|
||||
|
||||
return target.forget();
|
||||
|
@ -2472,27 +2472,24 @@ uint32_t nsFrameLoader::LazyHeight() const {
|
||||
return lazyHeight;
|
||||
}
|
||||
|
||||
static Tuple<ContentParent*, BrowserParent*> GetContentParent(
|
||||
Element* aBrowser) {
|
||||
using ReturnTuple = Tuple<ContentParent*, BrowserParent*>;
|
||||
|
||||
static ContentParent* GetContentParent(Element* aBrowser) {
|
||||
nsCOMPtr<nsIBrowser> browser = aBrowser ? aBrowser->AsBrowser() : nullptr;
|
||||
if (!browser) {
|
||||
return ReturnTuple(nullptr, nullptr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<nsFrameLoader> otherLoader;
|
||||
browser->GetSameProcessAsFrameLoader(getter_AddRefs(otherLoader));
|
||||
if (!otherLoader) {
|
||||
return ReturnTuple(nullptr, nullptr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BrowserParent* browserParent = BrowserParent::GetFrom(otherLoader);
|
||||
if (browserParent && browserParent->Manager()) {
|
||||
return MakeTuple(browserParent->Manager(), browserParent);
|
||||
if (browserParent) {
|
||||
return browserParent->Manager();
|
||||
}
|
||||
|
||||
return ReturnTuple(nullptr, nullptr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool nsFrameLoader::EnsureRemoteBrowser() {
|
||||
@ -2597,21 +2594,7 @@ bool nsFrameLoader::TryRemoteBrowserInternal() {
|
||||
}
|
||||
|
||||
// Try to get the related content parent from our browser element.
|
||||
Tie(openerContentParent, sameTabGroupAs) = GetContentParent(mOwnerContent);
|
||||
// If we have an opener, it may be in the same process as our new child, and
|
||||
// therefore needs to be in the same tab group. The long term solution to
|
||||
// this problem is to get rid of TabGroups entirely. In the short term, the
|
||||
// following hack deals with the specific problem that when a window has an
|
||||
// opener, it asserts that its BrowserChild is bound to the same tab group
|
||||
// as its opener. There are likely other mismatches that it does not handle,
|
||||
// but those will all be fixed by the removal of TabGroups.
|
||||
if (RefPtr<BrowsingContext> openerBC =
|
||||
mPendingBrowsingContext->GetOpener()) {
|
||||
auto global = openerBC->Canonical()->GetCurrentWindowGlobal();
|
||||
if (global) {
|
||||
sameTabGroupAs = global->GetBrowserParent();
|
||||
}
|
||||
}
|
||||
openerContentParent = GetContentParent(mOwnerContent);
|
||||
}
|
||||
|
||||
uint32_t chromeFlags = 0;
|
||||
@ -2656,7 +2639,7 @@ bool nsFrameLoader::TryRemoteBrowserInternal() {
|
||||
|
||||
mRemoteBrowser = ContentParent::CreateBrowser(
|
||||
context, ownerElement, mRemoteType, mPendingBrowsingContext,
|
||||
openerContentParent, sameTabGroupAs, nextRemoteTabId);
|
||||
openerContentParent, nextRemoteTabId);
|
||||
if (!mRemoteBrowser) {
|
||||
return false;
|
||||
}
|
||||
|
@ -111,7 +111,6 @@
|
||||
#include "nsCharTraits.h" // NS_IS_HIGH/LOW_SURROGATE
|
||||
#include "PostMessageEvent.h"
|
||||
#include "mozilla/dom/DocGroup.h"
|
||||
#include "mozilla/dom/TabGroup.h"
|
||||
#include "mozilla/StaticPrefs_dom.h"
|
||||
#include "PaintWorkletImpl.h"
|
||||
|
||||
@ -7089,46 +7088,6 @@ already_AddRefed<Promise> nsGlobalWindowInner::CreateImageBitmap(
|
||||
Some(gfx::IntRect(aSx, aSy, aSw, aSh)), aRv);
|
||||
}
|
||||
|
||||
mozilla::dom::TabGroup* nsGlobalWindowInner::MaybeTabGroupInner() {
|
||||
// If we don't have a TabGroup yet, try to get it from the outer window and
|
||||
// cache it.
|
||||
if (!mTabGroup) {
|
||||
nsGlobalWindowOuter* outer = GetOuterWindowInternal();
|
||||
if (!outer) {
|
||||
return nullptr;
|
||||
}
|
||||
mTabGroup = outer->MaybeTabGroup();
|
||||
if (!mTabGroup) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
nsGlobalWindowOuter* outer = GetOuterWindowInternal();
|
||||
MOZ_ASSERT_IF(outer, outer->TabGroup() == mTabGroup);
|
||||
#endif
|
||||
|
||||
return mTabGroup;
|
||||
}
|
||||
|
||||
mozilla::dom::TabGroup* nsGlobalWindowInner::TabGroupInner() {
|
||||
// This will never be called without either an outer window, or a cached tab
|
||||
// group. This is because of the following:
|
||||
// * This method is only called on inner windows
|
||||
// * This method is called as a document is attached to its script global
|
||||
// by the document
|
||||
// * Inner windows are created in nsGlobalWindowInner::SetNewDocument, which
|
||||
// immediately sets a document, which will call this method, causing
|
||||
// the TabGroup to be cached.
|
||||
MOZ_RELEASE_ASSERT(
|
||||
mTabGroup || GetOuterWindowInternal(),
|
||||
"Inner window without outer window has no cached tab group!");
|
||||
|
||||
mozilla::dom::TabGroup* tabGroup = MaybeTabGroupInner();
|
||||
MOZ_RELEASE_ASSERT(tabGroup);
|
||||
return tabGroup;
|
||||
}
|
||||
|
||||
nsresult nsGlobalWindowInner::Dispatch(
|
||||
TaskCategory aCategory, already_AddRefed<nsIRunnable>&& aRunnable) {
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
@ -7252,14 +7211,6 @@ void nsGlobalWindowInner::StorageAccessGranted() {
|
||||
}
|
||||
}
|
||||
|
||||
mozilla::dom::TabGroup* nsPIDOMWindowInner::TabGroup() {
|
||||
return nsGlobalWindowInner::Cast(this)->TabGroupInner();
|
||||
}
|
||||
|
||||
mozilla::dom::TabGroup* nsPIDOMWindowInner::MaybeTabGroup() {
|
||||
return nsGlobalWindowInner::Cast(this)->MaybeTabGroupInner();
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<nsGlobalWindowInner> nsGlobalWindowInner::Create(
|
||||
nsGlobalWindowOuter* aOuterWindow, bool aIsChrome,
|
||||
|
@ -122,7 +122,6 @@ class RequestOrUSVString;
|
||||
class SharedWorker;
|
||||
class Selection;
|
||||
class SpeechSynthesis;
|
||||
class TabGroup;
|
||||
class Timeout;
|
||||
class U2F;
|
||||
class VisualViewport;
|
||||
@ -1180,12 +1179,6 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
||||
friend class nsPIDOMWindowInner;
|
||||
friend class nsPIDOMWindowOuter;
|
||||
|
||||
mozilla::dom::TabGroup* TabGroupInner();
|
||||
|
||||
// Like TabGroupInner, but it is more tolerant of being called at peculiar
|
||||
// times, and it can return null.
|
||||
mozilla::dom::TabGroup* MaybeTabGroupInner();
|
||||
|
||||
bool IsBackgroundInternal() const;
|
||||
|
||||
// NOTE: Chrome Only
|
||||
|
@ -109,7 +109,6 @@
|
||||
#include "nsCharTraits.h" // NS_IS_HIGH/LOW_SURROGATE
|
||||
#include "PostMessageEvent.h"
|
||||
#include "mozilla/dom/DocGroup.h"
|
||||
#include "mozilla/dom/TabGroup.h"
|
||||
#include "mozilla/net/CookieJarSettings.h"
|
||||
|
||||
// Interfaces Needed
|
||||
@ -1333,9 +1332,6 @@ nsGlobalWindowOuter::nsGlobalWindowOuter(uint64_t aWindowID)
|
||||
mSetOpenerWindowCalled(false),
|
||||
#endif
|
||||
mCleanedUp(false),
|
||||
#ifdef DEBUG
|
||||
mIsValidatingTabGroup(false),
|
||||
#endif
|
||||
mCanSkipCCGeneration(0),
|
||||
mAutoActivateVRDisplayID(0) {
|
||||
AssertIsOnMainThread();
|
||||
@ -1465,10 +1461,6 @@ nsGlobalWindowOuter::~nsGlobalWindowOuter() {
|
||||
|
||||
DropOuterWindowDocs();
|
||||
|
||||
if (mTabGroup) {
|
||||
mTabGroup->Leave(this);
|
||||
}
|
||||
|
||||
// Outer windows are always supposed to call CleanUp before letting themselves
|
||||
// be destroyed.
|
||||
MOZ_ASSERT(mCleanedUp);
|
||||
@ -2378,8 +2370,6 @@ nsresult nsGlobalWindowOuter::SetNewDocument(Document* aDocument,
|
||||
}
|
||||
|
||||
aDocument->SetScriptGlobalObject(newInnerWindow);
|
||||
MOZ_ASSERT(newInnerWindow->mTabGroup,
|
||||
"We must have a TabGroup cached at this point");
|
||||
|
||||
MOZ_RELEASE_ASSERT(newInnerWindow->mDoc == aDocument);
|
||||
|
||||
@ -2438,16 +2428,6 @@ nsresult nsGlobalWindowOuter::SetNewDocument(Document* aDocument,
|
||||
}
|
||||
currentInner = nullptr;
|
||||
|
||||
// Ask the JS engine to assert that it's valid to access our DocGroup whenever
|
||||
// it runs JS code for this realm. We skip the check if this window is for
|
||||
// chrome JS or an add-on.
|
||||
nsCOMPtr<nsIPrincipal> principal = mDoc->NodePrincipal();
|
||||
if (GetDocGroup() && !principal->IsSystemPrincipal() &&
|
||||
!BasePrincipal::Cast(principal)->AddonPolicy()) {
|
||||
js::SetRealmValidAccessPtr(
|
||||
cx, newInnerGlobal, newInnerWindow->GetDocGroup()->GetValidAccessPtr());
|
||||
}
|
||||
|
||||
// We wait to fire the debugger hook until the window is all set up and hooked
|
||||
// up with the outer. See bug 969156.
|
||||
if (createdInnerWindow) {
|
||||
@ -2659,11 +2639,10 @@ void nsGlobalWindowOuter::SetDocShell(nsDocShell* aDocShell) {
|
||||
mDocShell = aDocShell;
|
||||
mBrowsingContext = aDocShell->GetBrowsingContext();
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> parentWindow =
|
||||
GetInProcessScriptableParentOrNull();
|
||||
MOZ_RELEASE_ASSERT(!parentWindow || !mTabGroup ||
|
||||
mTabGroup ==
|
||||
nsGlobalWindowOuter::Cast(parentWindow)->mTabGroup);
|
||||
RefPtr<BrowsingContext> parentContext = mBrowsingContext->GetParent();
|
||||
|
||||
MOZ_RELEASE_ASSERT(!parentContext ||
|
||||
GetBrowsingContextGroup() == parentContext->Group());
|
||||
|
||||
mTopLevelOuterContentWindow =
|
||||
!mIsChrome && GetInProcessScriptableTopInternal() == this;
|
||||
@ -3148,6 +3127,11 @@ bool nsPIDOMWindowOuter::GetServiceWorkersTestingEnabled() {
|
||||
return topWindow->mServiceWorkersTestingEnabled;
|
||||
}
|
||||
|
||||
mozilla::dom::BrowsingContextGroup*
|
||||
nsPIDOMWindowOuter::GetBrowsingContextGroup() const {
|
||||
return mBrowsingContext ? mBrowsingContext->Group() : nullptr;
|
||||
}
|
||||
|
||||
Nullable<WindowProxyHolder> nsGlobalWindowOuter::GetParentOuter() {
|
||||
BrowsingContext* bc = GetBrowsingContext();
|
||||
return bc ? bc->GetParent(IgnoreErrors()) : nullptr;
|
||||
@ -7618,86 +7602,6 @@ void nsGlobalWindowOuter::CheckForDPIChange() {
|
||||
}
|
||||
}
|
||||
|
||||
mozilla::dom::TabGroup* nsGlobalWindowOuter::MaybeTabGroupOuter() {
|
||||
// Outer windows lazily join TabGroups when requested. This is usually done
|
||||
// because a document is getting its NodePrincipal, and asking for the
|
||||
// TabGroup to determine its DocGroup.
|
||||
if (!mTabGroup) {
|
||||
// Get the opener ourselves, instead of relying on GetOpenerWindowOuter,
|
||||
// because that way we dodge the LegacyIsCallerChromeOrNativeCode() call
|
||||
// which we want to return false.
|
||||
if (!GetBrowsingContext()) {
|
||||
return nullptr;
|
||||
}
|
||||
RefPtr<BrowsingContext> openerBC = GetBrowsingContext()->GetOpener();
|
||||
nsPIDOMWindowOuter* opener = openerBC ? openerBC->GetDOMWindow() : nullptr;
|
||||
nsPIDOMWindowOuter* parent = GetInProcessScriptableParentOrNull();
|
||||
MOZ_ASSERT(!parent || !opener,
|
||||
"Only one of parent and opener may be provided");
|
||||
|
||||
mozilla::dom::TabGroup* toJoin = nullptr;
|
||||
if (!GetDocShell()) {
|
||||
return nullptr;
|
||||
}
|
||||
if (GetDocShell()->ItemType() == nsIDocShellTreeItem::typeChrome) {
|
||||
toJoin = TabGroup::GetChromeTabGroup();
|
||||
} else if (opener) {
|
||||
toJoin = opener->TabGroup();
|
||||
} else if (parent) {
|
||||
toJoin = parent->TabGroup();
|
||||
} else {
|
||||
toJoin = TabGroup::GetFromWindow(this);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// Make sure that, if we have a tab group from the actor, it matches the one
|
||||
// we're planning to join.
|
||||
mozilla::dom::TabGroup* testGroup = TabGroup::GetFromWindow(this);
|
||||
MOZ_ASSERT_IF(testGroup, testGroup == toJoin);
|
||||
#endif
|
||||
|
||||
mTabGroup = mozilla::dom::TabGroup::Join(this, toJoin);
|
||||
}
|
||||
MOZ_ASSERT(mTabGroup);
|
||||
|
||||
#ifdef DEBUG
|
||||
// Ensure that we don't recurse forever
|
||||
if (!mIsValidatingTabGroup) {
|
||||
mIsValidatingTabGroup = true;
|
||||
// We only need to do this check if we aren't in the chrome tab group
|
||||
if (mIsChrome) {
|
||||
MOZ_ASSERT(mTabGroup == TabGroup::GetChromeTabGroup());
|
||||
} else {
|
||||
// Sanity check that our tabgroup matches our opener or parent.
|
||||
RefPtr<nsPIDOMWindowOuter> parent = GetInProcessScriptableParentOrNull();
|
||||
MOZ_ASSERT_IF(parent, parent->TabGroup() == mTabGroup);
|
||||
|
||||
RefPtr<BrowsingContext> openerBC = GetBrowsingContext()->GetOpener();
|
||||
nsPIDOMWindowOuter* opener =
|
||||
openerBC ? openerBC->GetDOMWindow() : nullptr;
|
||||
// For the case that a page A (foo.com) contains an iframe B (bar.com) and
|
||||
// B contains an iframe C (foo.com), it can not guarantee that A and C are
|
||||
// in same tabgroup in Fission mode. And if C reference back to A via
|
||||
// window.open, we hit this assertion. Ignore this assertion in Fission
|
||||
// given that tabgroup eventually will be removed after bug 1561715.
|
||||
MOZ_ASSERT_IF(mDocShell &&
|
||||
!nsDocShell::Cast(mDocShell)->UseRemoteSubframes() &&
|
||||
opener && Cast(opener) != this,
|
||||
opener->TabGroup() == mTabGroup);
|
||||
}
|
||||
mIsValidatingTabGroup = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return mTabGroup;
|
||||
}
|
||||
|
||||
mozilla::dom::TabGroup* nsGlobalWindowOuter::TabGroupOuter() {
|
||||
mozilla::dom::TabGroup* tabGroup = MaybeTabGroupOuter();
|
||||
MOZ_RELEASE_ASSERT(tabGroup);
|
||||
return tabGroup;
|
||||
}
|
||||
|
||||
nsresult nsGlobalWindowOuter::Dispatch(
|
||||
TaskCategory aCategory, already_AddRefed<nsIRunnable>&& aRunnable) {
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
@ -7756,14 +7660,6 @@ nsGlobalWindowOuter::TemporarilyDisableDialogs::~TemporarilyDisableDialogs() {
|
||||
}
|
||||
}
|
||||
|
||||
mozilla::dom::TabGroup* nsPIDOMWindowOuter::TabGroup() {
|
||||
return nsGlobalWindowOuter::Cast(this)->TabGroupOuter();
|
||||
}
|
||||
|
||||
mozilla::dom::TabGroup* nsPIDOMWindowOuter::MaybeTabGroup() {
|
||||
return nsGlobalWindowOuter::Cast(this)->MaybeTabGroupOuter();
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<nsGlobalWindowOuter> nsGlobalWindowOuter::Create(
|
||||
nsDocShell* aDocShell, bool aIsChrome) {
|
||||
|
@ -110,7 +110,6 @@ struct RequestInit;
|
||||
class RequestOrUSVString;
|
||||
class Selection;
|
||||
class SpeechSynthesis;
|
||||
class TabGroup;
|
||||
class Timeout;
|
||||
class U2F;
|
||||
class VRDisplay;
|
||||
@ -1037,12 +1036,6 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
|
||||
friend class nsPIDOMWindowInner;
|
||||
friend class nsPIDOMWindowOuter;
|
||||
|
||||
mozilla::dom::TabGroup* TabGroupOuter();
|
||||
|
||||
// Like TabGroupOuter, but it is more tolerant of being called at peculiar
|
||||
// times, and it can return null.
|
||||
mozilla::dom::TabGroup* MaybeTabGroupOuter();
|
||||
|
||||
void SetIsBackgroundInternal(bool aIsBackground);
|
||||
|
||||
nsresult GetInterfaceInternal(const nsIID& aIID, void** aSink);
|
||||
@ -1124,12 +1117,6 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
|
||||
// mSuspendedDoc is responsible for unsuspending it.
|
||||
RefPtr<Document> mSuspendedDoc;
|
||||
|
||||
#ifdef DEBUG
|
||||
// This member is used in the debug only assertions in TabGroup()
|
||||
// to catch cyclic parent/opener trees and not overflow the stack.
|
||||
bool mIsValidatingTabGroup;
|
||||
#endif
|
||||
|
||||
// This is the CC generation the last time we called CanSkip.
|
||||
uint32_t mCanSkipCCGeneration;
|
||||
|
||||
|
@ -57,7 +57,6 @@ class ClientState;
|
||||
class ContentFrameMessageManager;
|
||||
class DocGroup;
|
||||
class Document;
|
||||
class TabGroup;
|
||||
class Element;
|
||||
class Navigator;
|
||||
class Performance;
|
||||
@ -314,7 +313,7 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
|
||||
void TryToCacheTopInnerWindow();
|
||||
|
||||
// Increase/Decrease the number of active IndexedDB databases for the
|
||||
// decision making of TabGroup scheduling and timeout-throttling.
|
||||
// decision making of timeout-throttling.
|
||||
void UpdateActiveIndexedDBDatabaseCount(int32_t aDelta);
|
||||
|
||||
// Return true if there is any active IndexedDB databases which could block
|
||||
@ -340,12 +339,6 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
|
||||
|
||||
void NoteDOMContentLoaded();
|
||||
|
||||
mozilla::dom::TabGroup* TabGroup();
|
||||
|
||||
// Like MaybeTabGroup, but it is more tolerant of being called at peculiar
|
||||
// times, and it can return null.
|
||||
mozilla::dom::TabGroup* MaybeTabGroup();
|
||||
|
||||
virtual mozilla::dom::CustomElementRegistry* CustomElements() = 0;
|
||||
|
||||
// XXX: This is called on inner windows
|
||||
@ -639,8 +632,6 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
|
||||
// The AudioContexts created for the current document, if any.
|
||||
nsTArray<mozilla::dom::AudioContext*> mAudioContexts; // Weak
|
||||
|
||||
RefPtr<mozilla::dom::TabGroup> mTabGroup;
|
||||
|
||||
RefPtr<mozilla::dom::BrowsingContext> mBrowsingContext;
|
||||
|
||||
// A unique (as long as our 64-bit counter doesn't roll over) id for
|
||||
@ -769,12 +760,6 @@ class nsPIDOMWindowOuter : public mozIDOMWindowProxy {
|
||||
bool IsTopLevelWindow();
|
||||
bool HadOriginalOpener() const;
|
||||
|
||||
mozilla::dom::TabGroup* TabGroup();
|
||||
|
||||
// Like MaybeTabGroup, but it is more tolerant of being called at peculiar
|
||||
// times, and it can return null.
|
||||
mozilla::dom::TabGroup* MaybeTabGroup();
|
||||
|
||||
virtual nsPIDOMWindowOuter* GetPrivateRoot() = 0;
|
||||
|
||||
virtual void ActivateOrDeactivate(bool aActivate) = 0;
|
||||
@ -875,6 +860,11 @@ class nsPIDOMWindowOuter : public mozIDOMWindowProxy {
|
||||
*/
|
||||
inline mozilla::dom::BrowsingContext* GetBrowsingContext() const;
|
||||
|
||||
/**
|
||||
* Get the browsing context group this window belongs to.
|
||||
*/
|
||||
mozilla::dom::BrowsingContextGroup* GetBrowsingContextGroup() const;
|
||||
|
||||
/**
|
||||
* Set a new document in the window. Calling this method will in most cases
|
||||
* create a new inner window. This may be called with a pointer to the current
|
||||
@ -1139,8 +1129,6 @@ class nsPIDOMWindowOuter : public mozIDOMWindowProxy {
|
||||
// And these are the references between inner and outer windows.
|
||||
nsPIDOMWindowInner* MOZ_NON_OWNING_REF mInnerWindow;
|
||||
|
||||
RefPtr<mozilla::dom::TabGroup> mTabGroup;
|
||||
|
||||
// A unique (as long as our 64-bit counter doesn't roll over) id for
|
||||
// this window.
|
||||
uint64_t mWindowID;
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include "FetchStreamReader.h"
|
||||
#include "InternalResponse.h"
|
||||
#include "mozilla/dom/PromiseBinding.h"
|
||||
#include "mozilla/SystemGroup.h"
|
||||
#include "mozilla/TaskCategory.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIScriptError.h"
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/SystemGroup.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "mozilla/dom/IDBFactoryBinding.h"
|
||||
#include "mozilla/dom/quota/QuotaManager.h"
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include "js/StructuredClone.h"
|
||||
#include "mozilla/EndianUtils.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/SystemGroup.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/BlobBinding.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
|
@ -86,7 +86,7 @@ nsresult BrowserBridgeParent::InitWithProcess(
|
||||
|
||||
// Tell the content process to set up its PBrowserChild.
|
||||
bool ok = aContentParent->SendConstructBrowser(
|
||||
std::move(childEp), std::move(windowChildEp), aTabId, TabId(0),
|
||||
std::move(childEp), std::move(windowChildEp), aTabId,
|
||||
tabContext.AsIPCTabContext(), aWindowInit, aChromeFlags,
|
||||
aContentParent->ChildID(), aContentParent->IsForBrowser(),
|
||||
/* aIsTopLevel */ false);
|
||||
|
@ -322,24 +322,20 @@ already_AddRefed<BrowserChild> BrowserChild::FindBrowserChild(
|
||||
|
||||
/*static*/
|
||||
already_AddRefed<BrowserChild> BrowserChild::Create(
|
||||
ContentChild* aManager, const TabId& aTabId, const TabId& aSameTabGroupAs,
|
||||
const TabContext& aContext, BrowsingContext* aBrowsingContext,
|
||||
uint32_t aChromeFlags, bool aIsTopLevel) {
|
||||
RefPtr<BrowserChild> groupChild = FindBrowserChild(aSameTabGroupAs);
|
||||
dom::TabGroup* group = groupChild ? groupChild->TabGroup() : nullptr;
|
||||
RefPtr<BrowserChild> iframe =
|
||||
new BrowserChild(aManager, aTabId, group, aContext, aBrowsingContext,
|
||||
aChromeFlags, aIsTopLevel);
|
||||
ContentChild* aManager, const TabId& aTabId, const TabContext& aContext,
|
||||
BrowsingContext* aBrowsingContext, uint32_t aChromeFlags,
|
||||
bool aIsTopLevel) {
|
||||
RefPtr<BrowserChild> iframe = new BrowserChild(
|
||||
aManager, aTabId, aContext, aBrowsingContext, aChromeFlags, aIsTopLevel);
|
||||
return iframe.forget();
|
||||
}
|
||||
|
||||
BrowserChild::BrowserChild(ContentChild* aManager, const TabId& aTabId,
|
||||
dom::TabGroup* aTabGroup, const TabContext& aContext,
|
||||
const TabContext& aContext,
|
||||
BrowsingContext* aBrowsingContext,
|
||||
uint32_t aChromeFlags, bool aIsTopLevel)
|
||||
: TabContext(aContext),
|
||||
mBrowserChildMessageManager(nullptr),
|
||||
mTabGroup(aTabGroup),
|
||||
mManager(aManager),
|
||||
mBrowsingContext(aBrowsingContext),
|
||||
mChromeFlags(aChromeFlags),
|
||||
@ -483,7 +479,6 @@ bool BrowserChild::DoUpdateZoomConstraints(
|
||||
|
||||
nsresult BrowserChild::Init(mozIDOMWindowProxy* aParent,
|
||||
WindowGlobalChild* aInitialWindowChild) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(mTabGroup);
|
||||
MOZ_ASSERT_IF(aInitialWindowChild,
|
||||
aInitialWindowChild->BrowsingContext() == mBrowsingContext);
|
||||
|
||||
@ -517,10 +512,6 @@ nsresult BrowserChild::Init(mozIDOMWindowProxy* aParent,
|
||||
|
||||
mStatusFilter = new nsBrowserStatusFilter();
|
||||
|
||||
RefPtr<nsIEventTarget> eventTarget =
|
||||
TabGroup()->EventTargetFor(TaskCategory::Network);
|
||||
|
||||
mStatusFilter->SetTarget(eventTarget);
|
||||
nsresult rv =
|
||||
mStatusFilter->AddProgressListener(this, nsIWebProgress::NOTIFY_ALL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -930,13 +921,6 @@ BrowserChild::ProvideWindow(mozIDOMWindowProxy* aParent, uint32_t aChromeFlags,
|
||||
void BrowserChild::DestroyWindow() {
|
||||
mBrowsingContext = nullptr;
|
||||
|
||||
// TabGroups contain circular references to their event queues that they break
|
||||
// when the last window leaves. If we never attached a window to our TabGroup,
|
||||
// though, it will never see a window leave, and will therefore never break
|
||||
// its circular references. If it hasn't had a window attached by now, it
|
||||
// never will, so have it destroy itself now if it's empty.
|
||||
mTabGroup->MaybeDestroy();
|
||||
|
||||
if (mStatusFilter) {
|
||||
if (nsCOMPtr<nsIWebProgress> webProgress =
|
||||
do_QueryInterface(WebNavigation())) {
|
||||
@ -3585,8 +3569,6 @@ NS_IMETHODIMP BrowserChild::BeginSendingWebProgressEventsToParent() {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mozilla::dom::TabGroup* BrowserChild::TabGroup() { return mTabGroup; }
|
||||
|
||||
nsresult BrowserChild::GetHasSiblings(bool* aHasSiblings) {
|
||||
*aHasSiblings = mHasSiblings;
|
||||
return NS_OK;
|
||||
@ -4148,24 +4130,15 @@ uint64_t BrowserChildMessageManager::ChromeOuterWindowID() {
|
||||
|
||||
nsresult BrowserChildMessageManager::Dispatch(
|
||||
TaskCategory aCategory, already_AddRefed<nsIRunnable>&& aRunnable) {
|
||||
if (mBrowserChild && mBrowserChild->TabGroup()) {
|
||||
return mBrowserChild->TabGroup()->Dispatch(aCategory, std::move(aRunnable));
|
||||
}
|
||||
return DispatcherTrait::Dispatch(aCategory, std::move(aRunnable));
|
||||
}
|
||||
|
||||
nsISerialEventTarget* BrowserChildMessageManager::EventTargetFor(
|
||||
TaskCategory aCategory) const {
|
||||
if (mBrowserChild && mBrowserChild->TabGroup()) {
|
||||
return mBrowserChild->TabGroup()->EventTargetFor(aCategory);
|
||||
}
|
||||
return DispatcherTrait::EventTargetFor(aCategory);
|
||||
}
|
||||
|
||||
AbstractThread* BrowserChildMessageManager::AbstractMainThreadFor(
|
||||
TaskCategory aCategory) {
|
||||
if (mBrowserChild && mBrowserChild->TabGroup()) {
|
||||
return mBrowserChild->TabGroup()->AbstractMainThreadFor(aCategory);
|
||||
}
|
||||
return DispatcherTrait::AbstractMainThreadFor(aCategory);
|
||||
}
|
||||
|
@ -75,6 +75,7 @@ struct AutoCacheNativeKeyCommands;
|
||||
namespace dom {
|
||||
|
||||
class BrowserChild;
|
||||
class BrowsingContext;
|
||||
class TabGroup;
|
||||
class ClonedMessageData;
|
||||
class CoalescedMouseData;
|
||||
@ -183,18 +184,19 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
|
||||
/**
|
||||
* Create a new BrowserChild object.
|
||||
*/
|
||||
BrowserChild(ContentChild* aManager, const TabId& aTabId, TabGroup* aTabGroup,
|
||||
const TabContext& aContext, BrowsingContext* aBrowsingContext,
|
||||
uint32_t aChromeFlags, bool aIsTopLevel);
|
||||
BrowserChild(ContentChild* aManager, const TabId& aTabId,
|
||||
const TabContext& aContext,
|
||||
dom::BrowsingContext* aBrowsingContext, uint32_t aChromeFlags,
|
||||
bool aIsTopLevel);
|
||||
|
||||
nsresult Init(mozIDOMWindowProxy* aParent,
|
||||
WindowGlobalChild* aInitialWindowChild);
|
||||
|
||||
/** Return a BrowserChild with the given attributes. */
|
||||
static already_AddRefed<BrowserChild> Create(
|
||||
ContentChild* aManager, const TabId& aTabId, const TabId& aSameTabGroupAs,
|
||||
const TabContext& aContext, BrowsingContext* aBrowsingContext,
|
||||
uint32_t aChromeFlags, bool aIsTopLevel);
|
||||
ContentChild* aManager, const TabId& aTabId, const TabContext& aContext,
|
||||
BrowsingContext* aBrowsingContext, uint32_t aChromeFlags,
|
||||
bool aIsTopLevel);
|
||||
|
||||
// Let managees query if it is safe to send messages.
|
||||
bool IsDestroyed() const { return mDestroyed; }
|
||||
@ -630,7 +632,7 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
|
||||
bool StopAwaitingLargeAlloc();
|
||||
bool IsAwaitingLargeAlloc();
|
||||
|
||||
mozilla::dom::TabGroup* TabGroup();
|
||||
BrowsingContext* GetBrowsingContext() const { return mBrowsingContext; }
|
||||
|
||||
#if defined(ACCESSIBILITY)
|
||||
void SetTopLevelDocAccessibleChild(PDocAccessibleChild* aTopLevelChild) {
|
||||
@ -842,7 +844,6 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
|
||||
TextureFactoryIdentifier mTextureFactoryIdentifier;
|
||||
RefPtr<nsWebBrowser> mWebBrowser;
|
||||
nsCOMPtr<nsIWebNavigation> mWebNav;
|
||||
RefPtr<mozilla::dom::TabGroup> mTabGroup;
|
||||
RefPtr<PuppetWidget> mPuppetWidget;
|
||||
nsCOMPtr<nsIURI> mLastURI;
|
||||
RefPtr<ContentChild> mManager;
|
||||
|
@ -59,7 +59,6 @@
|
||||
#include "mozilla/dom/ServiceWorkerManager.h"
|
||||
#include "mozilla/dom/SHEntryChild.h"
|
||||
#include "mozilla/dom/SHistoryChild.h"
|
||||
#include "mozilla/dom/TabGroup.h"
|
||||
#include "mozilla/dom/URLClassifierChild.h"
|
||||
#include "mozilla/dom/WindowGlobalChild.h"
|
||||
#include "mozilla/dom/WorkerDebugger.h"
|
||||
@ -969,16 +968,11 @@ nsresult ContentChild::ProvideWindowCommon(
|
||||
// We need to assign a TabGroup to the PBrowser actor before we send it to the
|
||||
// parent. Otherwise, the parent could send messages to us before we have a
|
||||
// proper TabGroup for that actor.
|
||||
RefPtr<TabGroup> tabGroup;
|
||||
RefPtr<BrowsingContext> openerBC;
|
||||
if (aTabOpener && !aForceNoOpener) {
|
||||
// The new actor will use the same tab group as the opener.
|
||||
tabGroup = aTabOpener->TabGroup();
|
||||
if (aParent) {
|
||||
openerBC = nsPIDOMWindowOuter::From(aParent)->GetBrowsingContext();
|
||||
}
|
||||
} else {
|
||||
tabGroup = new TabGroup();
|
||||
}
|
||||
|
||||
RefPtr<BrowsingContext> browsingContext = BrowsingContext::Create(
|
||||
@ -1006,7 +1000,7 @@ nsresult ContentChild::ProvideWindowCommon(
|
||||
|
||||
auto windowChild = MakeRefPtr<WindowGlobalChild>(windowInit, nullptr);
|
||||
|
||||
auto newChild = MakeRefPtr<BrowserChild>(this, tabId, tabGroup, newTabContext,
|
||||
auto newChild = MakeRefPtr<BrowserChild>(this, tabId, newTabContext,
|
||||
browsingContext, aChromeFlags,
|
||||
/* aIsTopLevel */ true);
|
||||
|
||||
@ -1756,10 +1750,9 @@ bool ContentChild::DeallocPJavaScriptChild(PJavaScriptChild* aChild) {
|
||||
mozilla::ipc::IPCResult ContentChild::RecvConstructBrowser(
|
||||
ManagedEndpoint<PBrowserChild>&& aBrowserEp,
|
||||
ManagedEndpoint<PWindowGlobalChild>&& aWindowEp, const TabId& aTabId,
|
||||
const TabId& aSameTabGroupAs, const IPCTabContext& aContext,
|
||||
const WindowGlobalInit& aWindowInit, const uint32_t& aChromeFlags,
|
||||
const ContentParentId& aCpID, const bool& aIsForBrowser,
|
||||
const bool& aIsTopLevel) {
|
||||
const IPCTabContext& aContext, const WindowGlobalInit& aWindowInit,
|
||||
const uint32_t& aChromeFlags, const ContentParentId& aCpID,
|
||||
const bool& aIsForBrowser, const bool& aIsTopLevel) {
|
||||
MOZ_ASSERT(!IsShuttingDown());
|
||||
|
||||
static bool hasRunOnce = false;
|
||||
@ -1795,8 +1788,8 @@ mozilla::ipc::IPCResult ContentChild::RecvConstructBrowser(
|
||||
auto windowChild = MakeRefPtr<WindowGlobalChild>(aWindowInit, nullptr);
|
||||
|
||||
RefPtr<BrowserChild> browserChild = BrowserChild::Create(
|
||||
this, aTabId, aSameTabGroupAs, tc.GetTabContext(),
|
||||
aWindowInit.browsingContext().get(), aChromeFlags, aIsTopLevel);
|
||||
this, aTabId, tc.GetTabContext(), aWindowInit.browsingContext().get(),
|
||||
aChromeFlags, aIsTopLevel);
|
||||
|
||||
// Bind the created BrowserChild to IPC to actually link the actor.
|
||||
if (NS_WARN_IF(!BindPBrowserEndpoint(std::move(aBrowserEp), browserChild))) {
|
||||
@ -1809,15 +1802,10 @@ mozilla::ipc::IPCResult ContentChild::RecvConstructBrowser(
|
||||
}
|
||||
windowChild->Init();
|
||||
|
||||
// Ensure that a TabGroup is set for our BrowserChild before running `Init`.
|
||||
if (!browserChild->mTabGroup) {
|
||||
browserChild->mTabGroup = TabGroup::GetFromActor(browserChild);
|
||||
|
||||
if (!browserChild->mTabGroup) {
|
||||
browserChild->mTabGroup = new TabGroup();
|
||||
MOZ_DIAGNOSTIC_ASSERT(aSameTabGroupAs != 0);
|
||||
}
|
||||
}
|
||||
// Ensure that a BrowsingContext is set for our BrowserChild before
|
||||
// running `Init`.
|
||||
MOZ_RELEASE_ASSERT(browserChild->mBrowsingContext ==
|
||||
aWindowInit.browsingContext().get());
|
||||
|
||||
if (NS_WARN_IF(
|
||||
NS_FAILED(browserChild->Init(/* aOpener */ nullptr, windowChild)))) {
|
||||
@ -3606,90 +3594,6 @@ mozilla::ipc::IPCResult ContentChild::RecvUpdateSHEntriesInDocShell(
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
already_AddRefed<nsIEventTarget> ContentChild::GetSpecificMessageEventTarget(
|
||||
const Message& aMsg) {
|
||||
switch (aMsg.type()) {
|
||||
// Javascript
|
||||
case PJavaScript::Msg_DropTemporaryStrongReferences__ID:
|
||||
case PJavaScript::Msg_DropObject__ID:
|
||||
|
||||
// Navigation
|
||||
case PContent::Msg_NotifyVisited__ID:
|
||||
|
||||
// Storage API
|
||||
case PContent::Msg_DataStoragePut__ID:
|
||||
case PContent::Msg_DataStorageRemove__ID:
|
||||
case PContent::Msg_DataStorageClear__ID:
|
||||
|
||||
// Blob and BlobURL
|
||||
case PContent::Msg_BlobURLRegistration__ID:
|
||||
case PContent::Msg_BlobURLUnregistration__ID:
|
||||
case PContent::Msg_InitBlobURLs__ID:
|
||||
case PContent::Msg_PIPCBlobInputStreamConstructor__ID:
|
||||
case PContent::Msg_StoreAndBroadcastBlobURLRegistration__ID:
|
||||
|
||||
return do_AddRef(SystemGroup::EventTargetFor(TaskCategory::Other));
|
||||
|
||||
// PBrowserChild Construction
|
||||
case PContent::Msg_ConstructBrowser__ID: {
|
||||
// Deserialize the arguments for this message to get the endpoint and
|
||||
// `sameTabGroupAs`. The endpoint is needed to set up the event target for
|
||||
// our newly created actor, and sameTabGroupAs is needed to determine if
|
||||
// we're going to join an existing TabGroup.
|
||||
ManagedEndpoint<PBrowserChild> endpoint;
|
||||
ManagedEndpoint<PWindowGlobalChild> windowGlobalEndpoint;
|
||||
TabId tabId, sameTabGroupAs;
|
||||
PickleIterator iter(aMsg);
|
||||
if (NS_WARN_IF(!IPC::ReadParam(&aMsg, &iter, &endpoint))) {
|
||||
return nullptr;
|
||||
}
|
||||
aMsg.IgnoreSentinel(&iter);
|
||||
if (NS_WARN_IF(!IPC::ReadParam(&aMsg, &iter, &windowGlobalEndpoint))) {
|
||||
return nullptr;
|
||||
}
|
||||
aMsg.IgnoreSentinel(&iter);
|
||||
if (NS_WARN_IF(!IPC::ReadParam(&aMsg, &iter, &tabId))) {
|
||||
return nullptr;
|
||||
}
|
||||
aMsg.IgnoreSentinel(&iter);
|
||||
if (NS_WARN_IF(!IPC::ReadParam(&aMsg, &iter, &sameTabGroupAs))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// If sameTabGroupAs is non-zero, then the new tab will be in the same
|
||||
// TabGroup as a previously created tab. Rather than try to find the
|
||||
// previously created tab (whose constructor message may not even have
|
||||
// been processed yet, in theory) and look up its event target, we just
|
||||
// use the default event target. This means that runnables for this tab
|
||||
// will not be labeled. However, this path is only taken for print preview
|
||||
// and view source, which are not performance-sensitive.
|
||||
if (sameTabGroupAs) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!endpoint.IsValid())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// If the request for a new BrowserChild is coming from the parent
|
||||
// process, then there is no opener. Therefore, we create a fresh
|
||||
// TabGroup.
|
||||
RefPtr<TabGroup> tabGroup = new TabGroup();
|
||||
nsCOMPtr<nsIEventTarget> target =
|
||||
tabGroup->EventTargetFor(TaskCategory::Other);
|
||||
|
||||
// Set this event target for our newly created entry, and use it for this
|
||||
// message.
|
||||
SetEventTargetForRoute(*endpoint.ActorId(), target);
|
||||
|
||||
return target.forget();
|
||||
}
|
||||
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void ContentChild::OnChannelReceivedMessage(const Message& aMsg) {
|
||||
if (aMsg.is_sync() && !aMsg.is_reply()) {
|
||||
LSObject::OnSyncMessageReceived();
|
||||
|
@ -498,10 +498,9 @@ class ContentChild final
|
||||
mozilla::ipc::IPCResult RecvConstructBrowser(
|
||||
ManagedEndpoint<PBrowserChild>&& aBrowserEp,
|
||||
ManagedEndpoint<PWindowGlobalChild>&& aWindowEp, const TabId& aTabId,
|
||||
const TabId& aSameTabGroupAs, const IPCTabContext& aContext,
|
||||
const WindowGlobalInit& aWindowInit, const uint32_t& aChromeFlags,
|
||||
const ContentParentId& aCpID, const bool& aIsForBrowser,
|
||||
const bool& aIsTopLevel);
|
||||
const IPCTabContext& aContext, const WindowGlobalInit& aWindowInit,
|
||||
const uint32_t& aChromeFlags, const ContentParentId& aCpID,
|
||||
const bool& aIsForBrowser, const bool& aIsTopLevel);
|
||||
|
||||
FORWARD_SHMEM_ALLOCATOR_TO(PContentChild)
|
||||
|
||||
@ -714,9 +713,6 @@ class ContentChild final
|
||||
|
||||
virtual void ProcessingError(Result aCode, const char* aReason) override;
|
||||
|
||||
virtual already_AddRefed<nsIEventTarget> GetSpecificMessageEventTarget(
|
||||
const Message& aMsg) override;
|
||||
|
||||
virtual void OnChannelReceivedMessage(const Message& aMsg) override;
|
||||
|
||||
mozilla::ipc::IPCResult RecvAttachBrowsingContext(
|
||||
|
@ -1192,8 +1192,7 @@ mozilla::ipc::IPCResult ContentParent::RecvLaunchRDDProcess(
|
||||
already_AddRefed<RemoteBrowser> ContentParent::CreateBrowser(
|
||||
const TabContext& aContext, Element* aFrameElement,
|
||||
const nsAString& aRemoteType, BrowsingContext* aBrowsingContext,
|
||||
ContentParent* aOpenerContentParent, BrowserParent* aSameTabGroupAs,
|
||||
uint64_t aNextRemoteTabId) {
|
||||
ContentParent* aOpenerContentParent, uint64_t aNextRemoteTabId) {
|
||||
AUTO_PROFILER_LABEL("ContentParent::CreateBrowser", OTHER);
|
||||
|
||||
if (!sCanLaunchSubprocesses) {
|
||||
@ -1324,7 +1323,6 @@ already_AddRefed<RemoteBrowser> ContentParent::CreateBrowser(
|
||||
// Tell the content process to set up its PBrowserChild.
|
||||
bool ok = constructorSender->SendConstructBrowser(
|
||||
std::move(childEp), std::move(windowEp), tabId,
|
||||
aSameTabGroupAs ? aSameTabGroupAs->GetTabId() : TabId(0),
|
||||
aContext.AsIPCTabContext(), windowInit, chromeFlags,
|
||||
constructorSender->ChildID(), constructorSender->IsForBrowser(),
|
||||
/* aIsTopLevel */ true);
|
||||
|
@ -230,8 +230,7 @@ class ContentParent final
|
||||
static already_AddRefed<RemoteBrowser> CreateBrowser(
|
||||
const TabContext& aContext, Element* aFrameElement,
|
||||
const nsAString& aRemoteType, BrowsingContext* aBrowsingContext,
|
||||
ContentParent* aOpenerContentParent, BrowserParent* aSameTabGroupAs,
|
||||
uint64_t aNextRemoteTabId);
|
||||
ContentParent* aOpenerContentParent, uint64_t aNextRemoteTabId);
|
||||
|
||||
static void GetAll(nsTArray<ContentParent*>& aArray);
|
||||
|
||||
|
@ -428,7 +428,7 @@ parent:
|
||||
child:
|
||||
async ConstructBrowser(ManagedEndpoint<PBrowserChild> browserEp,
|
||||
ManagedEndpoint<PWindowGlobalChild> windowEp,
|
||||
TabId tabId, TabId sameTabGroupAs,
|
||||
TabId tabId,
|
||||
IPCTabContext context,
|
||||
WindowGlobalInit windowInit,
|
||||
uint32_t chromeFlags, ContentParentId cpId,
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "mozilla/SharedThreadPool.h"
|
||||
#include "mozilla/StaticMutex.h"
|
||||
#include "mozilla/StaticPrefs_media.h"
|
||||
#include "mozilla/SystemGroup.h"
|
||||
#include "mozilla/TaskQueue.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "nsAnonymousTemporaryFile.h"
|
||||
#include "nsIThreadManager.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/SystemGroup.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "GMPVideoEncodedFrameImpl.h"
|
||||
#include "GMPVideoi420FrameImpl.h"
|
||||
#include "mozilla/gmp/GMPTypes.h"
|
||||
#include "mozilla/SystemGroup.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsAutoRef.h"
|
||||
#include "nsThread.h"
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
#include "mozilla/LoadInfo.h"
|
||||
#include "mozilla/SchedulerGroup.h"
|
||||
#include "mozilla/StorageAccess.h"
|
||||
#include "mozilla/dom/ClientIPCTypes.h"
|
||||
#include "mozilla/dom/DOMMozPromiseRequestHolder.h"
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include "mozilla/ScopeExit.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/StaticPrefs_dom.h"
|
||||
#include "mozilla/SystemGroup.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/dom/ClientIPCTypes.h"
|
||||
#include "mozilla/dom/DOMTypes.h"
|
||||
|
@ -2247,8 +2247,9 @@ WorkerPrivate::WorkerPrivate(
|
||||
}
|
||||
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
target =
|
||||
GetWindow() ? GetWindow()->EventTargetFor(TaskCategory::Worker) : nullptr;
|
||||
target = GetWindow()
|
||||
? GetWindow()->GetBrowsingContextGroup()->GetWorkerEventQueue()
|
||||
: nullptr;
|
||||
|
||||
if (!target) {
|
||||
target = GetMainThreadSerialEventTarget();
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
#include "mozilla/layers/ProfilerScreenshots.h"
|
||||
|
||||
#include "mozilla/SystemGroup.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
|
||||
#include "GeckoProfiler.h"
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include "mozilla/TouchEvents.h"
|
||||
#include "mozilla/dom/BrowserChild.h"
|
||||
#include "mozilla/dom/MouseEventBinding.h"
|
||||
#include "mozilla/dom/TabGroup.h"
|
||||
#include "mozilla/layers/APZCCallbackHelper.h"
|
||||
#include "mozilla/widget/nsAutoRollup.h"
|
||||
#include "nsCOMPtr.h"
|
||||
@ -184,12 +183,6 @@ void APZEventState::ProcessSingleTap(const CSSPoint& aPoint,
|
||||
|
||||
APZES_LOG("Scheduling timer for click event\n");
|
||||
nsCOMPtr<nsITimer> timer = NS_NewTimer();
|
||||
dom::BrowserChild* browserChild = widget->GetOwningBrowserChild();
|
||||
|
||||
if (browserChild && XRE_IsContentProcess()) {
|
||||
timer->SetTarget(
|
||||
browserChild->TabGroup()->EventTargetFor(TaskCategory::Other));
|
||||
}
|
||||
RefPtr<DelayedFireSingleTapEvent> callback = new DelayedFireSingleTapEvent(
|
||||
mWidget, ldPoint, aModifiers, aClickCount, timer, touchRollup);
|
||||
nsresult rv = timer->InitWithCallback(
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "mozilla/StaticPrefs_gfx.h"
|
||||
#include "mozilla/StaticPrefs_layers.h"
|
||||
#include "mozilla/dom/BrowserChild.h" // for BrowserChild
|
||||
#include "mozilla/dom/TabGroup.h" // for TabGroup
|
||||
#include "mozilla/hal_sandbox/PHal.h" // for ScreenConfiguration
|
||||
#include "mozilla/layers/CompositableClient.h"
|
||||
#include "mozilla/layers/CompositorBridgeChild.h" // for CompositorBridgeChild
|
||||
@ -142,15 +141,6 @@ void ClientLayerManager::Destroy() {
|
||||
mWidget = nullptr;
|
||||
}
|
||||
|
||||
TabGroup* ClientLayerManager::GetTabGroup() {
|
||||
if (mWidget) {
|
||||
if (BrowserChild* browserChild = mWidget->GetOwningBrowserChild()) {
|
||||
return browserChild->TabGroup();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int32_t ClientLayerManager::GetMaxTextureSize() const {
|
||||
return mForwarder->GetMaxTextureSize();
|
||||
}
|
||||
|
@ -33,14 +33,8 @@
|
||||
class nsDisplayListBuilder;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace dom {
|
||||
class TabGroup;
|
||||
}
|
||||
namespace layers {
|
||||
|
||||
using dom::TabGroup;
|
||||
|
||||
class ClientPaintedLayer;
|
||||
class CompositorBridgeChild;
|
||||
class ImageLayer;
|
||||
@ -66,8 +60,6 @@ class ClientLayerManager final : public LayerManager,
|
||||
|
||||
ClientLayerManager* AsClientLayerManager() override { return this; }
|
||||
|
||||
TabGroup* GetTabGroup();
|
||||
|
||||
int32_t GetMaxTextureSize() const override;
|
||||
|
||||
void SetDefaultTargetConfiguration(BufferMode aDoubleBuffering,
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "ipc/IPCMessageUtils.h" // for gfxContentType, null_t
|
||||
#include "IPDLActor.h"
|
||||
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
|
||||
#include "mozilla/dom/TabGroup.h"
|
||||
#include "mozilla/gfx/Point.h" // for IntSize
|
||||
#include "mozilla/layers/CompositableClient.h" // for CompositableClient, etc
|
||||
#include "mozilla/layers/CompositorBridgeChild.h"
|
||||
@ -195,9 +194,8 @@ ShadowLayerForwarder::ShadowLayerForwarder(
|
||||
mIsFirstPaint(false),
|
||||
mNextLayerHandle(1) {
|
||||
mTxn = new Transaction();
|
||||
if (TabGroup* tabGroup = mClientLayerManager->GetTabGroup()) {
|
||||
mEventTarget = tabGroup->EventTargetFor(TaskCategory::Other);
|
||||
}
|
||||
mEventTarget = GetMainThreadSerialEventTarget();
|
||||
|
||||
MOZ_ASSERT(mEventTarget || !XRE_IsContentProcess());
|
||||
mActiveResourceTracker = MakeUnique<ActiveResourceTracker>(
|
||||
1000, "CompositableForwarder", mEventTarget);
|
||||
|
@ -8,7 +8,6 @@
|
||||
|
||||
#include "gfxPlatform.h"
|
||||
#include "mozilla/StaticPrefs_gfx.h"
|
||||
#include "mozilla/dom/TabGroup.h"
|
||||
#include "mozilla/layers/CompositableClient.h"
|
||||
#include "mozilla/layers/CompositorBridgeChild.h"
|
||||
#include "mozilla/layers/ImageDataSerializer.h"
|
||||
@ -565,13 +564,9 @@ void WebRenderBridgeChild::SetWebRenderLayerManager(
|
||||
MOZ_ASSERT(aManager && !mManager);
|
||||
mManager = aManager;
|
||||
|
||||
nsCOMPtr<nsIEventTarget> eventTarget = nullptr;
|
||||
if (dom::TabGroup* tabGroup = mManager->GetTabGroup()) {
|
||||
eventTarget = tabGroup->EventTargetFor(TaskCategory::Other);
|
||||
}
|
||||
MOZ_ASSERT(eventTarget || !XRE_IsContentProcess());
|
||||
MOZ_ASSERT(NS_IsMainThread() || !XRE_IsContentProcess());
|
||||
mActiveResourceTracker = MakeUnique<ActiveResourceTracker>(
|
||||
1000, "CompositableForwarder", eventTarget);
|
||||
1000, "CompositableForwarder", nullptr);
|
||||
}
|
||||
|
||||
ipc::IShmemAllocator* WebRenderBridgeChild::GetShmemAllocator() {
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "mozilla/StaticPrefs_apz.h"
|
||||
#include "mozilla/StaticPrefs_layers.h"
|
||||
#include "mozilla/dom/BrowserChild.h"
|
||||
#include "mozilla/dom/TabGroup.h"
|
||||
#include "mozilla/gfx/DrawEventRecorder.h"
|
||||
#include "mozilla/layers/CompositorBridgeChild.h"
|
||||
#include "mozilla/layers/StackingContextHelper.h"
|
||||
@ -622,15 +621,6 @@ void WebRenderLayerManager::WrUpdated() {
|
||||
}
|
||||
}
|
||||
|
||||
dom::TabGroup* WebRenderLayerManager::GetTabGroup() {
|
||||
if (mWidget) {
|
||||
if (dom::BrowserChild* browserChild = mWidget->GetOwningBrowserChild()) {
|
||||
return browserChild->TabGroup();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void WebRenderLayerManager::UpdateTextureFactoryIdentifier(
|
||||
const TextureFactoryIdentifier& aNewIdentifier) {
|
||||
WrBridge()->IdentifyTextureHost(aNewIdentifier);
|
||||
|
@ -35,10 +35,6 @@ namespace mozilla {
|
||||
|
||||
struct ActiveScrolledRoot;
|
||||
|
||||
namespace dom {
|
||||
class TabGroup;
|
||||
}
|
||||
|
||||
namespace layers {
|
||||
|
||||
class CompositorBridgeChild;
|
||||
@ -176,8 +172,6 @@ class WebRenderLayerManager final : public LayerManager {
|
||||
void WrUpdated();
|
||||
nsIWidget* GetWidget() { return mWidget; }
|
||||
|
||||
dom::TabGroup* GetTabGroup();
|
||||
|
||||
uint32_t StartFrameTimeRecording(int32_t aBufferSize) override;
|
||||
void StopFrameTimeRecording(uint32_t aStartIndex,
|
||||
nsTArray<float>& aFrameIntervals) override;
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/SystemGroup.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/VsyncDispatcher.h"
|
||||
#include "mozilla/dom/MemoryReportRequest.h"
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "imgLoader.h"
|
||||
#include "mozilla/Telemetry.h" // for Telemetry
|
||||
#include "mozilla/dom/DocGroup.h" // for DocGroup
|
||||
#include "mozilla/dom/TabGroup.h" // for TabGroup
|
||||
#include "nsCRTGlue.h"
|
||||
#include "nsError.h"
|
||||
|
||||
@ -277,7 +276,7 @@ nsresult imgRequestProxy::DispatchWithTargetIfAvailable(
|
||||
void imgRequestProxy::DispatchWithTarget(already_AddRefed<nsIRunnable> aEvent) {
|
||||
LOG_FUNC(gImgLog, "imgRequestProxy::DispatchWithTarget");
|
||||
|
||||
MOZ_ASSERT(mListener || mTabGroup);
|
||||
MOZ_ASSERT(mListener);
|
||||
MOZ_ASSERT(mEventTarget);
|
||||
|
||||
mHadDispatch = true;
|
||||
@ -302,9 +301,6 @@ void imgRequestProxy::AddToOwner(Document* aLoadingDocument) {
|
||||
if (aLoadingDocument) {
|
||||
RefPtr<mozilla::dom::DocGroup> docGroup = aLoadingDocument->GetDocGroup();
|
||||
if (docGroup) {
|
||||
mTabGroup = docGroup->GetTabGroup();
|
||||
MOZ_ASSERT(mTabGroup);
|
||||
|
||||
mEventTarget = docGroup->EventTargetFor(mozilla::TaskCategory::Other);
|
||||
MOZ_ASSERT(mEventTarget);
|
||||
}
|
||||
@ -1070,11 +1066,6 @@ void imgRequestProxy::NullOutListener() {
|
||||
} else {
|
||||
mListener = nullptr;
|
||||
}
|
||||
|
||||
// Note that we don't free the event target. We actually need that to ensure
|
||||
// we get removed from the ProgressTracker properly. No harm in keeping it
|
||||
// however.
|
||||
mTabGroup = nullptr;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -34,10 +34,6 @@ class imgStatusNotifyRunnable;
|
||||
class ProxyBehaviour;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class TabGroup;
|
||||
}
|
||||
|
||||
namespace image {
|
||||
class Image;
|
||||
class ProgressTracker;
|
||||
@ -213,7 +209,6 @@ class imgRequestProxy : public imgIRequest,
|
||||
"they are destroyed") mListener;
|
||||
|
||||
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
||||
RefPtr<mozilla::dom::TabGroup> mTabGroup;
|
||||
nsCOMPtr<nsIEventTarget> mEventTarget;
|
||||
|
||||
nsLoadFlags mLoadFlags;
|
||||
|
@ -45,7 +45,6 @@
|
||||
#include "mozilla/dom/ServiceWorkerActors.h"
|
||||
#include "mozilla/dom/ServiceWorkerManagerChild.h"
|
||||
#include "mozilla/dom/BrowserChild.h"
|
||||
#include "mozilla/dom/TabGroup.h"
|
||||
#include "mozilla/ipc/IPCStreamAlloc.h"
|
||||
#include "mozilla/ipc/PBackgroundTestChild.h"
|
||||
#include "mozilla/ipc/PChildToParentStreamChild.h"
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "mozilla/ipc/MessageChannel.h"
|
||||
#include "mozilla/ipc/Transport.h"
|
||||
#include "mozilla/StaticMutex.h"
|
||||
#include "mozilla/SystemGroup.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsPrintfCString.h"
|
||||
|
||||
|
@ -60,7 +60,6 @@
|
||||
#include "mozilla/RestyleManager.h"
|
||||
#include "mozilla/SizeOfState.h"
|
||||
#include "mozilla/StyleAnimationValue.h"
|
||||
#include "mozilla/SystemGroup.h"
|
||||
#include "mozilla/ServoBindings.h"
|
||||
#include "mozilla/ServoTraversalStatistics.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
@ -109,7 +109,6 @@ nrappkit copyright:
|
||||
#include "runnable_utils.h"
|
||||
#include "mozilla/SyncRunnable.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/SystemGroup.h"
|
||||
#include "nsISocketFilter.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "mozilla/ipc/URIUtils.h"
|
||||
#include "mozilla/net/NeckoChild.h"
|
||||
#include "mozilla/StaticPrefs_network.h"
|
||||
#include "mozilla/SystemGroup.h"
|
||||
#include "mozilla/StoragePrincipalHelper.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsNetCID.h"
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "mozilla/dom/DocGroup.h"
|
||||
#include "mozilla/dom/ServiceWorkerUtils.h"
|
||||
#include "mozilla/dom/BrowserChild.h"
|
||||
#include "mozilla/dom/TabGroup.h"
|
||||
#include "mozilla/extensions/StreamFilterParent.h"
|
||||
#include "mozilla/ipc/FileDescriptorSetChild.h"
|
||||
#include "mozilla/ipc/IPCStreamUtils.h"
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozilla/SystemGroup.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/ThreadLocal.h"
|
||||
#include "mozilla/Unused.h"
|
||||
|
@ -257,10 +257,6 @@ nsHangDetails::GetModules(JSContext* aCx, JS::MutableHandleValue aVal) {
|
||||
// Processing and submitting the stack as an observer notification.
|
||||
|
||||
void nsHangDetails::Submit() {
|
||||
if (NS_WARN_IF(!SystemGroup::Initialized())) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<nsHangDetails> hangDetails = this;
|
||||
nsCOMPtr<nsIRunnable> notifyObservers =
|
||||
NS_NewRunnableFunction("NotifyBHRHangObservers", [hangDetails] {
|
||||
|
@ -12,7 +12,6 @@
|
||||
|
||||
#include "mozilla/AbstractThread.h"
|
||||
#include "mozilla/HoldDropJSObjects.h"
|
||||
#include "mozilla/SystemGroup.h"
|
||||
#include "mozilla/extensions/StreamFilterChild.h"
|
||||
#include "mozilla/extensions/StreamFilterEvents.h"
|
||||
#include "mozilla/extensions/StreamFilterParent.h"
|
||||
|
@ -12,7 +12,6 @@
|
||||
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/SystemGroup.h"
|
||||
#include "mozilla/WebRequestService.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIThread.h"
|
||||
|
@ -4,7 +4,6 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsBrowserStatusFilter.h"
|
||||
#include "mozilla/SystemGroup.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsString.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
@ -68,7 +68,6 @@
|
||||
#include "mozilla/dom/BrowserParent.h"
|
||||
#include "mozilla/dom/BrowserHost.h"
|
||||
#include "mozilla/dom/DocGroup.h"
|
||||
#include "mozilla/dom/TabGroup.h"
|
||||
#include "nsIAppWindow.h"
|
||||
#include "nsIXULBrowserWindow.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
@ -986,10 +985,10 @@ nsresult nsWindowWatcher::OpenWindowInternal(
|
||||
} else {
|
||||
newBC->SetOpener(parentBC);
|
||||
}
|
||||
} else if (parentWindow && parentWindow != win) {
|
||||
MOZ_ASSERT(
|
||||
win->TabGroup() != parentWindow->TabGroup(),
|
||||
"If we're forcing no opener, they should be in different tab groups");
|
||||
} else if (parentBC && parentBC != newBC && !newBC->IsChrome()) {
|
||||
MOZ_ASSERT(newBC->Group() != parentBC->Group(),
|
||||
"If we're forcing no opener, they should be in different "
|
||||
"browsing context groups");
|
||||
}
|
||||
|
||||
if (windowIsNew) {
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "ClientLayerManager.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "mozilla/dom/BrowserChild.h"
|
||||
#include "mozilla/dom/TabGroup.h"
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
#include "mozilla/Hal.h"
|
||||
#include "mozilla/IMEStateManager.h"
|
||||
@ -19,6 +18,7 @@
|
||||
#include "mozilla/layers/WebRenderLayerManager.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/PresShell.h"
|
||||
#include "mozilla/SchedulerGroup.h"
|
||||
#include "mozilla/StaticPrefs_browser.h"
|
||||
#include "mozilla/TextComposition.h"
|
||||
#include "mozilla/TextEventDispatcher.h"
|
||||
@ -273,7 +273,7 @@ void PuppetWidget::Invalidate(const LayoutDeviceIntRect& aRect) {
|
||||
if (mBrowserChild && !mDirtyRegion.IsEmpty() && !mPaintTask.IsPending()) {
|
||||
mPaintTask = new PaintTask(this);
|
||||
nsCOMPtr<nsIRunnable> event(mPaintTask.get());
|
||||
mBrowserChild->TabGroup()->Dispatch(TaskCategory::Other, event.forget());
|
||||
SchedulerGroup::Dispatch(TaskCategory::Other, event.forget());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -781,7 +781,7 @@ nsresult PuppetWidget::NotifyIMEOfFocusChange(
|
||||
RefPtr<PuppetWidget> self = this;
|
||||
mBrowserChild->SendNotifyIMEFocus(mContentCache, aIMENotification)
|
||||
->Then(
|
||||
mBrowserChild->TabGroup()->EventTargetFor(TaskCategory::UI), __func__,
|
||||
GetMainThreadSerialEventTarget(), __func__,
|
||||
[self](IMENotificationRequests&& aRequests) {
|
||||
self->mIMENotificationRequestsOfParent = aRequests;
|
||||
if (TextEventDispatcher* dispatcher =
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include "mozilla/DebuggerOnGCRunnable.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
#include "mozilla/SystemGroup.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/TimelineConsumers.h"
|
||||
#include "mozilla/TimelineMarker.h"
|
||||
|
@ -71,7 +71,6 @@
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/Omnijar.h"
|
||||
#include "mozilla/ScriptPreloader.h"
|
||||
#include "mozilla/SystemGroup.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/BackgroundHangMonitor.h"
|
||||
|
||||
@ -328,9 +327,6 @@ NS_InitXPCOM(nsIServiceManager** aResult, nsIFile* aBinDirectory,
|
||||
}
|
||||
AUTO_PROFILER_INIT2;
|
||||
|
||||
// Init the mozilla::SystemGroup for dispatching main thread runnables.
|
||||
mozilla::SystemGroup::InitStatic();
|
||||
|
||||
// Set up the timer globals/timer thread
|
||||
rv = nsTimerImpl::Startup();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
@ -515,9 +511,6 @@ NS_InitMinimalXPCOM() {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Init the mozilla::SystemGroup for dispatching main thread runnables.
|
||||
mozilla::SystemGroup::InitStatic();
|
||||
|
||||
// Set up the timer globals/timer thread.
|
||||
rv = nsTimerImpl::Startup();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
@ -781,9 +774,6 @@ nsresult ShutdownXPCOM(nsIServiceManager* aServMgr) {
|
||||
nsComponentManagerImpl::gComponentManager = nullptr;
|
||||
nsCategoryManager::Destroy();
|
||||
|
||||
// Shut down SystemGroup for main thread dispatching.
|
||||
SystemGroup::Shutdown();
|
||||
|
||||
GkRust_Shutdown();
|
||||
|
||||
#ifdef NS_FREE_PERMANENT_DATA
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/SystemGroup.h"
|
||||
|
||||
#include "base/basictypes.h"
|
||||
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "mozilla/AbstractThread.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/dom/DocGroup.h"
|
||||
#include "mozilla/dom/TabGroup.h"
|
||||
#include "mozilla/SchedulerGroup.h"
|
||||
#include "mozilla/TaskCategory.h"
|
||||
#include "mozilla/PerformanceCounter.h"
|
||||
@ -118,10 +117,10 @@ class ThreadMetrics : public ::testing::Test {
|
||||
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
// building the TabGroup/DocGroup structure
|
||||
RefPtr<dom::TabGroup> tabGroup = new dom::TabGroup(false);
|
||||
mDocGroup = tabGroup->AddDocument(NS_LITERAL_CSTRING("key"), nullptr);
|
||||
mDocGroup2 = tabGroup->AddDocument(NS_LITERAL_CSTRING("key2"), nullptr);
|
||||
// building the DocGroup structure
|
||||
RefPtr<dom::BrowsingContextGroup> group = new dom::BrowsingContextGroup();
|
||||
mDocGroup = group->AddDocument(NS_LITERAL_CSTRING("key"), nullptr);
|
||||
mDocGroup2 = group->AddDocument(NS_LITERAL_CSTRING("key2"), nullptr);
|
||||
mCounter = mDocGroup->GetPerformanceCounter();
|
||||
mCounter2 = mDocGroup2->GetPerformanceCounter();
|
||||
mThreadMgr = do_GetService("@mozilla.org/thread-manager;1");
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include <utility>
|
||||
|
||||
#include "jsfriendapi.h"
|
||||
#include "mozilla/AbstractThread.h"
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/Unused.h"
|
||||
@ -21,77 +20,12 @@
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
/* SchedulerEventTarget */
|
||||
|
||||
namespace {
|
||||
|
||||
#define NS_DISPATCHEREVENTTARGET_IID \
|
||||
{ \
|
||||
0xbf4e36c8, 0x7d04, 0x4ef4, { \
|
||||
0xbb, 0xd8, 0x11, 0x09, 0x0a, 0xdb, 0x4d, 0xf7 \
|
||||
} \
|
||||
}
|
||||
|
||||
class SchedulerEventTarget final : public nsISerialEventTarget {
|
||||
RefPtr<SchedulerGroup> mDispatcher;
|
||||
TaskCategory mCategory;
|
||||
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_DISPATCHEREVENTTARGET_IID)
|
||||
|
||||
SchedulerEventTarget(SchedulerGroup* aDispatcher, TaskCategory aCategory)
|
||||
: mDispatcher(aDispatcher), mCategory(aCategory) {}
|
||||
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIEVENTTARGET_FULL
|
||||
|
||||
SchedulerGroup* Dispatcher() const { return mDispatcher; }
|
||||
|
||||
private:
|
||||
~SchedulerEventTarget() = default;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(SchedulerEventTarget,
|
||||
NS_DISPATCHEREVENTTARGET_IID)
|
||||
|
||||
static Atomic<uint64_t> gEarliestUnprocessedVsync(0);
|
||||
|
||||
} // namespace
|
||||
|
||||
NS_IMPL_ISUPPORTS(SchedulerEventTarget, SchedulerEventTarget, nsIEventTarget,
|
||||
nsISerialEventTarget)
|
||||
|
||||
NS_IMETHODIMP
|
||||
SchedulerEventTarget::DispatchFromScript(nsIRunnable* aRunnable,
|
||||
uint32_t aFlags) {
|
||||
return Dispatch(do_AddRef(aRunnable), aFlags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SchedulerEventTarget::Dispatch(already_AddRefed<nsIRunnable> aRunnable,
|
||||
uint32_t aFlags) {
|
||||
if (NS_WARN_IF(aFlags != NS_DISPATCH_NORMAL)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
return mDispatcher->Dispatch(mCategory, std::move(aRunnable));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SchedulerEventTarget::DelayedDispatch(already_AddRefed<nsIRunnable>, uint32_t) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SchedulerEventTarget::IsOnCurrentThread(bool* aIsOnCurrentThread) {
|
||||
*aIsOnCurrentThread = NS_IsMainThread();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(bool)
|
||||
SchedulerEventTarget::IsOnCurrentThreadInfallible() {
|
||||
return NS_IsMainThread();
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsresult SchedulerGroup::UnlabeledDispatch(
|
||||
TaskCategory aCategory, already_AddRefed<nsIRunnable>&& aRunnable) {
|
||||
@ -138,76 +72,6 @@ nsresult SchedulerGroup::Dispatch(TaskCategory aCategory,
|
||||
return LabeledDispatch(aCategory, std::move(aRunnable), nullptr);
|
||||
}
|
||||
|
||||
nsISerialEventTarget* SchedulerGroup::EventTargetFor(
|
||||
TaskCategory aCategory) const {
|
||||
MOZ_ASSERT(aCategory != TaskCategory::Count);
|
||||
MOZ_ASSERT(mEventTargets[size_t(aCategory)]);
|
||||
return mEventTargets[size_t(aCategory)];
|
||||
}
|
||||
|
||||
AbstractThread* SchedulerGroup::AbstractMainThreadFor(TaskCategory aCategory) {
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
return AbstractMainThreadForImpl(aCategory);
|
||||
}
|
||||
|
||||
AbstractThread* SchedulerGroup::AbstractMainThreadForImpl(
|
||||
TaskCategory aCategory) {
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aCategory != TaskCategory::Count);
|
||||
MOZ_ASSERT(mEventTargets[size_t(aCategory)]);
|
||||
|
||||
if (!mAbstractThreads[size_t(aCategory)]) {
|
||||
mAbstractThreads[size_t(aCategory)] =
|
||||
AbstractThread::CreateEventTargetWrapper(
|
||||
mEventTargets[size_t(aCategory)],
|
||||
/* aDrainDirectTasks = */ true);
|
||||
}
|
||||
|
||||
return mAbstractThreads[size_t(aCategory)];
|
||||
}
|
||||
|
||||
void SchedulerGroup::CreateEventTargets(bool aNeedValidation) {
|
||||
for (size_t i = 0; i < size_t(TaskCategory::Count); i++) {
|
||||
TaskCategory category = static_cast<TaskCategory>(i);
|
||||
if (!aNeedValidation) {
|
||||
// The chrome TabGroup dispatches directly to the main thread. This means
|
||||
// that we don't have to worry about cyclical references when cleaning up
|
||||
// the chrome TabGroup.
|
||||
mEventTargets[i] = GetMainThreadSerialEventTarget();
|
||||
} else {
|
||||
mEventTargets[i] = CreateEventTargetFor(category);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SchedulerGroup::Shutdown(bool aXPCOMShutdown) {
|
||||
// There is a RefPtr cycle TabGroup -> SchedulerEventTarget -> TabGroup. To
|
||||
// avoid leaks, we need to break the chain somewhere. We shouldn't be using
|
||||
// the ThrottledEventQueue for this TabGroup when no windows belong to it,
|
||||
// so it's safe to null out the queue here.
|
||||
for (size_t i = 0; i < size_t(TaskCategory::Count); i++) {
|
||||
mEventTargets[i] =
|
||||
aXPCOMShutdown ? nullptr : GetMainThreadSerialEventTarget();
|
||||
mAbstractThreads[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<nsISerialEventTarget> SchedulerGroup::CreateEventTargetFor(
|
||||
TaskCategory aCategory) {
|
||||
RefPtr<SchedulerEventTarget> target =
|
||||
new SchedulerEventTarget(this, aCategory);
|
||||
return target.forget();
|
||||
}
|
||||
|
||||
/* static */
|
||||
SchedulerGroup* SchedulerGroup::FromEventTarget(nsIEventTarget* aEventTarget) {
|
||||
RefPtr<SchedulerEventTarget> target = do_QueryObject(aEventTarget);
|
||||
if (!target) {
|
||||
return nullptr;
|
||||
}
|
||||
return target->Dispatcher();
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsresult SchedulerGroup::LabeledDispatch(
|
||||
TaskCategory aCategory, already_AddRefed<nsIRunnable>&& aRunnable,
|
||||
@ -277,7 +141,7 @@ NS_IMETHODIMP
|
||||
SchedulerGroup::Runnable::Run() {
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
// The runnable's destructor can have side effects, so try to execute it in
|
||||
// the scope of the TabGroup.
|
||||
// the scope of the SchedulerGroup.
|
||||
nsCOMPtr<nsIRunnable> runnable(std::move(mRunnable));
|
||||
return runnable->Run();
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "mozilla/Queue.h"
|
||||
#include "mozilla/TaskCategory.h"
|
||||
#include "mozilla/ThreadLocal.h"
|
||||
#include "mozilla/ThrottledEventQueue.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
@ -26,7 +27,6 @@ namespace mozilla {
|
||||
class AbstractThread;
|
||||
namespace dom {
|
||||
class DocGroup;
|
||||
class TabGroup;
|
||||
} // namespace dom
|
||||
|
||||
#define NS_SCHEDULERGROUPRUNNABLE_IID \
|
||||
@ -44,9 +44,9 @@ class TabGroup;
|
||||
//
|
||||
// A SchedulerGroup is an abstract class to represent a "group". Essentially the
|
||||
// only functionality offered by a SchedulerGroup is the ability to dispatch
|
||||
// runnables to the group. TabGroup, DocGroup, and SystemGroup are the concrete
|
||||
// runnables to the group. DocGroup, and SystemGroup are the concrete
|
||||
// implementations of SchedulerGroup.
|
||||
class SchedulerGroup : public LinkedListElement<SchedulerGroup> {
|
||||
class SchedulerGroup {
|
||||
public:
|
||||
SchedulerGroup();
|
||||
|
||||
@ -79,20 +79,9 @@ class SchedulerGroup : public LinkedListElement<SchedulerGroup> {
|
||||
};
|
||||
friend class Runnable;
|
||||
|
||||
bool* GetValidAccessPtr() { return &mIsRunning; }
|
||||
|
||||
static nsresult Dispatch(TaskCategory aCategory,
|
||||
already_AddRefed<nsIRunnable>&& aRunnable);
|
||||
|
||||
virtual nsISerialEventTarget* EventTargetFor(TaskCategory aCategory) const;
|
||||
|
||||
// Must always be called on the main thread. The returned AbstractThread can
|
||||
// always be used off the main thread.
|
||||
AbstractThread* AbstractMainThreadFor(TaskCategory aCategory);
|
||||
|
||||
// This method performs a safe cast. It returns null if |this| is not of the
|
||||
// requested type.
|
||||
virtual dom::TabGroup* AsTabGroup() { return nullptr; }
|
||||
|
||||
static nsresult UnlabeledDispatch(TaskCategory aCategory,
|
||||
already_AddRefed<nsIRunnable>&& aRunnable);
|
||||
@ -101,50 +90,19 @@ class SchedulerGroup : public LinkedListElement<SchedulerGroup> {
|
||||
|
||||
static void MarkVsyncRan();
|
||||
|
||||
void SetIsRunning(bool aIsRunning) { mIsRunning = aIsRunning; }
|
||||
bool IsRunning() const { return mIsRunning; }
|
||||
|
||||
struct EpochQueueEntry {
|
||||
nsCOMPtr<nsIRunnable> mRunnable;
|
||||
uintptr_t mEpochNumber;
|
||||
|
||||
EpochQueueEntry(already_AddRefed<nsIRunnable> aRunnable, uintptr_t aEpoch)
|
||||
: mRunnable(aRunnable), mEpochNumber(aEpoch) {}
|
||||
};
|
||||
|
||||
using RunnableEpochQueue = Queue<EpochQueueEntry, 32>;
|
||||
|
||||
RunnableEpochQueue& GetQueue(mozilla::EventQueuePriority aPriority) {
|
||||
return mEventQueues[size_t(aPriority)];
|
||||
}
|
||||
|
||||
protected:
|
||||
static nsresult DispatchWithDocGroup(
|
||||
TaskCategory aCategory, already_AddRefed<nsIRunnable>&& aRunnable,
|
||||
dom::DocGroup* aDocGroup);
|
||||
|
||||
protected:
|
||||
static nsresult InternalUnlabeledDispatch(
|
||||
TaskCategory aCategory, already_AddRefed<Runnable>&& aRunnable);
|
||||
|
||||
// Implementations are guaranteed that this method is called on the main
|
||||
// thread.
|
||||
virtual AbstractThread* AbstractMainThreadForImpl(TaskCategory aCategory);
|
||||
|
||||
// Helper method to create an event target specific to a particular
|
||||
// TaskCategory.
|
||||
virtual already_AddRefed<nsISerialEventTarget> CreateEventTargetFor(
|
||||
TaskCategory aCategory);
|
||||
|
||||
// Given an event target returned by |dispatcher->CreateEventTargetFor|, this
|
||||
// function returns |dispatcher|.
|
||||
static SchedulerGroup* FromEventTarget(nsIEventTarget* aEventTarget);
|
||||
|
||||
static nsresult LabeledDispatch(TaskCategory aCategory,
|
||||
already_AddRefed<nsIRunnable>&& aRunnable,
|
||||
dom::DocGroup* aDocGroup);
|
||||
|
||||
void CreateEventTargets(bool aNeedValidation);
|
||||
|
||||
// Shuts down this dispatcher. If aXPCOMShutdown is true, invalidates this
|
||||
// dispatcher.
|
||||
void Shutdown(bool aXPCOMShutdown);
|
||||
@ -154,10 +112,6 @@ class SchedulerGroup : public LinkedListElement<SchedulerGroup> {
|
||||
// Number of events that are currently enqueued for this SchedulerGroup
|
||||
// (across all queues).
|
||||
size_t mEventCount = 0;
|
||||
|
||||
nsCOMPtr<nsISerialEventTarget> mEventTargets[size_t(TaskCategory::Count)];
|
||||
RefPtr<AbstractThread> mAbstractThreads[size_t(TaskCategory::Count)];
|
||||
RunnableEpochQueue mEventQueues[size_t(mozilla::EventQueuePriority::Count)];
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(SchedulerGroup::Runnable,
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "mozilla/AbstractEventQueue.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "nsIThreadInternal.h"
|
||||
#include "nsTObserverArray.h"
|
||||
|
||||
class nsIEventTarget;
|
||||
|
@ -1,85 +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 "SystemGroup.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "mozilla/AbstractThread.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
class SystemGroupImpl final : public SchedulerGroup {
|
||||
public:
|
||||
SystemGroupImpl();
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SystemGroupImpl, override)
|
||||
|
||||
static void InitStatic();
|
||||
static void ShutdownStatic();
|
||||
static SystemGroupImpl* Get();
|
||||
|
||||
static bool Initialized() { return !!sSingleton; }
|
||||
|
||||
private:
|
||||
~SystemGroupImpl() = default;
|
||||
static StaticRefPtr<SystemGroupImpl> sSingleton;
|
||||
};
|
||||
|
||||
StaticRefPtr<SystemGroupImpl> SystemGroupImpl::sSingleton;
|
||||
|
||||
SystemGroupImpl::SystemGroupImpl() {
|
||||
CreateEventTargets(/* aNeedValidation = */ true);
|
||||
}
|
||||
|
||||
/* static */
|
||||
void SystemGroupImpl::InitStatic() {
|
||||
MOZ_ASSERT(!sSingleton);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
sSingleton = new SystemGroupImpl();
|
||||
}
|
||||
|
||||
/* static */
|
||||
void SystemGroupImpl::ShutdownStatic() {
|
||||
sSingleton->Shutdown(true);
|
||||
sSingleton = nullptr;
|
||||
}
|
||||
|
||||
/* static */
|
||||
SystemGroupImpl* SystemGroupImpl::Get() {
|
||||
MOZ_ASSERT(sSingleton);
|
||||
return sSingleton.get();
|
||||
}
|
||||
|
||||
void SystemGroup::InitStatic() { SystemGroupImpl::InitStatic(); }
|
||||
|
||||
void SystemGroup::Shutdown() { SystemGroupImpl::ShutdownStatic(); }
|
||||
|
||||
bool SystemGroup::Initialized() { return SystemGroupImpl::Initialized(); }
|
||||
|
||||
/* static */
|
||||
nsresult SystemGroup::Dispatch(TaskCategory aCategory,
|
||||
already_AddRefed<nsIRunnable>&& aRunnable) {
|
||||
if (!SystemGroupImpl::Initialized()) {
|
||||
return NS_DispatchToMainThread(std::move(aRunnable));
|
||||
}
|
||||
return SystemGroupImpl::Get()->Dispatch(aCategory, std::move(aRunnable));
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsISerialEventTarget* SystemGroup::EventTargetFor(TaskCategory aCategory) {
|
||||
if (!SystemGroupImpl::Initialized()) {
|
||||
return GetMainThreadSerialEventTarget();
|
||||
}
|
||||
return SystemGroupImpl::Get()->EventTargetFor(aCategory);
|
||||
}
|
||||
|
||||
/* static */
|
||||
AbstractThread* SystemGroup::AbstractMainThreadFor(TaskCategory aCategory) {
|
||||
MOZ_ASSERT(SystemGroupImpl::Initialized());
|
||||
return SystemGroupImpl::Get()->AbstractMainThreadFor(aCategory);
|
||||
}
|
@ -1,42 +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_SystemGroup_h
|
||||
#define mozilla_SystemGroup_h
|
||||
|
||||
#include "mozilla/TaskCategory.h"
|
||||
#include "mozilla/SchedulerGroup.h"
|
||||
|
||||
// The SystemGroup should be used for dispatching runnables that don't need to
|
||||
// touch web content. Runnables dispatched to the SystemGroup are run in order
|
||||
// relative to each other, but their order relative to other runnables is
|
||||
// undefined.
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class SystemGroup {
|
||||
public:
|
||||
// This method is safe to use from any thread.
|
||||
static nsresult Dispatch(TaskCategory aCategory,
|
||||
already_AddRefed<nsIRunnable>&& aRunnable);
|
||||
|
||||
// This method is safe to use from any thread.
|
||||
static nsISerialEventTarget* EventTargetFor(TaskCategory aCategory);
|
||||
|
||||
// Must be called on the main thread. The AbstractThread can always be used
|
||||
// off the main thread.
|
||||
static AbstractThread* AbstractMainThreadFor(TaskCategory aCategory);
|
||||
|
||||
static void InitStatic();
|
||||
static void Shutdown();
|
||||
|
||||
// Returns true if SystemGroup has been initialized.
|
||||
static bool Initialized();
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_SystemGroup_h
|
@ -68,7 +68,6 @@ EXPORTS.mozilla += [
|
||||
'StateWatching.h',
|
||||
'SynchronizedEventQueue.h',
|
||||
'SyncRunnable.h',
|
||||
'SystemGroup.h',
|
||||
'TaskCategory.h',
|
||||
'TaskDispatcher.h',
|
||||
'TaskQueue.h',
|
||||
@ -107,7 +106,6 @@ UNIFIED_SOURCES += [
|
||||
'SchedulerGroup.cpp',
|
||||
'SharedThreadPool.cpp',
|
||||
'SynchronizedEventQueue.cpp',
|
||||
'SystemGroup.cpp',
|
||||
'TaskQueue.cpp',
|
||||
'ThreadEventQueue.cpp',
|
||||
'ThreadEventTarget.cpp',
|
||||
|
@ -11,7 +11,6 @@
|
||||
|
||||
#include "MainThreadUtils.h"
|
||||
#include "mozilla/Likely.h"
|
||||
#include "mozilla/SystemGroup.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIEventTarget.h"
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "mozilla/Services.h"
|
||||
#include "nsXPCOMPrivate.h"
|
||||
#include "mozilla/ChaosMode.h"
|
||||
#include "mozilla/SchedulerGroup.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/Unused.h"
|
||||
|
Loading…
x
Reference in New Issue
Block a user