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

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: Rebased 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
« no previous file with comments | « Source/core/dom/ScriptedIdleTaskController.h ('k') | Source/core/frame/DOMWindow.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 namespace internal {
22
23 class IdleRequestCallbackWrapper : public RefCounted<IdleRequestCallbackWrapper> {
24 public:
25 static PassRefPtr<IdleRequestCallbackWrapper> create(ScriptedIdleTaskControl ler::CallbackId id, PassRefPtrWillBeRawPtr<ScriptedIdleTaskController> controlle r)
26 {
27 return adoptRef(new IdleRequestCallbackWrapper(id, controller));
28 }
29 virtual ~IdleRequestCallbackWrapper()
30 {
31 }
32
33 static void idleTaskFired(PassRefPtr<IdleRequestCallbackWrapper> callbackWra pper, double deadlineSeconds)
34 {
35 // TODO(rmcilroy): Implement clamping of deadline in some form.
36 callbackWrapper->controller()->callbackFired(callbackWrapper->id(), dead lineSeconds, IdleCallbackDeadline::CallbackType::CalledWhenIdle);
37 }
38
39 static void timeoutFired(PassRefPtr<IdleRequestCallbackWrapper> callbackWrap per)
40 {
41 callbackWrapper->controller()->callbackFired(callbackWrapper->id(), mono tonicallyIncreasingTime(), IdleCallbackDeadline::CallbackType::CalledByTimeout);
42 }
43
44 ScriptedIdleTaskController::CallbackId id() const { return m_id; }
45 PassRefPtrWillBeRawPtr<ScriptedIdleTaskController> controller() const { retu rn m_controller; }
46
47 private:
48 explicit IdleRequestCallbackWrapper(ScriptedIdleTaskController::CallbackId i d, PassRefPtrWillBeRawPtr<ScriptedIdleTaskController> controller)
49 : m_id(id)
50 , m_controller(controller)
51 {
52 }
53
54 ScriptedIdleTaskController::CallbackId m_id;
55 RefPtrWillBePersistent<ScriptedIdleTaskController> m_controller;
56 };
57
58 } // namespace internal
59
60 ScriptedIdleTaskController::ScriptedIdleTaskController(ExecutionContext* context , const DocumentLoadTiming& timing)
61 : ActiveDOMObject(context)
62 , m_timing(timing)
63 , m_scheduler(Platform::current()->currentThread()->scheduler())
64 , m_nextCallbackId(0)
65 , m_suspended(false)
66 {
67 suspendIfNeeded();
68 }
69
70 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(ScriptedIdleTaskController);
71
72 DEFINE_TRACE(ScriptedIdleTaskController)
73 {
74 ActiveDOMObject::trace(visitor);
75 visitor->trace(m_callbacks);
76 }
77
78 ScriptedIdleTaskController::CallbackId ScriptedIdleTaskController::registerCallb ack(IdleRequestCallback* callback, double timeoutMillis)
79 {
80 CallbackId id = ++m_nextCallbackId;
81 m_callbacks.set(id, callback);
82
83 RefPtr<internal::IdleRequestCallbackWrapper> callbackWrapper = internal::Idl eRequestCallbackWrapper::create(id, this);
84 m_scheduler->postIdleTask(FROM_HERE, WTF::bind<double>(&internal::IdleReques tCallbackWrapper::idleTaskFired, callbackWrapper));
85 if (timeoutMillis > 0)
86 m_scheduler->postTimerTask(FROM_HERE, WTF::bind(&internal::IdleRequestCa llbackWrapper::timeoutFired, callbackWrapper), static_cast<long long>(timeoutMil lis));
87
88 // TODO(rmcilroy): Add devtools tracing.
89 return id;
90 }
91
92 void ScriptedIdleTaskController::cancelCallback(CallbackId id)
93 {
94 // TODO(rmcilroy): Add devtools tracing.
95 m_callbacks.remove(id);
96 }
97
98 void ScriptedIdleTaskController::callbackFired(CallbackId id, double deadlineSec onds, IdleCallbackDeadline::CallbackType callbackType)
99 {
100 if (!m_callbacks.contains(id))
101 return;
102
103 if (m_suspended) {
104 if (callbackType == IdleCallbackDeadline::CallbackType::CalledByTimeout) {
105 // Queue for execution when we are resumed.
106 m_pendingTimeouts.append(id);
107 }
108 // Just drop callbacks called while suspended, these will be reposted on the idle task queue when we are resumed.
109 return;
110 }
111
112 double deadlineMillis = 1000.0 * m_timing.monotonicTimeToZeroBasedDocumentTi me(deadlineSeconds);
113 runCallback(id, deadlineMillis, callbackType);
114 }
115
116 void ScriptedIdleTaskController::runCallback(CallbackId id, double deadlineMilli s, IdleCallbackDeadline::CallbackType callbackType)
117 {
118 ASSERT(!m_suspended);
119 auto callback = m_callbacks.take(id);
120 if (!callback)
121 return;
122
123 // TODO(rmcilroy): Add devtools tracing.
124 callback->handleEvent(IdleCallbackDeadline::create(deadlineMillis, callbackT ype, m_timing));
125 }
126
127 void ScriptedIdleTaskController::stop()
128 {
129 m_callbacks.clear();
130 }
131
132 void ScriptedIdleTaskController::suspend()
133 {
134 m_suspended = true;
135 }
136
137 void ScriptedIdleTaskController::resume()
138 {
139 ASSERT(m_suspended);
140 m_suspended = false;
141
142 // Run any pending timeouts.
143 Vector<CallbackId> pendingTimeouts;
144 m_pendingTimeouts.swap(pendingTimeouts);
145 for (auto& id : pendingTimeouts)
146 runCallback(id, monotonicallyIncreasingTime(), IdleCallbackDeadline::Cal lbackType::CalledByTimeout);
147
148 // Repost idle tasks for any remaining callbacks.
149 for (auto& callback : m_callbacks) {
150 RefPtr<internal::IdleRequestCallbackWrapper> callbackWrapper = internal: :IdleRequestCallbackWrapper::create(callback.key, this);
151 m_scheduler->postIdleTask(FROM_HERE, WTF::bind<double>(&internal::IdleRe questCallbackWrapper::idleTaskFired, callbackWrapper));
152 }
153 }
154
155 bool ScriptedIdleTaskController::hasPendingActivity() const
156 {
157 return !m_callbacks.isEmpty();
158 }
159
160 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/dom/ScriptedIdleTaskController.h ('k') | Source/core/frame/DOMWindow.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698