| 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 22 matching lines...) Expand all Loading... |
| 33 #include "core/dom/Microtask.h" | 33 #include "core/dom/Microtask.h" |
| 34 #include "core/inspector/InspectorInstrumentation.h" | 34 #include "core/inspector/InspectorInstrumentation.h" |
| 35 #include "core/inspector/WorkerInspectorController.h" | 35 #include "core/inspector/WorkerInspectorController.h" |
| 36 #include "core/workers/DedicatedWorkerGlobalScope.h" | 36 #include "core/workers/DedicatedWorkerGlobalScope.h" |
| 37 #include "core/workers/WorkerClients.h" | 37 #include "core/workers/WorkerClients.h" |
| 38 #include "core/workers/WorkerReportingProxy.h" | 38 #include "core/workers/WorkerReportingProxy.h" |
| 39 #include "core/workers/WorkerThreadStartupData.h" | 39 #include "core/workers/WorkerThreadStartupData.h" |
| 40 #include "platform/PlatformThreadData.h" | 40 #include "platform/PlatformThreadData.h" |
| 41 #include "platform/Task.h" | 41 #include "platform/Task.h" |
| 42 #include "platform/ThreadTimers.h" | 42 #include "platform/ThreadTimers.h" |
| 43 #include "platform/TraceEvent.h" |
| 43 #include "platform/heap/ThreadState.h" | 44 #include "platform/heap/ThreadState.h" |
| 44 #include "platform/weborigin/KURL.h" | 45 #include "platform/weborigin/KURL.h" |
| 45 #include "public/platform/Platform.h" | 46 #include "public/platform/Platform.h" |
| 46 #include "public/platform/WebThread.h" | 47 #include "public/platform/WebThread.h" |
| 47 #include "public/platform/WebWaitableEvent.h" | 48 #include "public/platform/WebWaitableEvent.h" |
| 48 #include "public/platform/WebWorkerRunLoop.h" | 49 #include "public/platform/WebWorkerRunLoop.h" |
| 49 #include "wtf/Noncopyable.h" | 50 #include "wtf/Noncopyable.h" |
| 50 #include "wtf/text/WTFString.h" | 51 #include "wtf/text/WTFString.h" |
| 51 | 52 |
| 52 #include <utility> | 53 #include <utility> |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 WorkerThread* m_thread; | 242 WorkerThread* m_thread; |
| 242 }; | 243 }; |
| 243 | 244 |
| 244 WorkerThread::WorkerThread(WorkerLoaderProxy& workerLoaderProxy, WorkerReporting
Proxy& workerReportingProxy, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData> sta
rtupData) | 245 WorkerThread::WorkerThread(WorkerLoaderProxy& workerLoaderProxy, WorkerReporting
Proxy& workerReportingProxy, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData> sta
rtupData) |
| 245 : m_terminated(false) | 246 : m_terminated(false) |
| 246 , m_workerLoaderProxy(workerLoaderProxy) | 247 , m_workerLoaderProxy(workerLoaderProxy) |
| 247 , m_workerReportingProxy(workerReportingProxy) | 248 , m_workerReportingProxy(workerReportingProxy) |
| 248 , m_startupData(startupData) | 249 , m_startupData(startupData) |
| 249 , m_shutdownEvent(adoptPtr(blink::Platform::current()->createWaitableEvent()
)) | 250 , m_shutdownEvent(adoptPtr(blink::Platform::current()->createWaitableEvent()
)) |
| 250 , m_terminationEvent(adoptPtr(blink::Platform::current()->createWaitableEven
t())) | 251 , m_terminationEvent(adoptPtr(blink::Platform::current()->createWaitableEven
t())) |
| 252 , m_teleporter(0) |
| 253 , m_compositorId(0) |
| 251 { | 254 { |
| 252 MutexLocker lock(threadSetMutex()); | 255 MutexLocker lock(threadSetMutex()); |
| 253 workerThreads().add(this); | 256 workerThreads().add(this); |
| 254 } | 257 } |
| 255 | 258 |
| 256 WorkerThread::~WorkerThread() | 259 WorkerThread::~WorkerThread() |
| 257 { | 260 { |
| 258 MutexLocker lock(threadSetMutex()); | 261 MutexLocker lock(threadSetMutex()); |
| 259 ASSERT(workerThreads().contains(this)); | 262 ASSERT(workerThreads().contains(this)); |
| 260 workerThreads().remove(this); | 263 workerThreads().remove(this); |
| 261 } | 264 } |
| 262 | 265 |
| 263 void WorkerThread::start() | 266 void WorkerThread::start() |
| 264 { | 267 { |
| 265 if (m_thread) | 268 if (thread()) |
| 266 return; | 269 return; |
| 267 | 270 |
| 268 m_thread = WebThreadSupportingGC::create("WebCore: Worker"); | 271 initializeWebThread(); |
| 269 m_thread->postTask(new Task(WTF::bind(&WorkerThread::initialize, this))); | 272 thread()->postTask(new Task(WTF::bind(&WorkerThread::initialize, this))); |
| 270 } | 273 } |
| 271 | 274 |
| 272 void WorkerThread::interruptAndDispatchInspectorCommands() | 275 void WorkerThread::interruptAndDispatchInspectorCommands() |
| 273 { | 276 { |
| 274 MutexLocker locker(m_workerInspectorControllerMutex); | 277 MutexLocker locker(m_workerInspectorControllerMutex); |
| 275 if (m_workerInspectorController) | 278 if (m_workerInspectorController) |
| 276 m_workerInspectorController->interruptAndDispatchInspectorCommands(); | 279 m_workerInspectorController->interruptAndDispatchInspectorCommands(); |
| 277 } | 280 } |
| 278 | 281 |
| 279 PlatformThreadId WorkerThread::platformThreadId() const | 282 PlatformThreadId WorkerThread::platformThreadId() const |
| 280 { | 283 { |
| 281 if (!m_thread) | 284 if (!m_thread) |
| 282 return 0; | 285 return 0; |
| 283 return m_thread->platformThread().threadId(); | 286 return m_thread->platformThread().threadId(); |
| 284 } | 287 } |
| 285 | 288 |
| 286 void WorkerThread::initialize() | 289 void WorkerThread::initialize() |
| 287 { | 290 { |
| 291 TRACE_EVENT0("teleport", "WorkerThread::initialize"); |
| 292 // fprintf(stderr, "right here\n"); |
| 288 KURL scriptURL = m_startupData->m_scriptURL; | 293 KURL scriptURL = m_startupData->m_scriptURL; |
| 289 String sourceCode = m_startupData->m_sourceCode; | 294 String sourceCode = m_startupData->m_sourceCode; |
| 290 WorkerThreadStartMode startMode = m_startupData->m_startMode; | 295 WorkerThreadStartMode startMode = m_startupData->m_startMode; |
| 296 m_compositorId = m_startupData->m_compositorId; |
| 291 | 297 |
| 292 { | 298 { |
| 293 MutexLocker lock(m_threadCreationMutex); | 299 MutexLocker lock(m_threadCreationMutex); |
| 294 | 300 |
| 295 // The worker was terminated before the thread had a chance to run. | 301 // The worker was terminated before the thread had a chance to run. |
| 296 if (m_terminated) { | 302 if (m_terminated) { |
| 297 // Notify the proxy that the WorkerGlobalScope has been disposed of. | 303 // Notify the proxy that the WorkerGlobalScope has been disposed of. |
| 298 // This can free this thread object, hence it must not be touched af
terwards. | 304 // This can free this thread object, hence it must not be touched af
terwards. |
| 299 m_workerReportingProxy.workerThreadTerminated(); | 305 m_workerReportingProxy.workerThreadTerminated(); |
| 300 return; | 306 return; |
| 301 } | 307 } |
| 302 | 308 |
| 303 m_microtaskRunner = adoptPtr(new MicrotaskRunner); | 309 m_microtaskRunner = adoptPtr(new MicrotaskRunner); |
| 304 m_thread->addTaskObserver(m_microtaskRunner.get()); | 310 thread()->addTaskObserver(m_microtaskRunner.get()); |
| 305 m_thread->attachGC(); | 311 thread()->attachGC(); |
| 306 m_workerGlobalScope = createWorkerGlobalScope(m_startupData.release()); | 312 m_workerGlobalScope = createWorkerGlobalScope(m_startupData.release()); |
| 307 | 313 |
| 308 m_sharedTimer = adoptPtr(new WorkerSharedTimer(this)); | 314 m_sharedTimer = adoptPtr(new WorkerSharedTimer(this)); |
| 309 PlatformThreadData::current().threadTimers().setSharedTimer(m_sharedTime
r.get()); | 315 PlatformThreadData::current().threadTimers().setSharedTimer(m_sharedTime
r.get()); |
| 310 } | 316 } |
| 311 | 317 |
| 312 // The corresponding call to didStopWorkerRunLoop is in | 318 // The corresponding call to didStopWorkerRunLoop is in |
| 313 // ~WorkerScriptController. | 319 // ~WorkerScriptController. |
| 314 blink::Platform::current()->didStartWorkerRunLoop(blink::WebWorkerRunLoop(th
is)); | 320 blink::Platform::current()->didStartWorkerRunLoop(getRunLoop()); |
| 315 | 321 |
| 316 // Notify proxy that a new WorkerGlobalScope has been created and started. | 322 // Notify proxy that a new WorkerGlobalScope has been created and started. |
| 317 m_workerReportingProxy.workerGlobalScopeStarted(m_workerGlobalScope.get()); | 323 m_workerReportingProxy.workerGlobalScopeStarted(m_workerGlobalScope.get()); |
| 318 | 324 |
| 319 WorkerScriptController* script = m_workerGlobalScope->script(); | 325 WorkerScriptController* script = m_workerGlobalScope->script(); |
| 320 if (!script->isExecutionForbidden()) | 326 if (!script->isExecutionForbidden()) |
| 321 script->initializeContextIfNeeded(); | 327 script->initializeContextIfNeeded(); |
| 322 InspectorInstrumentation::willEvaluateWorkerScript(workerGlobalScope(), star
tMode); | 328 InspectorInstrumentation::willEvaluateWorkerScript(workerGlobalScope(), star
tMode); |
| 323 script->evaluate(ScriptSourceCode(sourceCode, scriptURL)); | 329 script->evaluate(ScriptSourceCode(sourceCode, scriptURL)); |
| 324 m_workerGlobalScope->didEvaluateWorkerScript(); | 330 m_workerGlobalScope->didEvaluateWorkerScript(); |
| 325 | 331 |
| 326 postInitialize(); | 332 postInitialize(); |
| 327 | 333 |
| 328 postDelayedTask(createSameThreadTask(&WorkerThread::idleHandler, this), kSho
rtIdleHandlerDelayMs); | 334 postDelayedTask(createSameThreadTask(&WorkerThread::idleHandler, this), kSho
rtIdleHandlerDelayMs); |
| 329 } | 335 } |
| 330 | 336 |
| 337 blink::WebWorkerRunLoop WorkerThread::getRunLoop() { |
| 338 return blink::WebWorkerRunLoop(this); |
| 339 } |
| 340 |
| 331 void WorkerThread::cleanup() | 341 void WorkerThread::cleanup() |
| 332 { | 342 { |
| 333 | 343 |
| 334 // This should be called before we start the shutdown procedure. | 344 // This should be called before we start the shutdown procedure. |
| 335 workerReportingProxy().willDestroyWorkerGlobalScope(); | 345 workerReportingProxy().willDestroyWorkerGlobalScope(); |
| 336 | 346 |
| 337 // The below assignment will destroy the context, which will in turn notify
messaging proxy. | 347 // The below assignment will destroy the context, which will in turn notify
messaging proxy. |
| 338 // We cannot let any objects survive past thread exit, because no other thre
ad will run GC or otherwise destroy them. | 348 // We cannot let any objects survive past thread exit, because no other thre
ad will run GC or otherwise destroy them. |
| 339 // If Oilpan is enabled, we detach of the context/global scope, with the fin
al heap cleanup below sweeping it out. | 349 // If Oilpan is enabled, we detach of the context/global scope, with the fin
al heap cleanup below sweeping it out. |
| 340 #if !ENABLE(OILPAN) | 350 #if !ENABLE(OILPAN) |
| 341 ASSERT(m_workerGlobalScope->hasOneRef()); | 351 ASSERT(m_workerGlobalScope->hasOneRef()); |
| 342 #endif | 352 #endif |
| 343 m_workerGlobalScope->dispose(); | 353 m_workerGlobalScope->dispose(); |
| 344 m_workerGlobalScope = nullptr; | 354 m_workerGlobalScope = nullptr; |
| 345 | 355 |
| 346 m_thread->detachGC(); | 356 thread()->detachGC(); |
| 347 | 357 |
| 348 m_thread->removeTaskObserver(m_microtaskRunner.get()); | 358 thread()->removeTaskObserver(m_microtaskRunner.get()); |
| 349 m_microtaskRunner = nullptr; | 359 m_microtaskRunner = nullptr; |
| 350 | 360 |
| 351 // Notify the proxy that the WorkerGlobalScope has been disposed of. | 361 // Notify the proxy that the WorkerGlobalScope has been disposed of. |
| 352 // This can free this thread object, hence it must not be touched afterwards
. | 362 // This can free this thread object, hence it must not be touched afterwards
. |
| 353 workerReportingProxy().workerThreadTerminated(); | 363 workerReportingProxy().workerThreadTerminated(); |
| 354 | 364 |
| 355 m_terminationEvent->signal(); | 365 m_terminationEvent->signal(); |
| 356 | 366 |
| 357 // Clean up PlatformThreadData before WTF::WTFThreadData goes away! | 367 // Clean up PlatformThreadData before WTF::WTFThreadData goes away! |
| 358 PlatformThreadData::current().destroy(); | 368 PlatformThreadData::current().destroy(); |
| 359 } | 369 } |
| 360 | 370 |
| 361 class WorkerThreadShutdownFinishTask : public ExecutionContextTask { | 371 class WorkerThreadShutdownFinishTask : public ExecutionContextTask { |
| 362 public: | 372 public: |
| 363 static PassOwnPtr<WorkerThreadShutdownFinishTask> create() | 373 static PassOwnPtr<WorkerThreadShutdownFinishTask> create() |
| 364 { | 374 { |
| 365 return adoptPtr(new WorkerThreadShutdownFinishTask()); | 375 return adoptPtr(new WorkerThreadShutdownFinishTask()); |
| 366 } | 376 } |
| 367 | 377 |
| 368 virtual void performTask(ExecutionContext *context) | 378 virtual void performTask(ExecutionContext *context) |
| 369 { | 379 { |
| 370 WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context); | 380 WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context); |
| 371 workerGlobalScope->clearInspector(); | 381 workerGlobalScope->clearInspector(); |
| 372 // It's not safe to call clearScript until all the cleanup tasks posted
by functions initiated by WorkerThreadShutdownStartTask have completed. | 382 // It's not safe to call clearScript until all the cleanup tasks posted
by functions initiated by WorkerThreadShutdownStartTask have completed. |
| 373 workerGlobalScope->clearScript(); | 383 workerGlobalScope->clearScript(); |
| 374 workerGlobalScope->thread()->m_thread->postTask(new Task(WTF::bind(&Work
erThread::cleanup, workerGlobalScope->thread()))); | 384 workerGlobalScope->thread()->thread()->postTask(new Task(WTF::bind(&Work
erThread::cleanup, workerGlobalScope->thread()))); |
| 375 } | 385 } |
| 376 | 386 |
| 377 virtual bool isCleanupTask() const { return true; } | 387 virtual bool isCleanupTask() const { return true; } |
| 378 }; | 388 }; |
| 379 | 389 |
| 380 class WorkerThreadShutdownStartTask : public ExecutionContextTask { | 390 class WorkerThreadShutdownStartTask : public ExecutionContextTask { |
| 381 public: | 391 public: |
| 382 static PassOwnPtr<WorkerThreadShutdownStartTask> create() | 392 static PassOwnPtr<WorkerThreadShutdownStartTask> create() |
| 383 { | 393 { |
| 384 return adoptPtr(new WorkerThreadShutdownStartTask()); | 394 return adoptPtr(new WorkerThreadShutdownStartTask()); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 452 HashSet<WorkerThread*> threads = workerThreads(); | 462 HashSet<WorkerThread*> threads = workerThreads(); |
| 453 for (WorkerThread* thread : threads) | 463 for (WorkerThread* thread : threads) |
| 454 thread->stopInShutdownSequence(); | 464 thread->stopInShutdownSequence(); |
| 455 | 465 |
| 456 for (WorkerThread* thread : threads) | 466 for (WorkerThread* thread : threads) |
| 457 thread->terminationEvent()->wait(); | 467 thread->terminationEvent()->wait(); |
| 458 } | 468 } |
| 459 | 469 |
| 460 bool WorkerThread::isCurrentThread() const | 470 bool WorkerThread::isCurrentThread() const |
| 461 { | 471 { |
| 462 return m_thread && m_thread->isCurrentThread(); | 472 return thread() && thread()->isCurrentThread(); |
| 463 } | 473 } |
| 464 | 474 |
| 465 void WorkerThread::idleHandler() | 475 void WorkerThread::idleHandler() |
| 466 { | 476 { |
| 467 ASSERT(m_workerGlobalScope.get()); | 477 ASSERT(m_workerGlobalScope.get()); |
| 468 int64 delay = kLongIdleHandlerDelayMs; | 478 int64 delay = kLongIdleHandlerDelayMs; |
| 469 | 479 |
| 470 // Do a script engine idle notification if the next event is distant enough. | 480 // Do a script engine idle notification if the next event is distant enough. |
| 471 const double kMinIdleTimespan = 0.3; | 481 const double kMinIdleTimespan = 0.3; |
| 472 if (m_sharedTimer->nextFireTime() == 0.0 || m_sharedTimer->nextFireTime() >
currentTime() + kMinIdleTimespan) { | 482 if (m_sharedTimer->nextFireTime() == 0.0 || m_sharedTimer->nextFireTime() >
currentTime() + kMinIdleTimespan) { |
| 473 bool hasMoreWork = !m_workerGlobalScope->idleNotification(); | 483 bool hasMoreWork = !m_workerGlobalScope->idleNotification(); |
| 474 if (hasMoreWork) | 484 if (hasMoreWork) |
| 475 delay = kShortIdleHandlerDelayMs; | 485 delay = kShortIdleHandlerDelayMs; |
| 476 } | 486 } |
| 477 | 487 |
| 478 postDelayedTask(createSameThreadTask(&WorkerThread::idleHandler, this), dela
y); | 488 postDelayedTask(createSameThreadTask(&WorkerThread::idleHandler, this), dela
y); |
| 479 } | 489 } |
| 480 | 490 |
| 481 void WorkerThread::postTask(PassOwnPtr<ExecutionContextTask> task) | 491 void WorkerThread::postTask(PassOwnPtr<ExecutionContextTask> task) |
| 482 { | 492 { |
| 483 m_thread->postTask(WorkerThreadTask::create(*this, task, true).leakPtr()); | 493 thread()->postTask(WorkerThreadTask::create(*this, task, true).leakPtr()); |
| 484 } | 494 } |
| 485 | 495 |
| 486 void WorkerThread::postDelayedTask(PassOwnPtr<ExecutionContextTask> task, long l
ong delayMs) | 496 void WorkerThread::postDelayedTask(PassOwnPtr<ExecutionContextTask> task, long l
ong delayMs) |
| 487 { | 497 { |
| 488 m_thread->postDelayedTask(WorkerThreadTask::create(*this, task, true).leakPt
r(), delayMs); | 498 thread()->postDelayedTask(WorkerThreadTask::create(*this, task, true).leakPt
r(), delayMs); |
| 489 } | 499 } |
| 490 | 500 |
| 491 void WorkerThread::postDebuggerTask(PassOwnPtr<ExecutionContextTask> task) | 501 void WorkerThread::postDebuggerTask(PassOwnPtr<ExecutionContextTask> task) |
| 492 { | 502 { |
| 493 m_debuggerMessageQueue.append(WorkerThreadTask::create(*this, task, false)); | 503 m_debuggerMessageQueue.append(WorkerThreadTask::create(*this, task, false)); |
| 494 postTask(RunDebuggerQueueTask::create(this)); | 504 postTask(RunDebuggerQueueTask::create(this)); |
| 495 } | 505 } |
| 496 | 506 |
| 497 MessageQueueWaitResult WorkerThread::runDebuggerTask(WaitMode waitMode) | 507 MessageQueueWaitResult WorkerThread::runDebuggerTask(WaitMode waitMode) |
| 498 { | 508 { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 525 { | 535 { |
| 526 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); | 536 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); |
| 527 } | 537 } |
| 528 | 538 |
| 529 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke
rInspectorController) | 539 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke
rInspectorController) |
| 530 { | 540 { |
| 531 MutexLocker locker(m_workerInspectorControllerMutex); | 541 MutexLocker locker(m_workerInspectorControllerMutex); |
| 532 m_workerInspectorController = workerInspectorController; | 542 m_workerInspectorController = workerInspectorController; |
| 533 } | 543 } |
| 534 | 544 |
| 545 void WorkerThread::setTeleporter(WebTeleporter* teleporter) |
| 546 { |
| 547 TRACE_EVENT0("teleport", "WorkerThread::setTeleporter"); |
| 548 m_teleporter = teleporter; |
| 549 } |
| 550 |
| 551 void WorkerThread::initializeWebThread() |
| 552 { |
| 553 m_thread = WebThreadSupportingGC::create("WebCore: Worker"); |
| 554 } |
| 555 |
| 556 blink::WebThreadSupportingGC* WorkerThread::thread() const |
| 557 { |
| 558 return m_thread.get(); |
| 559 } |
| 560 |
| 535 } // namespace blink | 561 } // namespace blink |
| OLD | NEW |