Chromium Code Reviews| OLD | NEW |
|---|---|
| (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 callbackWrapper->controller()->callbackFired(callbackWrapper->id(), dead lineSeconds, IdleCallbackDeadline::CallbackType::CalledWhenIdle); | |
|
esprehn
2015/08/21 08:22:21
This doesn't have the clamping behavior where shor
rmcilroy
2015/08/21 11:21:52
I know that there is discussion on clamping to avo
| |
| 36 } | |
| 37 | |
| 38 static void timeoutFired(PassRefPtr<IdleRequestCallbackWrapper> callbackWrap per) | |
| 39 { | |
| 40 callbackWrapper->controller()->callbackFired(callbackWrapper->id(), mono tonicallyIncreasingTime(), IdleCallbackDeadline::CallbackType::CalledByTimeout); | |
| 41 } | |
| 42 | |
| 43 ScriptedIdleTaskController::CallbackId id() { return m_id; } | |
|
esprehn
2015/08/21 08:22:21
const
rmcilroy
2015/08/21 11:21:52
Done.
| |
| 44 PassRefPtrWillBeRawPtr<ScriptedIdleTaskController> controller() { return m_c ontroller; } | |
| 45 | |
| 46 private: | |
| 47 explicit IdleRequestCallbackWrapper(ScriptedIdleTaskController::CallbackId i d, PassRefPtrWillBeRawPtr<ScriptedIdleTaskController> controller) | |
| 48 : m_id(id) | |
| 49 , m_controller(controller) | |
| 50 { | |
| 51 } | |
| 52 | |
| 53 ScriptedIdleTaskController::CallbackId m_id; | |
| 54 RefPtrWillBePersistent<ScriptedIdleTaskController> m_controller; | |
| 55 }; | |
| 56 | |
| 57 } // namespace internal | |
| 58 | |
| 59 ScriptedIdleTaskController::ScriptedIdleTaskController(ExecutionContext* context , const DocumentLoadTiming& timing) | |
| 60 : ActiveDOMObject(context) | |
| 61 , m_timing(timing) | |
| 62 , m_scheduler(Platform::current()->currentThread()->scheduler()) | |
| 63 , m_nextCallbackId(0) | |
| 64 , m_suspended(false) | |
| 65 { | |
| 66 suspendIfNeeded(); | |
| 67 } | |
| 68 | |
| 69 DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(ScriptedIdleTaskController); | |
| 70 | |
| 71 DEFINE_TRACE(ScriptedIdleTaskController) | |
| 72 { | |
| 73 ActiveDOMObject::trace(visitor); | |
| 74 visitor->trace(m_callbacks); | |
| 75 } | |
| 76 | |
| 77 ScriptedIdleTaskController::CallbackId ScriptedIdleTaskController::registerCallb ack(IdleRequestCallback* callback, double timeoutMillis) | |
| 78 { | |
| 79 CallbackId id = ++m_nextCallbackId; | |
| 80 m_callbacks.set(id, callback); | |
| 81 | |
| 82 RefPtr<internal::IdleRequestCallbackWrapper> callbackWrapper = internal::Idl eRequestCallbackWrapper::create(id, this); | |
| 83 m_scheduler->postIdleTask(FROM_HERE, WTF::bind<double>(&internal::IdleReques tCallbackWrapper::idleTaskFired, callbackWrapper)); | |
| 84 if (timeoutMillis > 0) | |
| 85 m_scheduler->postTimerTask(FROM_HERE, WTF::bind(&internal::IdleRequestCa llbackWrapper::timeoutFired, callbackWrapper), static_cast<long long>(timeoutMil lis)); | |
| 86 | |
| 87 // TODO(rmcilroy): Add devtools tracing. | |
| 88 return id; | |
| 89 } | |
| 90 | |
| 91 void ScriptedIdleTaskController::cancelCallback(CallbackId id) | |
| 92 { | |
| 93 // TODO(rmcilroy): Add devtools tracing. | |
| 94 m_callbacks.remove(id); | |
| 95 } | |
| 96 | |
| 97 void ScriptedIdleTaskController::callbackFired(CallbackId id, double deadlineSec onds, IdleCallbackDeadline::CallbackType callbackType) | |
| 98 { | |
| 99 if (!m_callbacks.contains(id)) | |
| 100 return; | |
| 101 | |
| 102 if (m_suspended) { | |
| 103 if (callbackType == IdleCallbackDeadline::CallbackType::CalledByTimeout) { | |
| 104 // Queue for execution when we are resumed. | |
| 105 m_pendingTimeouts.append(id); | |
| 106 } | |
| 107 // Just drop callbacks called while suspended, these will be reposted on the idle task queue when we are resumed. | |
| 108 return; | |
| 109 } | |
| 110 | |
| 111 double deadlineMillis = 1000.0 * m_timing.monotonicTimeToZeroBasedDocumentTi me(deadlineSeconds); | |
| 112 runCallback(id, deadlineMillis, callbackType); | |
| 113 } | |
| 114 | |
| 115 void ScriptedIdleTaskController::runCallback(CallbackId id, double deadlineMilli s, IdleCallbackDeadline::CallbackType callbackType) | |
| 116 { | |
| 117 ASSERT(!m_suspended); | |
| 118 auto callback = m_callbacks.take(id); | |
| 119 if (!callback) | |
| 120 return; | |
| 121 | |
| 122 // TODO(rmcilroy): Add devtools tracing. | |
| 123 callback->handleEvent(IdleCallbackDeadline::create(deadlineMillis, callbackT ype, m_timing)); | |
| 124 } | |
| 125 | |
| 126 void ScriptedIdleTaskController::stop() | |
| 127 { | |
| 128 m_callbacks.clear(); | |
| 129 } | |
| 130 | |
| 131 void ScriptedIdleTaskController::suspend() | |
| 132 { | |
| 133 m_suspended = true; | |
| 134 } | |
| 135 | |
| 136 void ScriptedIdleTaskController::resume() | |
| 137 { | |
| 138 ASSERT(m_suspended); | |
| 139 m_suspended = false; | |
| 140 | |
| 141 // Run any pending timeouts. | |
| 142 Vector<CallbackId> pendingTimeouts; | |
| 143 m_pendingTimeouts.swap(pendingTimeouts); | |
| 144 for (auto& id : pendingTimeouts) | |
| 145 runCallback(id, monotonicallyIncreasingTime(), IdleCallbackDeadline::Cal lbackType::CalledByTimeout); | |
| 146 | |
| 147 // Repost idle tasks for any remaining callbacks. | |
| 148 for (auto& callback : m_callbacks) { | |
| 149 RefPtr<internal::IdleRequestCallbackWrapper> callbackWrapper = internal: :IdleRequestCallbackWrapper::create(callback.key, this); | |
| 150 m_scheduler->postIdleTask(FROM_HERE, WTF::bind<double>(&internal::IdleRe questCallbackWrapper::idleTaskFired, callbackWrapper)); | |
| 151 } | |
| 152 } | |
| 153 | |
| 154 bool ScriptedIdleTaskController::hasPendingActivity() const | |
| 155 { | |
| 156 return !m_callbacks.isEmpty(); | |
| 157 } | |
| 158 | |
| 159 | |
| 160 | |
| 161 } // namespace blink | |
| OLD | NEW |