Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2229)

Side by Side Diff: Source/core/dom/ScriptedIdleTaskController.cpp

Issue 1119683003: Implement requestIdleCallback API (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Address Review Comments Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "config.h"
6 #include "core/dom/ScriptedIdleTaskController.h"
7
8 #include "core/dom/ExecutionContext.h"
9 #include "core/dom/IdleRequestCallback.h"
10 #include "core/loader/DocumentLoadTiming.h"
11 #include "platform/Logging.h"
12 #include "platform/TraceEvent.h"
13 #include "public/platform/Platform.h"
14 #include "public/platform/WebScheduler.h"
15 #include "public/platform/WebTraceLocation.h"
16 #include "wtf/CurrentTime.h"
17 #include "wtf/Functional.h"
18
19 namespace blink {
20
21 ScriptedIdleTaskController::ScriptedIdleTaskController(ExecutionContext* context , const DocumentLoadTiming& timing)
22 : ActiveDOMObject(context)
23 , m_timing(timing)
24 , m_nextCallbackId(0)
25 , m_suspended(false)
26 {
27 suspendIfNeeded();
28 }
29
30 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(ScriptedIdleTaskController);
31
32 DEFINE_TRACE(ScriptedIdleTaskController)
33 {
34 ActiveDOMObject::trace(visitor);
35 visitor->trace(m_callbacks);
36 }
37
38 ScriptedIdleTaskController::CallbackId ScriptedIdleTaskController::registerCallb ack(IdleRequestCallback* callback, double timeoutMillis)
39 {
40 CallbackId id = ++m_nextCallbackId;
41 m_callbacks.set(id, callback);
42
43 RefPtr<IdleRequestCallbackWrapper> callbackWrapper = IdleRequestCallbackWrap per::create(id, this);
44 if (timeoutMillis > 0)
45 callbackWrapper->setTimeout(timeoutMillis);
46
47 Platform::current()->currentThread()->scheduler()->postIdleTask(
Sami 2015/08/11 18:03:00 nit: Maybe it's worth saving a pointer to the sche
rmcilroy 2015/08/12 14:17:30 Done.
48 FROM_HERE, WTF::bind<double>(&ScriptedIdleTaskController::IdleRequestCal lbackWrapper::idleTaskFired, callbackWrapper));
49 // TODO(rmcilroy): Add devtools tracing.
50 return id;
51 }
52
53 void ScriptedIdleTaskController::cancelCallback(CallbackId id)
54 {
55 // TODO(rmcilroy): Add devtools tracing.
56 m_callbacks.remove(id);
57 }
58
59 void ScriptedIdleTaskController::callbackFired(IdleRequestCallbackWrapper* callb ackWrapper, double deadlineSeconds, IdleCallbackDeadline::CallbackType callbackT ype)
60 {
61 CallbackId id = callbackWrapper->id();
62 if (!m_callbacks.contains(id))
63 return;
64
65 if (m_suspended) {
66 if (callbackType == IdleCallbackDeadline::CalledByTimeout) {
67 callbackWrapper->cancelTimeout();
68 // Queue for execution when we are resumed.
69 m_pendingTimeouts.push(id);
70 }
71 // Just drop callbacks called while idle, these will be reposted on the idle task queue when we are resumed.
Sami 2015/08/11 18:03:00 s/idle/suspended/?
rmcilroy 2015/08/12 14:17:30 Done.
72 return;
73 }
74
75 double deadlineMillis;
76 if (callbackType == IdleCallbackDeadline::CalledByTimeout)
77 deadlineMillis = -1;
78 else
79 deadlineMillis = 1000.0 * m_timing.monotonicTimeToZeroBasedDocumentTime( deadlineSeconds);
80
81 callbackWrapper->cancelTimeout();
82 runCallback(id, deadlineMillis, callbackType);
83 }
84
85 void ScriptedIdleTaskController::runCallback(CallbackId id, double deadlineMilli s, IdleCallbackDeadline::CallbackType callbackType)
86 {
87 ASSERT(!m_suspended);
88 auto callback = m_callbacks.take(id);
89 if (!callback)
90 return;
91
92 // TODO(rmcilroy): Add devtools tracing.
93 callback->handleEvent(IdleCallbackDeadline::create(deadlineMillis, callbackT ype, m_timing));
94 }
95
96 void ScriptedIdleTaskController::stop()
97 {
98 m_callbacks.clear();
99 }
100
101 void ScriptedIdleTaskController::suspend()
102 {
103 m_suspended = true;
104 }
105
106 void ScriptedIdleTaskController::resume()
107 {
108 ASSERT(m_suspended);
109 m_suspended = false;
110
111 // Run any pending timeouts.
112 while (!m_pendingTimeouts.empty()) {
113 runCallback(m_pendingTimeouts.front(), -1, IdleCallbackDeadline::CalledB yTimeout);
114 m_pendingTimeouts.pop();
115 }
116
117 // Repost idle tasks for any remaining callbacks.
118 for (auto callback = m_callbacks.begin(); callback != m_callbacks.end();
119 ++callback) {
120 RefPtr<IdleRequestCallbackWrapper> callbackWrapper = IdleRequestCallback Wrapper::create(callback->key, this);
121 Platform::current()->currentThread()->scheduler()->postIdleTask(
122 FROM_HERE, WTF::bind<double>(&ScriptedIdleTaskController::IdleReques tCallbackWrapper::idleTaskFired, callbackWrapper));
123 }
124 }
125
126 bool ScriptedIdleTaskController::hasPendingActivity() const
127 {
128 return !m_callbacks.isEmpty();
129 }
130
131 ScriptedIdleTaskController::IdleRequestCallbackWrapper::IdleRequestCallbackWrapp er(CallbackId id, PassRefPtrWillBeRawPtr<ScriptedIdleTaskController> controller)
132 : m_id(id)
133 , m_timeoutTimer(nullptr)
134 , m_controller(controller)
135 {
136 }
137
138 ScriptedIdleTaskController::IdleRequestCallbackWrapper::~IdleRequestCallbackWrap per()
139 {
140 }
141
142 // static
143 void ScriptedIdleTaskController::IdleRequestCallbackWrapper::idleTaskFired(PassR efPtr<IdleRequestCallbackWrapper> callbackWrapper, double deadlineSeconds)
144 {
145 callbackWrapper->m_controller->callbackFired(callbackWrapper.get(), deadline Seconds, IdleCallbackDeadline::CalledWhenIdle);
146 }
147
148 ScriptedIdleTaskController::IdleRequestCallbackWrapper::IdleRequestTimoutTimer:: IdleRequestTimoutTimer(PassRefPtr<IdleRequestCallbackWrapper> callbackWrapper)
149 : Timer(this, &IdleRequestTimoutTimer::timeoutFired)
150 , m_callbackWrapper(callbackWrapper)
151 {
152 }
153
154 void ScriptedIdleTaskController::IdleRequestCallbackWrapper::cancelTimeout()
155 {
156 if (m_timeoutTimer.get()) {
157 m_timeoutTimer->stop();
158 m_timeoutTimer.clear();
159 }
160 }
161
162 ScriptedIdleTaskController::IdleRequestCallbackWrapper::IdleRequestTimoutTimer:: ~IdleRequestTimoutTimer()
163 {
164 }
165
166 void ScriptedIdleTaskController::IdleRequestCallbackWrapper::IdleRequestTimoutTi mer::timeoutFired(Timer<IdleRequestTimoutTimer>* timer)
167 {
168 m_callbackWrapper->controller()->callbackFired(m_callbackWrapper.get(), -1, IdleCallbackDeadline::CalledByTimeout);
169 }
170
171 void ScriptedIdleTaskController::IdleRequestCallbackWrapper::setTimeout(double t imeoutMillis)
172 {
173 ASSERT(!m_timeoutTimer.get());
174 m_timeoutTimer = adoptPtr(new IdleRequestTimoutTimer(this));
175 m_timeoutTimer->startOneShot(0.001 * timeoutMillis, FROM_HERE);
176 }
177
178 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698