| 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/ThreadState.h" | 42 #include "platform/heap/ThreadState.h" |
| 45 #include "platform/weborigin/KURL.h" | 43 #include "platform/weborigin/KURL.h" |
| 46 #include "public/platform/Platform.h" | 44 #include "public/platform/Platform.h" |
| 47 #include "public/platform/WebThread.h" | 45 #include "public/platform/WebThread.h" |
| 48 #include "public/platform/WebWaitableEvent.h" | 46 #include "public/platform/WebWaitableEvent.h" |
| 49 #include "wtf/Noncopyable.h" | 47 #include "wtf/Noncopyable.h" |
| 50 #include "wtf/WeakPtr.h" | 48 #include "wtf/WeakPtr.h" |
| 51 #include "wtf/text/WTFString.h" | 49 #include "wtf/text/WTFString.h" |
| 52 | 50 |
| 53 #include <utility> | 51 #include <utility> |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 : m_closure(closure) | 147 : m_closure(closure) |
| 150 , m_weakFactory(this) | 148 , m_weakFactory(this) |
| 151 , m_taskCanceled(false) | 149 , m_taskCanceled(false) |
| 152 { } | 150 { } |
| 153 | 151 |
| 154 OwnPtr<Closure> m_closure; | 152 OwnPtr<Closure> m_closure; |
| 155 WeakPtrFactory<WorkerThreadCancelableTask> m_weakFactory; | 153 WeakPtrFactory<WorkerThreadCancelableTask> m_weakFactory; |
| 156 bool m_taskCanceled; | 154 bool m_taskCanceled; |
| 157 }; | 155 }; |
| 158 | 156 |
| 159 class WorkerSharedTimer : public SharedTimer { | |
| 160 public: | |
| 161 explicit WorkerSharedTimer(WorkerThread* workerThread) | |
| 162 : m_workerThread(workerThread) | |
| 163 , m_nextFireTime(0.0) | |
| 164 , m_running(false) | |
| 165 { } | |
| 166 | |
| 167 typedef void (*SharedTimerFunction)(); | |
| 168 virtual void setFiredFunction(SharedTimerFunction func) | |
| 169 { | |
| 170 m_sharedTimerFunction = func; | |
| 171 if (!m_sharedTimerFunction) | |
| 172 m_nextFireTime = 0.0; | |
| 173 } | |
| 174 | |
| 175 virtual void setFireInterval(double interval) | |
| 176 { | |
| 177 ASSERT(m_sharedTimerFunction); | |
| 178 | |
| 179 // See BlinkPlatformImpl::setSharedTimerFireInterval for explanation of | |
| 180 // why ceil is used in the interval calculation. | |
| 181 int64_t delay = static_cast<int64_t>(ceil(interval * 1000)); | |
| 182 | |
| 183 if (delay < 0) { | |
| 184 delay = 0; | |
| 185 m_nextFireTime = 0.0; | |
| 186 } | |
| 187 | |
| 188 m_running = true; | |
| 189 m_nextFireTime = currentTime() + interval; | |
| 190 | |
| 191 if (m_lastQueuedTask.get()) | |
| 192 m_lastQueuedTask->cancelTask(); | |
| 193 | |
| 194 // Now queue the task as a cancellable one. | |
| 195 OwnPtr<WorkerThreadCancelableTask> task = WorkerThreadCancelableTask::cr
eate(bind(&WorkerSharedTimer::OnTimeout, this)); | |
| 196 m_lastQueuedTask = task->createWeakPtr(); | |
| 197 m_workerThread->postDelayedTask(FROM_HERE, task.release(), delay); | |
| 198 } | |
| 199 | |
| 200 virtual void stop() | |
| 201 { | |
| 202 m_running = false; | |
| 203 m_lastQueuedTask = nullptr; | |
| 204 } | |
| 205 | |
| 206 double nextFireTime() { return m_nextFireTime; } | |
| 207 | |
| 208 private: | |
| 209 void OnTimeout() | |
| 210 { | |
| 211 ASSERT(m_workerThread->workerGlobalScope()); | |
| 212 | |
| 213 m_lastQueuedTask = nullptr; | |
| 214 | |
| 215 if (m_sharedTimerFunction && m_running && !m_workerThread->workerGlobalS
cope()->isClosing()) | |
| 216 m_sharedTimerFunction(); | |
| 217 } | |
| 218 | |
| 219 WorkerThread* m_workerThread; | |
| 220 SharedTimerFunction m_sharedTimerFunction; | |
| 221 double m_nextFireTime; | |
| 222 bool m_running; | |
| 223 | |
| 224 // The task to run OnTimeout, if any. While OnTimeout resets | |
| 225 // m_lastQueuedTask, this must be a weak pointer because the | |
| 226 // worker runloop may delete the task as it is shutting down. | |
| 227 WeakPtr<WorkerThreadCancelableTask> m_lastQueuedTask; | |
| 228 }; | |
| 229 | |
| 230 class WorkerThreadTask : public blink::WebThread::Task { | 157 class WorkerThreadTask : public blink::WebThread::Task { |
| 231 WTF_MAKE_NONCOPYABLE(WorkerThreadTask); WTF_MAKE_FAST_ALLOCATED; | 158 WTF_MAKE_NONCOPYABLE(WorkerThreadTask); WTF_MAKE_FAST_ALLOCATED; |
| 232 public: | 159 public: |
| 233 static PassOwnPtr<WorkerThreadTask> create(WorkerThread& workerThread, PassO
wnPtr<ExecutionContextTask> task, bool isInstrumented) | 160 static PassOwnPtr<WorkerThreadTask> create(WorkerThread& workerThread, PassO
wnPtr<ExecutionContextTask> task, bool isInstrumented) |
| 234 { | 161 { |
| 235 return adoptPtr(new WorkerThreadTask(workerThread, task, isInstrumented)
); | 162 return adoptPtr(new WorkerThreadTask(workerThread, task, isInstrumented)
); |
| 236 } | 163 } |
| 237 | 164 |
| 238 virtual ~WorkerThreadTask() { } | 165 virtual ~WorkerThreadTask() { } |
| 239 | 166 |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 m_workerReportingProxy.workerThreadTerminated(); | 276 m_workerReportingProxy.workerThreadTerminated(); |
| 350 return; | 277 return; |
| 351 } | 278 } |
| 352 | 279 |
| 353 m_microtaskRunner = adoptPtr(new MicrotaskRunner(this)); | 280 m_microtaskRunner = adoptPtr(new MicrotaskRunner(this)); |
| 354 m_thread->addTaskObserver(m_microtaskRunner.get()); | 281 m_thread->addTaskObserver(m_microtaskRunner.get()); |
| 355 m_thread->attachGC(); | 282 m_thread->attachGC(); |
| 356 | 283 |
| 357 m_isolate = initializeIsolate(); | 284 m_isolate = initializeIsolate(); |
| 358 m_workerGlobalScope = createWorkerGlobalScope(m_startupData.release()); | 285 m_workerGlobalScope = createWorkerGlobalScope(m_startupData.release()); |
| 359 | |
| 360 m_sharedTimer = adoptPtr(new WorkerSharedTimer(this)); | |
| 361 PlatformThreadData::current().threadTimers().setSharedTimer(m_sharedTime
r.get()); | |
| 362 } | 286 } |
| 363 | 287 |
| 364 // The corresponding call to stopRunLoop() is in ~WorkerScriptController(). | 288 // The corresponding call to stopRunLoop() is in ~WorkerScriptController(). |
| 365 didStartRunLoop(); | 289 didStartRunLoop(); |
| 366 | 290 |
| 367 // Notify proxy that a new WorkerGlobalScope has been created and started. | 291 // Notify proxy that a new WorkerGlobalScope has been created and started. |
| 368 m_workerReportingProxy.workerGlobalScopeStarted(m_workerGlobalScope.get()); | 292 m_workerReportingProxy.workerGlobalScopeStarted(m_workerGlobalScope.get()); |
| 369 | 293 |
| 370 WorkerScriptController* script = m_workerGlobalScope->script(); | 294 WorkerScriptController* script = m_workerGlobalScope->script(); |
| 371 if (!script->isExecutionForbidden()) | 295 if (!script->isExecutionForbidden()) |
| (...skipping 27 matching lines...) Expand all Loading... |
| 399 m_thread->detachGC(); | 323 m_thread->detachGC(); |
| 400 | 324 |
| 401 m_thread->removeTaskObserver(m_microtaskRunner.get()); | 325 m_thread->removeTaskObserver(m_microtaskRunner.get()); |
| 402 m_microtaskRunner = nullptr; | 326 m_microtaskRunner = nullptr; |
| 403 | 327 |
| 404 // Notify the proxy that the WorkerGlobalScope has been disposed of. | 328 // Notify the proxy that the WorkerGlobalScope has been disposed of. |
| 405 // This can free this thread object, hence it must not be touched afterwards
. | 329 // This can free this thread object, hence it must not be touched afterwards
. |
| 406 workerReportingProxy().workerThreadTerminated(); | 330 workerReportingProxy().workerThreadTerminated(); |
| 407 | 331 |
| 408 m_terminationEvent->signal(); | 332 m_terminationEvent->signal(); |
| 409 | |
| 410 // Clean up PlatformThreadData before WTF::WTFThreadData goes away! | |
| 411 PlatformThreadData::current().destroy(); | |
| 412 } | 333 } |
| 413 | 334 |
| 414 class WorkerThreadShutdownFinishTask : public ExecutionContextTask { | 335 class WorkerThreadShutdownFinishTask : public ExecutionContextTask { |
| 415 public: | 336 public: |
| 416 static PassOwnPtr<WorkerThreadShutdownFinishTask> create() | 337 static PassOwnPtr<WorkerThreadShutdownFinishTask> create() |
| 417 { | 338 { |
| 418 return adoptPtr(new WorkerThreadShutdownFinishTask()); | 339 return adoptPtr(new WorkerThreadShutdownFinishTask()); |
| 419 } | 340 } |
| 420 | 341 |
| 421 virtual void performTask(ExecutionContext *context) | 342 virtual void performTask(ExecutionContext *context) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 436 public: | 357 public: |
| 437 static PassOwnPtr<WorkerThreadShutdownStartTask> create() | 358 static PassOwnPtr<WorkerThreadShutdownStartTask> create() |
| 438 { | 359 { |
| 439 return adoptPtr(new WorkerThreadShutdownStartTask()); | 360 return adoptPtr(new WorkerThreadShutdownStartTask()); |
| 440 } | 361 } |
| 441 | 362 |
| 442 virtual void performTask(ExecutionContext *context) | 363 virtual void performTask(ExecutionContext *context) |
| 443 { | 364 { |
| 444 WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context); | 365 WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context); |
| 445 workerGlobalScope->stopActiveDOMObjects(); | 366 workerGlobalScope->stopActiveDOMObjects(); |
| 446 PlatformThreadData::current().threadTimers().setSharedTimer(nullptr); | |
| 447 | 367 |
| 448 // Event listeners would keep DOMWrapperWorld objects alive for too long
. Also, they have references to JS objects, | 368 // Event listeners would keep DOMWrapperWorld objects alive for too long
. Also, they have references to JS objects, |
| 449 // which become dangling once Heap is destroyed. | 369 // which become dangling once Heap is destroyed. |
| 450 workerGlobalScope->removeAllEventListeners(); | 370 workerGlobalScope->removeAllEventListeners(); |
| 451 | 371 |
| 452 // Stick a shutdown command at the end of the queue, so that we deal | 372 // Stick a shutdown command at the end of the queue, so that we deal |
| 453 // with all the cleanup tasks the databases post first. | 373 // with all the cleanup tasks the databases post first. |
| 454 workerGlobalScope->postTask(FROM_HERE, WorkerThreadShutdownFinishTask::c
reate()); | 374 workerGlobalScope->postTask(FROM_HERE, WorkerThreadShutdownFinishTask::c
reate()); |
| 455 } | 375 } |
| 456 | 376 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 544 { | 464 { |
| 545 return m_thread && m_thread->isCurrentThread(); | 465 return m_thread && m_thread->isCurrentThread(); |
| 546 } | 466 } |
| 547 | 467 |
| 548 void WorkerThread::idleHandler() | 468 void WorkerThread::idleHandler() |
| 549 { | 469 { |
| 550 ASSERT(m_workerGlobalScope.get()); | 470 ASSERT(m_workerGlobalScope.get()); |
| 551 int64_t delay = kLongIdleHandlerDelayMs; | 471 int64_t delay = kLongIdleHandlerDelayMs; |
| 552 | 472 |
| 553 // Do a script engine idle notification if the next event is distant enough. | 473 // Do a script engine idle notification if the next event is distant enough. |
| 554 const double kMinIdleTimespan = 0.3; | 474 /* const double kMinIdleTimespan = 0.3; |
| 555 if (m_sharedTimer->nextFireTime() == 0.0 || m_sharedTimer->nextFireTime() >
currentTime() + kMinIdleTimespan) { | 475 if (m_sharedTimer->nextFireTime() == 0.0 || m_sharedTimer->nextFireTime() >
currentTime() + kMinIdleTimespan) { |
| 556 bool hasMoreWork = !m_workerGlobalScope->idleNotification(); | 476 bool hasMoreWork = !m_workerGlobalScope->idleNotification(); |
| 557 if (hasMoreWork) | 477 if (hasMoreWork) |
| 558 delay = kShortIdleHandlerDelayMs; | 478 delay = kShortIdleHandlerDelayMs; |
| 559 } | 479 }*/ |
| 560 | 480 |
| 561 postDelayedTask(FROM_HERE, createSameThreadTask(&WorkerThread::idleHandler,
this), delay); | 481 postDelayedTask(FROM_HERE, createSameThreadTask(&WorkerThread::idleHandler,
this), delay); |
| 562 } | 482 } |
| 563 | 483 |
| 564 void WorkerThread::postTask(const WebTraceLocation& location, PassOwnPtr<Executi
onContextTask> task) | 484 void WorkerThread::postTask(const WebTraceLocation& location, PassOwnPtr<Executi
onContextTask> task) |
| 565 { | 485 { |
| 566 m_thread->postTask(location, WorkerThreadTask::create(*this, task, true).lea
kPtr()); | 486 m_thread->postTask(location, WorkerThreadTask::create(*this, task, true).lea
kPtr()); |
| 567 } | 487 } |
| 568 | 488 |
| 569 void WorkerThread::postDelayedTask(const WebTraceLocation& location, PassOwnPtr<
ExecutionContextTask> task, long long delayMs) | 489 void WorkerThread::postDelayedTask(const WebTraceLocation& location, PassOwnPtr<
ExecutionContextTask> task, long long delayMs) |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 629 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); | 549 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); |
| 630 } | 550 } |
| 631 | 551 |
| 632 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke
rInspectorController) | 552 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke
rInspectorController) |
| 633 { | 553 { |
| 634 MutexLocker locker(m_workerInspectorControllerMutex); | 554 MutexLocker locker(m_workerInspectorControllerMutex); |
| 635 m_workerInspectorController = workerInspectorController; | 555 m_workerInspectorController = workerInspectorController; |
| 636 } | 556 } |
| 637 | 557 |
| 638 } // namespace blink | 558 } // namespace blink |
| OLD | NEW |