gecko-dev/dom/base/IdleRequest.cpp
Ehsan Akhgari 443e426d7c Bug 1321903 - Refactor the timeout/interval management code out of nsGlobalWindow; r=bkelly
This code now lives in TimeoutManager.  Note that this is a transition
state, the Timeout list management code also needs to be refactored out
later.

In order to simplify the lifetime management of the new class, its
lifetime is equal to the lifetime of its containing nsGlobalWindow.  In
a few places where we need to dispatch runnables to do asynchronous work
on this object, we hold the containing window alive to guarantee safety.

This patch also removes a bit of dead code that was left over from the
code removed in bug 1281793. See:
https://hg.mozilla.org/mozilla-central/rev/0ac748f4d677#l1.63
2016-12-13 14:08:47 -05:00

158 lines
3.6 KiB
C++

/* -*- 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 "IdleRequest.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/dom/IdleDeadline.h"
#include "mozilla/dom/Performance.h"
#include "mozilla/dom/PerformanceTiming.h"
#include "mozilla/dom/TimeoutManager.h"
#include "mozilla/dom/WindowBinding.h"
#include "nsComponentManagerUtils.h"
#include "nsGlobalWindow.h"
#include "nsISupportsPrimitives.h"
#include "nsPIDOMWindow.h"
namespace mozilla {
namespace dom {
IdleRequest::IdleRequest(JSContext* aCx, nsPIDOMWindowInner* aWindow,
IdleRequestCallback& aCallback, uint32_t aHandle)
: mWindow(aWindow)
, mCallback(&aCallback)
, mHandle(aHandle)
, mTimeoutHandle(Nothing())
{
MOZ_ASSERT(aWindow);
// Get the calling location.
nsJSUtils::GetCallingLocation(aCx, mFileName, &mLineNo, &mColumn);
}
IdleRequest::~IdleRequest()
{
}
NS_IMPL_CYCLE_COLLECTION_CLASS(IdleRequest)
NS_IMPL_CYCLE_COLLECTING_ADDREF(IdleRequest)
NS_IMPL_CYCLE_COLLECTING_RELEASE(IdleRequest)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IdleRequest)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCallback)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IdleRequest)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCallback)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IdleRequest)
NS_INTERFACE_MAP_ENTRY(nsIRunnable)
NS_INTERFACE_MAP_ENTRY(nsICancelableRunnable)
NS_INTERFACE_MAP_ENTRY(nsIIncrementalRunnable)
NS_INTERFACE_MAP_ENTRY(nsITimeoutHandler)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsITimeoutHandler)
NS_INTERFACE_MAP_END
nsresult
IdleRequest::SetTimeout(uint32_t aTimeout)
{
int32_t handle;
nsresult rv = mWindow->TimeoutManager().SetTimeout(
this, aTimeout, false, Timeout::Reason::eIdleCallbackTimeout, &handle);
mTimeoutHandle = Some(handle);
return rv;
}
nsresult
IdleRequest::Run()
{
if (mCallback) {
RunIdleRequestCallback(false);
}
return NS_OK;
}
nsresult
IdleRequest::Cancel()
{
mCallback = nullptr;
CancelTimeout();
if (isInList()) {
remove();
}
Release();
return NS_OK;
}
void
IdleRequest::SetDeadline(TimeStamp aDeadline)
{
mozilla::dom::Performance* perf = mWindow->GetPerformance();
mDeadline =
perf ? perf->GetDOMTiming()->TimeStampToDOMHighRes(aDeadline) : 0.0;
}
nsresult
IdleRequest::RunIdleRequestCallback(bool aDidTimeout)
{
MOZ_ASSERT(NS_IsMainThread());
if (!aDidTimeout) {
CancelTimeout();
}
remove();
ErrorResult error;
RefPtr<IdleDeadline> deadline =
new IdleDeadline(mWindow, aDidTimeout, mDeadline);
mCallback->Call(*deadline, error, "requestIdleCallback handler");
mCallback = nullptr;
Release();
return error.StealNSResult();
}
void
IdleRequest::CancelTimeout()
{
if (mTimeoutHandle.isSome()) {
mWindow->TimeoutManager().ClearTimeout(
mTimeoutHandle.value(), Timeout::Reason::eIdleCallbackTimeout);
}
}
nsresult
IdleRequest::Call()
{
SetDeadline(TimeStamp::Now());
return RunIdleRequestCallback(true);
}
void
IdleRequest::GetLocation(const char** aFileName, uint32_t* aLineNo,
uint32_t* aColumn)
{
*aFileName = mFileName.get();
*aLineNo = mLineNo;
*aColumn = mColumn;
}
void
IdleRequest::MarkForCC()
{
mCallback->MarkForCC();
}
} // namespace dom
} // namespace mozilla