OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. | 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 20 matching lines...) Expand all Loading... | |
31 #include "bindings/core/v8/ScriptSourceCode.h" | 31 #include "bindings/core/v8/ScriptSourceCode.h" |
32 #include "bindings/core/v8/V8GCController.h" | 32 #include "bindings/core/v8/V8GCController.h" |
33 #include "bindings/core/v8/V8Initializer.h" | 33 #include "bindings/core/v8/V8Initializer.h" |
34 #include "core/dom/Microtask.h" | 34 #include "core/dom/Microtask.h" |
35 #include "core/inspector/InspectorInstrumentation.h" | 35 #include "core/inspector/InspectorInstrumentation.h" |
36 #include "core/inspector/WorkerInspectorController.h" | 36 #include "core/inspector/WorkerInspectorController.h" |
37 #include "core/workers/DedicatedWorkerGlobalScope.h" | 37 #include "core/workers/DedicatedWorkerGlobalScope.h" |
38 #include "core/workers/WorkerClients.h" | 38 #include "core/workers/WorkerClients.h" |
39 #include "core/workers/WorkerReportingProxy.h" | 39 #include "core/workers/WorkerReportingProxy.h" |
40 #include "core/workers/WorkerThreadStartupData.h" | 40 #include "core/workers/WorkerThreadStartupData.h" |
41 #include "platform/PlatformThreadData.h" | |
42 #include "platform/Task.h" | 41 #include "platform/Task.h" |
43 #include "platform/ThreadTimers.h" | |
44 #include "platform/heap/SafePoint.h" | 42 #include "platform/heap/SafePoint.h" |
45 #include "platform/heap/ThreadState.h" | 43 #include "platform/heap/ThreadState.h" |
46 #include "platform/weborigin/KURL.h" | 44 #include "platform/weborigin/KURL.h" |
47 #include "public/platform/Platform.h" | 45 #include "public/platform/Platform.h" |
48 #include "public/platform/WebThread.h" | 46 #include "public/platform/WebThread.h" |
49 #include "public/platform/WebWaitableEvent.h" | 47 #include "public/platform/WebWaitableEvent.h" |
50 #include "wtf/Noncopyable.h" | 48 #include "wtf/Noncopyable.h" |
51 #include "wtf/WeakPtr.h" | 49 #include "wtf/WeakPtr.h" |
52 #include "wtf/text/WTFString.h" | 50 #include "wtf/text/WTFString.h" |
53 | 51 |
54 namespace blink { | 52 namespace blink { |
55 | 53 |
56 namespace { | 54 namespace { |
57 const int64_t kShortIdleHandlerDelayMs = 1000; | |
58 const int64_t kLongIdleHandlerDelayMs = 10*1000; | |
59 | 55 |
60 class MicrotaskRunner : public WebThread::TaskObserver { | 56 class MicrotaskRunner : public WebThread::TaskObserver { |
61 public: | 57 public: |
62 explicit MicrotaskRunner(WorkerThread* workerThread) | 58 explicit MicrotaskRunner(WorkerThread* workerThread) |
63 : m_workerThread(workerThread) | 59 : m_workerThread(workerThread) |
64 { | 60 { |
65 } | 61 } |
66 | 62 |
67 virtual void willProcessTask() override { } | 63 virtual void willProcessTask() override { } |
68 virtual void didProcessTask() override | 64 virtual void didProcessTask() override |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
124 : m_closure(closure) | 120 : m_closure(closure) |
125 , m_weakFactory(this) | 121 , m_weakFactory(this) |
126 , m_taskCanceled(false) | 122 , m_taskCanceled(false) |
127 { } | 123 { } |
128 | 124 |
129 OwnPtr<Closure> m_closure; | 125 OwnPtr<Closure> m_closure; |
130 WeakPtrFactory<WorkerThreadCancelableTask> m_weakFactory; | 126 WeakPtrFactory<WorkerThreadCancelableTask> m_weakFactory; |
131 bool m_taskCanceled; | 127 bool m_taskCanceled; |
132 }; | 128 }; |
133 | 129 |
134 class WorkerSharedTimer : public SharedTimer { | |
135 public: | |
136 explicit WorkerSharedTimer(WorkerThread* workerThread) | |
137 : m_workerThread(workerThread) | |
138 , m_running(false) | |
139 { } | |
140 | |
141 typedef void (*SharedTimerFunction)(); | |
142 virtual void setFiredFunction(SharedTimerFunction func) | |
143 { | |
144 m_sharedTimerFunction = func; | |
145 } | |
146 | |
147 virtual void setFireInterval(double interval) | |
148 { | |
149 ASSERT(m_sharedTimerFunction); | |
150 | |
151 // See BlinkPlatformImpl::setSharedTimerFireInterval for explanation of | |
152 // why ceil is used in the interval calculation. | |
153 int64_t delay = static_cast<int64_t>(ceil(interval * 1000)); | |
154 | |
155 if (delay < 0) { | |
156 delay = 0; | |
157 } | |
158 | |
159 m_running = true; | |
160 | |
161 if (m_lastQueuedTask.get()) | |
162 m_lastQueuedTask->cancelTask(); | |
163 | |
164 // Now queue the task as a cancellable one. | |
165 OwnPtr<WorkerThreadCancelableTask> task = WorkerThreadCancelableTask::cr eate(bind(&WorkerSharedTimer::OnTimeout, this)); | |
166 m_lastQueuedTask = task->createWeakPtr(); | |
167 m_workerThread->postDelayedTask(FROM_HERE, task.release(), delay); | |
168 } | |
169 | |
170 virtual void stop() | |
171 { | |
172 m_running = false; | |
173 m_lastQueuedTask = nullptr; | |
174 } | |
175 | |
176 private: | |
177 void OnTimeout() | |
178 { | |
179 ASSERT(m_workerThread->workerGlobalScope()); | |
180 | |
181 m_lastQueuedTask = nullptr; | |
182 | |
183 if (m_sharedTimerFunction && m_running && !m_workerThread->workerGlobalS cope()->isClosing()) | |
184 m_sharedTimerFunction(); | |
185 } | |
186 | |
187 WorkerThread* m_workerThread; | |
188 SharedTimerFunction m_sharedTimerFunction; | |
189 bool m_running; | |
190 | |
191 // The task to run OnTimeout, if any. While OnTimeout resets | |
192 // m_lastQueuedTask, this must be a weak pointer because the | |
193 // worker runloop may delete the task as it is shutting down. | |
194 WeakPtr<WorkerThreadCancelableTask> m_lastQueuedTask; | |
195 }; | |
196 | |
197 class WorkerThreadTask : public blink::WebThread::Task { | 130 class WorkerThreadTask : public blink::WebThread::Task { |
198 WTF_MAKE_NONCOPYABLE(WorkerThreadTask); WTF_MAKE_FAST_ALLOCATED(WorkerThread Task); | 131 WTF_MAKE_NONCOPYABLE(WorkerThreadTask); WTF_MAKE_FAST_ALLOCATED(WorkerThread Task); |
199 public: | 132 public: |
200 static PassOwnPtr<WorkerThreadTask> create(WorkerThread& workerThread, PassO wnPtr<ExecutionContextTask> task, bool isInstrumented) | 133 static PassOwnPtr<WorkerThreadTask> create(WorkerThread& workerThread, PassO wnPtr<ExecutionContextTask> task, bool isInstrumented) |
201 { | 134 { |
202 return adoptPtr(new WorkerThreadTask(workerThread, task, isInstrumented) ); | 135 return adoptPtr(new WorkerThreadTask(workerThread, task, isInstrumented) ); |
203 } | 136 } |
204 | 137 |
205 virtual ~WorkerThreadTask() { } | 138 virtual ~WorkerThreadTask() { } |
206 | 139 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
256 }; | 189 }; |
257 | 190 |
258 WorkerThread::WorkerThread(PassRefPtr<WorkerLoaderProxy> workerLoaderProxy, Work erReportingProxy& workerReportingProxy, PassOwnPtr<WorkerThreadStartupData> star tupData) | 191 WorkerThread::WorkerThread(PassRefPtr<WorkerLoaderProxy> workerLoaderProxy, Work erReportingProxy& workerReportingProxy, PassOwnPtr<WorkerThreadStartupData> star tupData) |
259 : m_terminated(false) | 192 : m_terminated(false) |
260 , m_workerLoaderProxy(workerLoaderProxy) | 193 , m_workerLoaderProxy(workerLoaderProxy) |
261 , m_workerReportingProxy(workerReportingProxy) | 194 , m_workerReportingProxy(workerReportingProxy) |
262 , m_startupData(startupData) | 195 , m_startupData(startupData) |
263 , m_isolate(nullptr) | 196 , m_isolate(nullptr) |
264 , m_shutdownEvent(adoptPtr(blink::Platform::current()->createWaitableEvent() )) | 197 , m_shutdownEvent(adoptPtr(blink::Platform::current()->createWaitableEvent() )) |
265 , m_terminationEvent(adoptPtr(blink::Platform::current()->createWaitableEven t())) | 198 , m_terminationEvent(adoptPtr(blink::Platform::current()->createWaitableEven t())) |
199 , m_minQuietPeriodMsBeforeDoingIdleGc(300ul) | |
200 , m_dontStartIdleTaskYet(false) | |
266 { | 201 { |
267 MutexLocker lock(threadSetMutex()); | 202 MutexLocker lock(threadSetMutex()); |
268 workerThreads().add(this); | 203 workerThreads().add(this); |
269 } | 204 } |
270 | 205 |
271 WorkerThread::~WorkerThread() | 206 WorkerThread::~WorkerThread() |
272 { | 207 { |
273 MutexLocker lock(threadSetMutex()); | 208 MutexLocker lock(threadSetMutex()); |
274 ASSERT(workerThreads().contains(this)); | 209 ASSERT(workerThreads().contains(this)); |
275 workerThreads().remove(this); | 210 workerThreads().remove(this); |
(...skipping 15 matching lines...) Expand all Loading... | |
291 m_workerInspectorController->interruptAndDispatchInspectorCommands(); | 226 m_workerInspectorController->interruptAndDispatchInspectorCommands(); |
292 } | 227 } |
293 | 228 |
294 PlatformThreadId WorkerThread::platformThreadId() const | 229 PlatformThreadId WorkerThread::platformThreadId() const |
295 { | 230 { |
296 if (!m_thread) | 231 if (!m_thread) |
297 return 0; | 232 return 0; |
298 return m_thread->platformThread().threadId(); | 233 return m_thread->platformThread().threadId(); |
299 } | 234 } |
300 | 235 |
236 // TODO(scheduler-dev): Ideally the WorkerScheduler should determine Quiescence rather than doing it here. | |
Sami
2015/04/09 10:52:29
nit: I think we should use real usernames for TODO
alex clarke (OOO till 29th)
2015/04/10 15:29:35
Acknowledged.
| |
237 class WorkerThreadWaitUntilQuiescenceTask : public WebThread::Task, public WebTh read::IdleTask { | |
238 public: | |
239 explicit WorkerThreadWaitUntilQuiescenceTask(WorkerThread* thread) : m_threa d(thread) { } | |
240 | |
241 ~WorkerThreadWaitUntilQuiescenceTask() override | |
242 { | |
243 } | |
244 | |
245 void run() override | |
246 { | |
247 m_thread->maybeStartIdleTask(); | |
248 } | |
249 | |
250 void run(double) override | |
251 { | |
252 m_thread->dontStartIdleTaskYet(); | |
253 } | |
254 | |
255 private: | |
256 RawPtr<WorkerThread> m_thread; | |
257 }; | |
258 | |
259 class WorkerThreadIdleTask : public WebThread::IdleTask { | |
260 public: | |
261 explicit WorkerThreadIdleTask(WorkerThread* thread) | |
262 : m_thread(thread) { } | |
263 | |
264 ~WorkerThreadIdleTask() override { } | |
265 | |
266 void run(double deadlineSeconds) override | |
267 { | |
268 m_thread->idleTask(deadlineSeconds); | |
269 } | |
270 | |
271 private: | |
272 RawPtr<WorkerThread> m_thread; | |
273 }; | |
274 | |
275 class WorkerThreadWakeupIdleTask : public WebThread::IdleTask { | |
276 public: | |
277 explicit WorkerThreadWakeupIdleTask(WorkerThread* thread) | |
278 : m_thread(thread) { } | |
279 | |
280 ~WorkerThreadWakeupIdleTask() override { } | |
281 | |
282 void run(double) override | |
283 { | |
284 m_thread->dontStartIdleTaskYet(); | |
285 m_thread->maybeStartIdleTask(); | |
286 } | |
287 | |
288 private: | |
289 RawPtr<WorkerThread> m_thread; | |
290 }; | |
291 | |
301 void WorkerThread::initialize() | 292 void WorkerThread::initialize() |
302 { | 293 { |
303 KURL scriptURL = m_startupData->m_scriptURL; | 294 KURL scriptURL = m_startupData->m_scriptURL; |
304 String sourceCode = m_startupData->m_sourceCode; | 295 String sourceCode = m_startupData->m_sourceCode; |
305 WorkerThreadStartMode startMode = m_startupData->m_startMode; | 296 WorkerThreadStartMode startMode = m_startupData->m_startMode; |
306 OwnPtr<Vector<char>> cachedMetaData = m_startupData->m_cachedMetaData.releas e(); | 297 OwnPtr<Vector<char>> cachedMetaData = m_startupData->m_cachedMetaData.releas e(); |
307 V8CacheOptions v8CacheOptions = m_startupData->m_v8CacheOptions; | 298 V8CacheOptions v8CacheOptions = m_startupData->m_v8CacheOptions; |
308 | 299 |
309 { | 300 { |
310 MutexLocker lock(m_threadCreationMutex); | 301 MutexLocker lock(m_threadCreationMutex); |
311 | 302 |
312 // The worker was terminated before the thread had a chance to run. | 303 // The worker was terminated before the thread had a chance to run. |
313 if (m_terminated) { | 304 if (m_terminated) { |
314 // Notify the proxy that the WorkerGlobalScope has been disposed of. | 305 // Notify the proxy that the WorkerGlobalScope has been disposed of. |
315 // This can free this thread object, hence it must not be touched af terwards. | 306 // This can free this thread object, hence it must not be touched af terwards. |
316 m_workerReportingProxy.workerThreadTerminated(); | 307 m_workerReportingProxy.workerThreadTerminated(); |
317 return; | 308 return; |
318 } | 309 } |
319 | 310 |
320 m_microtaskRunner = adoptPtr(new MicrotaskRunner(this)); | 311 m_microtaskRunner = adoptPtr(new MicrotaskRunner(this)); |
321 m_thread->addTaskObserver(m_microtaskRunner.get()); | 312 m_thread->addTaskObserver(m_microtaskRunner.get()); |
322 m_thread->attachGC(); | 313 m_thread->attachGC(); |
323 | 314 |
324 m_isolate = initializeIsolate(); | 315 m_isolate = initializeIsolate(); |
325 m_workerGlobalScope = createWorkerGlobalScope(m_startupData.release()); | 316 m_workerGlobalScope = createWorkerGlobalScope(m_startupData.release()); |
326 m_workerGlobalScope->scriptLoaded(sourceCode.length(), cachedMetaData.ge t() ? cachedMetaData->size() : 0); | 317 m_workerGlobalScope->scriptLoaded(sourceCode.length(), cachedMetaData.ge t() ? cachedMetaData->size() : 0); |
327 | |
328 PlatformThreadData::current().threadTimers().setSharedTimer(adoptPtr(new WorkerSharedTimer(this))); | |
329 } | 318 } |
330 | 319 |
331 // The corresponding call to stopRunLoop() is in ~WorkerScriptController(). | 320 // The corresponding call to stopRunLoop() is in ~WorkerScriptController(). |
332 didStartRunLoop(); | 321 didStartRunLoop(); |
333 | 322 |
334 // Notify proxy that a new WorkerGlobalScope has been created and started. | 323 // Notify proxy that a new WorkerGlobalScope has been created and started. |
335 m_workerReportingProxy.workerGlobalScopeStarted(m_workerGlobalScope.get()); | 324 m_workerReportingProxy.workerGlobalScopeStarted(m_workerGlobalScope.get()); |
336 | 325 |
337 WorkerScriptController* script = m_workerGlobalScope->script(); | 326 WorkerScriptController* script = m_workerGlobalScope->script(); |
338 if (!script->isExecutionForbidden()) | 327 if (!script->isExecutionForbidden()) |
339 script->initializeContextIfNeeded(); | 328 script->initializeContextIfNeeded(); |
340 if (startMode == PauseWorkerGlobalScopeOnStart) | 329 if (startMode == PauseWorkerGlobalScopeOnStart) |
341 m_workerGlobalScope->workerInspectorController()->pauseOnStart(); | 330 m_workerGlobalScope->workerInspectorController()->pauseOnStart(); |
342 | 331 |
343 OwnPtr<CachedMetadataHandler> handler(workerGlobalScope()->createWorkerScrip tCachedMetadataHandler(scriptURL, cachedMetaData.get())); | 332 OwnPtr<CachedMetadataHandler> handler(workerGlobalScope()->createWorkerScrip tCachedMetadataHandler(scriptURL, cachedMetaData.get())); |
344 bool success = script->evaluate(ScriptSourceCode(sourceCode, scriptURL), nul lptr, handler.get(), v8CacheOptions); | 333 bool success = script->evaluate(ScriptSourceCode(sourceCode, scriptURL), nul lptr, handler.get(), v8CacheOptions); |
345 m_workerGlobalScope->didEvaluateWorkerScript(); | 334 m_workerGlobalScope->didEvaluateWorkerScript(); |
346 m_workerReportingProxy.didEvaluateWorkerScript(success); | 335 m_workerReportingProxy.didEvaluateWorkerScript(success); |
347 | 336 |
348 postInitialize(); | 337 postInitialize(); |
349 | 338 |
350 postDelayedTask(FROM_HERE, createSameThreadTask(&WorkerThread::idleHandler, this), kShortIdleHandlerDelayMs); | 339 dontStartIdleTaskYet(); |
340 maybeStartIdleTask(); | |
Sami
2015/04/09 10:52:29
This reads a little poorly ("don't do idle ... oh
alex clarke (OOO till 29th)
2015/04/10 15:29:36
Acknowledged.
| |
351 } | 341 } |
352 | 342 |
353 PassOwnPtr<WebThreadSupportingGC> WorkerThread::createWebThreadSupportingGC() | 343 PassOwnPtr<WebThreadSupportingGC> WorkerThread::createWebThreadSupportingGC() |
354 { | 344 { |
355 return WebThreadSupportingGC::create("WebCore: Worker"); | 345 return WebThreadSupportingGC::create("WebCore: Worker"); |
356 } | 346 } |
357 | 347 |
358 void WorkerThread::cleanup() | 348 void WorkerThread::cleanup() |
359 { | 349 { |
360 // This should be called before we start the shutdown procedure. | 350 // This should be called before we start the shutdown procedure. |
(...skipping 12 matching lines...) Expand all Loading... | |
373 destroyIsolate(); | 363 destroyIsolate(); |
374 | 364 |
375 m_thread->removeTaskObserver(m_microtaskRunner.get()); | 365 m_thread->removeTaskObserver(m_microtaskRunner.get()); |
376 m_microtaskRunner = nullptr; | 366 m_microtaskRunner = nullptr; |
377 | 367 |
378 // Notify the proxy that the WorkerGlobalScope has been disposed of. | 368 // Notify the proxy that the WorkerGlobalScope has been disposed of. |
379 // This can free this thread object, hence it must not be touched afterwards . | 369 // This can free this thread object, hence it must not be touched afterwards . |
380 workerReportingProxy().workerThreadTerminated(); | 370 workerReportingProxy().workerThreadTerminated(); |
381 | 371 |
382 m_terminationEvent->signal(); | 372 m_terminationEvent->signal(); |
383 | |
384 // Clean up PlatformThreadData before WTF::WTFThreadData goes away! | |
385 PlatformThreadData::current().destroy(); | |
386 } | 373 } |
387 | 374 |
388 class WorkerThreadShutdownFinishTask : public ExecutionContextTask { | 375 class WorkerThreadShutdownFinishTask : public ExecutionContextTask { |
389 public: | 376 public: |
390 static PassOwnPtr<WorkerThreadShutdownFinishTask> create() | 377 static PassOwnPtr<WorkerThreadShutdownFinishTask> create() |
391 { | 378 { |
392 return adoptPtr(new WorkerThreadShutdownFinishTask()); | 379 return adoptPtr(new WorkerThreadShutdownFinishTask()); |
393 } | 380 } |
394 | 381 |
395 virtual void performTask(ExecutionContext *context) | 382 virtual void performTask(ExecutionContext *context) |
(...skipping 14 matching lines...) Expand all Loading... | |
410 public: | 397 public: |
411 static PassOwnPtr<WorkerThreadShutdownStartTask> create() | 398 static PassOwnPtr<WorkerThreadShutdownStartTask> create() |
412 { | 399 { |
413 return adoptPtr(new WorkerThreadShutdownStartTask()); | 400 return adoptPtr(new WorkerThreadShutdownStartTask()); |
414 } | 401 } |
415 | 402 |
416 virtual void performTask(ExecutionContext *context) | 403 virtual void performTask(ExecutionContext *context) |
417 { | 404 { |
418 WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context); | 405 WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context); |
419 workerGlobalScope->stopActiveDOMObjects(); | 406 workerGlobalScope->stopActiveDOMObjects(); |
420 PlatformThreadData::current().threadTimers().setSharedTimer(nullptr); | |
421 | 407 |
422 // Event listeners would keep DOMWrapperWorld objects alive for too long . Also, they have references to JS objects, | 408 // Event listeners would keep DOMWrapperWorld objects alive for too long . Also, they have references to JS objects, |
423 // which become dangling once Heap is destroyed. | 409 // which become dangling once Heap is destroyed. |
424 workerGlobalScope->removeAllEventListeners(); | 410 workerGlobalScope->removeAllEventListeners(); |
425 | 411 |
426 // Stick a shutdown command at the end of the queue, so that we deal | 412 // Stick a shutdown command at the end of the queue, so that we deal |
427 // with all the cleanup tasks the databases post first. | 413 // with all the cleanup tasks the databases post first. |
428 workerGlobalScope->postTask(FROM_HERE, WorkerThreadShutdownFinishTask::c reate()); | 414 workerGlobalScope->postTask(FROM_HERE, WorkerThreadShutdownFinishTask::c reate()); |
429 } | 415 } |
430 | 416 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
502 | 488 |
503 for (WorkerThread* thread : threads) | 489 for (WorkerThread* thread : threads) |
504 thread->terminationEvent()->wait(); | 490 thread->terminationEvent()->wait(); |
505 } | 491 } |
506 | 492 |
507 bool WorkerThread::isCurrentThread() const | 493 bool WorkerThread::isCurrentThread() const |
508 { | 494 { |
509 return m_thread && m_thread->isCurrentThread(); | 495 return m_thread && m_thread->isCurrentThread(); |
510 } | 496 } |
511 | 497 |
512 void WorkerThread::idleHandler() | 498 void WorkerThread::dontStartIdleTaskYet() |
513 { | 499 { |
514 ASSERT(m_workerGlobalScope.get()); | 500 m_dontStartIdleTaskYet = true; |
515 int64_t delay = kLongIdleHandlerDelayMs; | 501 } |
516 | 502 |
517 // Do a script engine idle notification if the next event is distant enough. | 503 void WorkerThread::maybeStartIdleTask() |
518 const double kMinIdleTimespan = 0.3; | 504 { |
519 const double nextFireTime = PlatformThreadData::current().threadTimers().nex tFireTime(); | 505 if (m_dontStartIdleTaskYet) { |
520 if (nextFireTime == 0.0 || nextFireTime > currentTime() + kMinIdleTimespan) { | 506 // We don't want to be too quick to enter idle mode (where we start doin g more GC) because |
521 bool hasMoreWork = !isolate()->IdleNotificationDeadline(Platform::curren t()->monotonicallyIncreasingTime() + 1.0); | 507 // that might cause the worker thread to be unresponsive to messages. T o avoid this we |
522 if (hasMoreWork) | 508 // check every |m_minQuietPeriodMsBeforeDoingIdleGc| if any tasks have b een run. If they havent we can start doing idle GCs. |
Sami
2015/04/09 10:52:29
s/havent/haven't/
alex clarke (OOO till 29th)
2015/04/10 15:29:36
Acknowledged.
| |
523 delay = kShortIdleHandlerDelayMs; | 509 // NOTE we use the IdleTaskAfterWakeup call to work out if something has run. It's execution |
Sami
2015/04/09 10:52:29
nit: Its
alex clarke (OOO till 29th)
2015/04/10 15:29:35
Acknowledged.
| |
510 // only happens if some other task gets posted. | |
511 m_thread->postDelayedTask(FROM_HERE, new WorkerThreadWaitUntilQuiescence Task(this), m_minQuietPeriodMsBeforeDoingIdleGc); | |
512 m_thread->postIdleTaskAfterWakeup(FROM_HERE, new WorkerThreadWaitUntilQu iescenceTask(this)); | |
513 m_dontStartIdleTaskYet = false; | |
514 return; | |
524 } | 515 } |
525 | 516 |
526 postDelayedTask(FROM_HERE, createSameThreadTask(&WorkerThread::idleHandler, this), delay); | 517 m_thread->postIdleTask(FROM_HERE, new WorkerThreadIdleTask(this)); |
518 } | |
519 | |
520 void WorkerThread::idleTask(double deadlineSeconds) | |
521 { | |
522 if (doIdleGc(deadlineSeconds)) | |
523 m_thread->postIdleTaskAfterWakeup(FROM_HERE, new WorkerThreadWakeupIdleT ask(this)); | |
524 else | |
525 m_thread->postIdleTask(FROM_HERE, new WorkerThreadIdleTask(this)); | |
526 } | |
527 | |
528 bool WorkerThread::doIdleGc(double deadlineSeconds) | |
529 { | |
530 if (deadlineSeconds > Platform::current()->monotonicallyIncreasingTime()) | |
531 return isolate()->IdleNotificationDeadline(deadlineSeconds); | |
532 | |
533 return false; | |
527 } | 534 } |
528 | 535 |
529 void WorkerThread::postTask(const WebTraceLocation& location, PassOwnPtr<Executi onContextTask> task) | 536 void WorkerThread::postTask(const WebTraceLocation& location, PassOwnPtr<Executi onContextTask> task) |
530 { | 537 { |
531 m_thread->postTask(location, WorkerThreadTask::create(*this, task, true).lea kPtr()); | 538 m_thread->postTask(location, WorkerThreadTask::create(*this, task, true).lea kPtr()); |
532 } | 539 } |
533 | 540 |
534 void WorkerThread::postDelayedTask(const WebTraceLocation& location, PassOwnPtr< ExecutionContextTask> task, long long delayMs) | 541 void WorkerThread::postDelayedTask(const WebTraceLocation& location, PassOwnPtr< ExecutionContextTask> task, long long delayMs) |
535 { | 542 { |
536 m_thread->postDelayedTask(location, WorkerThreadTask::create(*this, task, tr ue).leakPtr(), delayMs); | 543 m_thread->postDelayedTask(location, WorkerThreadTask::create(*this, task, tr ue).leakPtr(), delayMs); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
610 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); | 617 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); |
611 } | 618 } |
612 | 619 |
613 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke rInspectorController) | 620 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke rInspectorController) |
614 { | 621 { |
615 MutexLocker locker(m_workerInspectorControllerMutex); | 622 MutexLocker locker(m_workerInspectorControllerMutex); |
616 m_workerInspectorController = workerInspectorController; | 623 m_workerInspectorController = workerInspectorController; |
617 } | 624 } |
618 | 625 |
619 } // namespace blink | 626 } // namespace blink |
OLD | NEW |