Bug 1339707 - Replace NS_DispatchToCurrentThread to DocGroup / TabGroup dispatch method and set nsITimer target. r=smaug

This commit is contained in:
Samael Wang 2017-03-07 16:58:59 +08:00
parent c075f7b427
commit 2c24eb7d2b
6 changed files with 70 additions and 14 deletions

View File

@ -425,7 +425,7 @@ public:
mLoadGroup = aLoadGroup;
}
nsresult StartTimeout();
nsresult StartTimeout(Dispatcher* aDispatcher);
private:
~nsPingListener();
@ -445,9 +445,12 @@ nsPingListener::~nsPingListener()
}
nsresult
nsPingListener::StartTimeout()
nsPingListener::StartTimeout(Dispatcher* aDispatcher)
{
NS_ENSURE_ARG(aDispatcher);
nsCOMPtr<nsITimer> timer = do_CreateInstance(NS_TIMER_CONTRACTID);
timer->SetTarget(aDispatcher->EventTargetFor(TaskCategory::Network));
if (timer) {
nsresult rv = timer->InitWithFuncCallback(OnPingTimeout, mLoadGroup,
@ -641,7 +644,7 @@ SendPing(void* aClosure, nsIContent* aContent, nsIURI* aURI,
info->numPings++;
// Prevent ping requests from stalling and never being garbage collected...
if (NS_FAILED(pingListener->StartTimeout())) {
if (NS_FAILED(pingListener->StartTimeout(doc->GetDocGroup()))) {
// If we failed to setup the timer, then we should just cancel the channel
// because we won't be able to ensure that it goes away in a timely manner.
chan->Cancel(NS_ERROR_ABORT);
@ -1745,6 +1748,33 @@ nsDocShell::FirePageHideNotificationInternal(bool aIsUnload,
}
}
nsresult
nsDocShell::DispatchToTabGroup(const char* aName,
TaskCategory aCategory,
already_AddRefed<nsIRunnable>&& aRunnable)
{
// Hold the ref so we won't forget to release it.
nsCOMPtr<nsIRunnable> runnable(aRunnable);
nsCOMPtr<nsPIDOMWindowOuter> win = GetWindow();
if (!win) {
// Window should only be unavailable after destroyed.
MOZ_ASSERT(mIsBeingDestroyed);
return NS_ERROR_FAILURE;
}
RefPtr<mozilla::dom::TabGroup> tabGroup = win->TabGroup();
return tabGroup->Dispatch(aName, aCategory, runnable.forget());
}
NS_IMETHODIMP
nsDocShell::DispatchLocationChangeEvent()
{
return DispatchToTabGroup("nsDocShell::FireDummyOnLocationChange",
TaskCategory::Other,
NewRunnableMethod(this,
&nsDocShell::FireDummyOnLocationChange));
}
bool
nsDocShell::MaybeInitTiming()
{
@ -6745,8 +6775,11 @@ nsDocShell::RefreshURI(nsIURI* aURI, int32_t aDelay, bool aRepeat,
// timer and fire it right away.
nsCOMPtr<nsITimer> timer = do_CreateInstance("@mozilla.org/timer;1");
NS_ENSURE_TRUE(timer, NS_ERROR_FAILURE);
nsCOMPtr<nsPIDOMWindowOuter> win = GetWindow();
NS_ENSURE_TRUE(win, NS_ERROR_FAILURE);
mRefreshURIList->AppendElement(timer, /*weak =*/ false); // owning timer ref
timer->SetTarget(win->TabGroup()->EventTargetFor(TaskCategory::Network));
timer->InitWithCallback(refreshTimer, aDelay, nsITimer::TYPE_ONE_SHOT);
}
return NS_OK;
@ -7228,12 +7261,14 @@ nsDocShell::RefreshURIFromQueue()
static_cast<nsRefreshTimer*>(
static_cast<nsITimerCallback*>(refreshInfo))->GetDelay();
nsCOMPtr<nsITimer> timer = do_CreateInstance("@mozilla.org/timer;1");
if (timer) {
nsCOMPtr<nsPIDOMWindowOuter> win = GetWindow();
if (timer && win) {
// Replace the nsRefreshTimer element in the queue with
// its corresponding timer object, so that in case another
// load comes through before the timer can go off, the timer will
// get cancelled in CancelRefreshURITimer()
mRefreshURIList->ReplaceElementAt(timer, n, /*weak =*/ false);
timer->SetTarget(win->TabGroup()->EventTargetFor(TaskCategory::Network));
timer->InitWithCallback(refreshInfo, delay, nsITimer::TYPE_ONE_SHOT);
}
}
@ -8514,7 +8549,9 @@ nsDocShell::RestorePresentation(nsISHEntry* aSHEntry, bool* aRestoring)
mRestorePresentationEvent.Revoke();
RefPtr<RestorePresentationEvent> evt = new RestorePresentationEvent(this);
nsresult rv = NS_DispatchToCurrentThread(evt);
nsresult rv = DispatchToTabGroup("nsDocShell::RestorePresentationEvent",
TaskCategory::Other,
RefPtr<RestorePresentationEvent>(evt).forget());
if (NS_SUCCEEDED(rv)) {
mRestorePresentationEvent = evt.get();
// The rest of the restore processing will happen on our event
@ -10212,7 +10249,8 @@ nsDocShell::InternalLoad(nsIURI* aURI,
aFlags, aTypeHint, aPostData, aHeadersData,
aLoadType, aSHEntry, aFirstParty, aSrcdoc,
aSourceDocShell, aBaseURI, false);
return NS_DispatchToCurrentThread(ev);
return DispatchToTabGroup("nsDocShell::InternalLoadEvent",
TaskCategory::Other, ev.forget());
}
// Just ignore this load attempt
@ -14007,7 +14045,8 @@ nsDocShell::OnLinkClick(nsIContent* aContent,
new OnLinkClickEvent(this, aContent, aURI, target.get(), aFileName,
aPostDataStream, aHeadersDataStream, noOpenerImplied,
aIsTrusted, aTriggeringPrincipal);
return NS_DispatchToCurrentThread(ev);
return DispatchToTabGroup("nsDocShell::OnLinkClickEvent",
TaskCategory::UI, ev.forget());
}
NS_IMETHODIMP

View File

@ -63,6 +63,7 @@
#include "nsIThrottlingService.h"
namespace mozilla {
enum class TaskCategory;
namespace dom {
class EventTarget;
class PendingGlobalHistoryEntry;
@ -1075,6 +1076,11 @@ private:
void FirePageHideNotificationInternal(bool aIsUnload,
bool aSkipCheckingDynEntries);
// Dispatch a runnable to the TabGroup associated to this docshell.
nsresult DispatchToTabGroup(const char* aName,
mozilla::TaskCategory aCategory,
already_AddRefed<nsIRunnable>&& aRunnable);
#ifdef DEBUG
// We're counting the number of |nsDocShells| to help find leaks
static unsigned long gNumberOfDocShells;

View File

@ -1251,6 +1251,10 @@ ChromeTooltipListener::MouseMove(nsIDOMEvent* aMouseEvent)
aMouseEvent->InternalDOMEvent()->GetTarget();
if (eventTarget) {
mPossibleTooltipNode = do_QueryInterface(eventTarget);
nsCOMPtr<nsIGlobalObject> global(eventTarget->GetOwnerGlobal());
if (global) {
mTooltipTimer->SetTarget(global->EventTargetFor(TaskCategory::UI));
}
}
if (mPossibleTooltipNode) {
nsresult rv = mTooltipTimer->InitWithFuncCallback(

View File

@ -1136,4 +1136,9 @@ interface nsIDocShell : nsIDocShellTreeItem
* Attribute that determines whether tracking protection is enabled.
*/
attribute boolean useTrackingProtection;
/**
* Fire a dummy location change event asynchronously.
*/
[noscript] void dispatchLocationChangeEvent();
};

View File

@ -234,7 +234,7 @@ nsSHEntryShared::SetContentViewer(nsIContentViewer* aViewer)
nsresult
nsSHEntryShared::RemoveFromBFCacheSync()
{
NS_ASSERTION(mContentViewer && mDocument, "we're not in the bfcache!");
MOZ_ASSERT(mContentViewer && mDocument, "we're not in the bfcache!");
nsCOMPtr<nsIContentViewer> viewer = mContentViewer;
DropPresentationState();
@ -273,13 +273,17 @@ public:
nsresult
nsSHEntryShared::RemoveFromBFCacheAsync()
{
NS_ASSERTION(mContentViewer && mDocument, "we're not in the bfcache!");
MOZ_ASSERT(mContentViewer && mDocument, "we're not in the bfcache!");
// Release the reference to the contentviewer asynchronously so that the
// document doesn't get nuked mid-mutation.
if (!mDocument) {
return NS_ERROR_UNEXPECTED;
}
nsCOMPtr<nsIRunnable> evt = new DestroyViewerEvent(mContentViewer, mDocument);
nsresult rv = NS_DispatchToCurrentThread(evt);
nsresult rv = mDocument->Dispatch("nsSHEntryShared::DestroyViewerEvent",
mozilla::TaskCategory::Other, evt.forget());
if (NS_FAILED(rv)) {
NS_WARNING("failed to dispatch DestroyViewerEvent");
} else {

View File

@ -1519,8 +1519,7 @@ nsSHistory::RemoveEntries(nsTArray<nsID>& aIDs, int32_t aStartIndex)
--index;
}
if (didRemove && mRootDocShell) {
NS_DispatchToCurrentThread(NewRunnableMethod(static_cast<nsDocShell*>(mRootDocShell),
&nsDocShell::FireDummyOnLocationChange));
mRootDocShell->DispatchLocationChangeEvent();
}
}
@ -1932,8 +1931,7 @@ nsSHistory::OnAttachGroupedSHistory(int32_t aOffset)
// Setting grouped history info may change canGoBack / canGoForward.
// Send a location change to update these values.
NS_DispatchToCurrentThread(NewRunnableMethod(static_cast<nsDocShell*>(mRootDocShell),
&nsDocShell::FireDummyOnLocationChange));
mRootDocShell->DispatchLocationChangeEvent();
return NS_OK;
}