Chromium Code Reviews| 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 11 matching lines...) Expand all Loading... | |
| 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 24 * | 24 * |
| 25 */ | 25 */ |
| 26 | 26 |
| 27 #include "config.h" | 27 #include "config.h" |
| 28 | 28 |
| 29 #include "core/workers/WorkerThread.h" | 29 #include "core/workers/WorkerThread.h" |
| 30 | 30 |
| 31 #include "bindings/core/v8/ScriptSourceCode.h" | 31 #include "bindings/core/v8/ScriptSourceCode.h" |
| 32 #include "bindings/core/v8/V8GCController.h" | |
| 33 #include "bindings/core/v8/V8Initializer.h" | |
| 34 #include "core/dom/Microtask.h" | 32 #include "core/dom/Microtask.h" |
| 35 #include "core/inspector/InspectorInstrumentation.h" | 33 #include "core/inspector/InspectorInstrumentation.h" |
| 36 #include "core/inspector/WorkerInspectorController.h" | 34 #include "core/inspector/WorkerInspectorController.h" |
| 37 #include "core/workers/DedicatedWorkerGlobalScope.h" | 35 #include "core/workers/DedicatedWorkerGlobalScope.h" |
| 38 #include "core/workers/WorkerClients.h" | 36 #include "core/workers/WorkerClients.h" |
| 39 #include "core/workers/WorkerReportingProxy.h" | 37 #include "core/workers/WorkerReportingProxy.h" |
| 40 #include "core/workers/WorkerThreadStartupData.h" | 38 #include "core/workers/WorkerThreadStartupData.h" |
| 41 #include "platform/PlatformThreadData.h" | 39 #include "platform/PlatformThreadData.h" |
| 42 #include "platform/Task.h" | 40 #include "platform/Task.h" |
| 43 #include "platform/ThreadSafeFunctional.h" | 41 #include "platform/ThreadSafeFunctional.h" |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 249 bool m_isInstrumented; | 247 bool m_isInstrumented; |
| 250 }; | 248 }; |
| 251 | 249 |
| 252 WorkerThread::WorkerThread(PassRefPtr<WorkerLoaderProxy> workerLoaderProxy, Work erReportingProxy& workerReportingProxy) | 250 WorkerThread::WorkerThread(PassRefPtr<WorkerLoaderProxy> workerLoaderProxy, Work erReportingProxy& workerReportingProxy) |
| 253 : m_started(false) | 251 : m_started(false) |
| 254 , m_terminated(false) | 252 , m_terminated(false) |
| 255 , m_shutdown(false) | 253 , m_shutdown(false) |
| 256 , m_workerLoaderProxy(workerLoaderProxy) | 254 , m_workerLoaderProxy(workerLoaderProxy) |
| 257 , m_workerReportingProxy(workerReportingProxy) | 255 , m_workerReportingProxy(workerReportingProxy) |
| 258 , m_webScheduler(nullptr) | 256 , m_webScheduler(nullptr) |
| 259 , m_isolate(nullptr) | |
| 260 , m_shutdownEvent(adoptPtr(Platform::current()->createWaitableEvent())) | 257 , m_shutdownEvent(adoptPtr(Platform::current()->createWaitableEvent())) |
| 261 , m_terminationEvent(adoptPtr(Platform::current()->createWaitableEvent())) | 258 , m_terminationEvent(adoptPtr(Platform::current()->createWaitableEvent())) |
| 262 { | 259 { |
| 263 MutexLocker lock(threadSetMutex()); | 260 MutexLocker lock(threadSetMutex()); |
| 264 workerThreads().add(this); | 261 workerThreads().add(this); |
| 265 } | 262 } |
| 266 | 263 |
| 267 WorkerThread::~WorkerThread() | 264 WorkerThread::~WorkerThread() |
| 268 { | 265 { |
| 269 MutexLocker lock(threadSetMutex()); | 266 MutexLocker lock(threadSetMutex()); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 308 // The worker was terminated before the thread had a chance to run. | 305 // The worker was terminated before the thread had a chance to run. |
| 309 if (m_terminated) { | 306 if (m_terminated) { |
| 310 // Notify the proxy that the WorkerGlobalScope has been disposed of. | 307 // Notify the proxy that the WorkerGlobalScope has been disposed of. |
| 311 // This can free this thread object, hence it must not be touched af terwards. | 308 // This can free this thread object, hence it must not be touched af terwards. |
| 312 m_workerReportingProxy.workerThreadTerminated(); | 309 m_workerReportingProxy.workerThreadTerminated(); |
| 313 return; | 310 return; |
| 314 } | 311 } |
| 315 | 312 |
| 316 m_microtaskRunner = adoptPtr(new WorkerMicrotaskRunner(this)); | 313 m_microtaskRunner = adoptPtr(new WorkerMicrotaskRunner(this)); |
| 317 backingThread().addTaskObserver(m_microtaskRunner.get()); | 314 backingThread().addTaskObserver(m_microtaskRunner.get()); |
| 318 backingThread().initialize(); | 315 initializeBackingThread(); |
| 319 | 316 |
| 320 m_isolate = initializeIsolate(); | 317 // Make sure the isolate is intialized correctly. |
| 318 m_isolateWrapper = createIsolateWrapper(); | |
| 321 m_workerGlobalScope = createWorkerGlobalScope(startupData); | 319 m_workerGlobalScope = createWorkerGlobalScope(startupData); |
| 322 m_workerGlobalScope->scriptLoaded(sourceCode.length(), cachedMetaData.ge t() ? cachedMetaData->size() : 0); | 320 m_workerGlobalScope->scriptLoaded(sourceCode.length(), cachedMetaData.ge t() ? cachedMetaData->size() : 0); |
| 323 | 321 |
| 324 PlatformThreadData::current().threadTimers().setSharedTimer(adoptPtr(new WorkerSharedTimer(this))); | 322 PlatformThreadData::current().threadTimers().setSharedTimer(adoptPtr(new WorkerSharedTimer(this))); |
| 325 } | 323 } |
| 326 m_webScheduler = backingThread().platformThread().scheduler(); | 324 m_webScheduler = backingThread().platformThread().scheduler(); |
| 327 | 325 |
| 328 // The corresponding call to stopRunLoop() is in ~WorkerScriptController(). | 326 // The corresponding call to stopRunLoop() is in ~WorkerScriptController(). |
| 329 didStartRunLoop(); | 327 didStartRunLoop(); |
| 330 | 328 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 351 { | 349 { |
| 352 ASSERT(isCurrentThread()); | 350 ASSERT(isCurrentThread()); |
| 353 { | 351 { |
| 354 MutexLocker lock(m_threadStateMutex); | 352 MutexLocker lock(m_threadStateMutex); |
| 355 ASSERT(!m_shutdown); | 353 ASSERT(!m_shutdown); |
| 356 m_shutdown = true; | 354 m_shutdown = true; |
| 357 } | 355 } |
| 358 | 356 |
| 359 PlatformThreadData::current().threadTimers().setSharedTimer(nullptr); | 357 PlatformThreadData::current().threadTimers().setSharedTimer(nullptr); |
| 360 workerGlobalScope()->dispose(); | 358 workerGlobalScope()->dispose(); |
| 361 willDestroyIsolate(); | 359 m_isolateWrapper->willDestroy(); |
| 362 | 360 |
| 363 // This should be called before we start the shutdown procedure. | 361 // This should be called before we start the shutdown procedure. |
| 364 workerReportingProxy().willDestroyWorkerGlobalScope(); | 362 workerReportingProxy().willDestroyWorkerGlobalScope(); |
| 365 | 363 |
| 366 // The below assignment will destroy the context, which will in turn notify messaging proxy. | 364 // The below assignment will destroy the context, which will in turn notify messaging proxy. |
| 367 // We cannot let any objects survive past thread exit, because no other thre ad will run GC or otherwise destroy them. | 365 // We cannot let any objects survive past thread exit, because no other thre ad will run GC or otherwise destroy them. |
| 368 // If Oilpan is enabled, we detach of the context/global scope, with the fin al heap cleanup below sweeping it out. | 366 // If Oilpan is enabled, we detach of the context/global scope, with the fin al heap cleanup below sweeping it out. |
| 369 #if !ENABLE(OILPAN) | 367 #if !ENABLE(OILPAN) |
| 370 ASSERT(m_workerGlobalScope->hasOneRef()); | 368 ASSERT(m_workerGlobalScope->hasOneRef()); |
| 371 #endif | 369 #endif |
| 372 m_workerGlobalScope->notifyContextDestroyed(); | 370 m_workerGlobalScope->notifyContextDestroyed(); |
| 373 m_workerGlobalScope = nullptr; | 371 m_workerGlobalScope = nullptr; |
| 374 | 372 |
| 375 backingThread().removeTaskObserver(m_microtaskRunner.get()); | 373 backingThread().removeTaskObserver(m_microtaskRunner.get()); |
| 376 backingThread().shutdown(); | 374 shutdownBackingThread(); |
| 377 destroyIsolate(); | 375 m_isolateWrapper.clear(); |
| 378 | 376 |
| 379 m_microtaskRunner = nullptr; | 377 m_microtaskRunner = nullptr; |
| 380 | 378 |
| 381 // Notify the proxy that the WorkerGlobalScope has been disposed of. | 379 // Notify the proxy that the WorkerGlobalScope has been disposed of. |
| 382 // This can free this thread object, hence it must not be touched afterwards . | 380 // This can free this thread object, hence it must not be touched afterwards . |
| 383 workerReportingProxy().workerThreadTerminated(); | 381 workerReportingProxy().workerThreadTerminated(); |
| 384 | 382 |
| 385 m_terminationEvent->signal(); | 383 m_terminationEvent->signal(); |
| 386 | 384 |
| 387 // Clean up PlatformThreadData before WTF::WTFThreadData goes away! | 385 // Clean up PlatformThreadData before WTF::WTFThreadData goes away! |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 450 ASSERT(isCurrentThread()); | 448 ASSERT(isCurrentThread()); |
| 451 Platform::current()->didStartWorkerRunLoop(); | 449 Platform::current()->didStartWorkerRunLoop(); |
| 452 } | 450 } |
| 453 | 451 |
| 454 void WorkerThread::didStopRunLoop() | 452 void WorkerThread::didStopRunLoop() |
| 455 { | 453 { |
| 456 ASSERT(isCurrentThread()); | 454 ASSERT(isCurrentThread()); |
| 457 Platform::current()->didStopWorkerRunLoop(); | 455 Platform::current()->didStopWorkerRunLoop(); |
| 458 } | 456 } |
| 459 | 457 |
| 458 v8::Isolate* WorkerThread::isolate() | |
| 459 { | |
| 460 return m_isolateWrapper ? m_isolateWrapper->isolate() : nullptr; | |
|
haraken
2015/06/02 02:14:49
v8::Isolate* must not be null. Can we change this
sadrul
2015/06/02 02:48:28
Done.
| |
| 461 } | |
| 462 | |
| 463 void WorkerThread::initializeBackingThread() | |
| 464 { | |
|
haraken
2015/06/02 02:14:49
Add ASSERT(!isMainThread()).
sadrul
2015/06/02 02:48:28
Done. (added ASSERT(isCurrentThread()); instead)
| |
| 465 backingThread().initialize(); | |
| 466 } | |
| 467 | |
| 468 void WorkerThread::shutdownBackingThread() | |
| 469 { | |
| 470 backingThread().shutdown(); | |
|
haraken
2015/06/02 02:14:49
Add ASSERT(!isMainThread()).
sadrul
2015/06/02 02:48:28
Ditto.
| |
| 471 } | |
| 472 | |
| 460 void WorkerThread::terminateAndWaitForAllWorkers() | 473 void WorkerThread::terminateAndWaitForAllWorkers() |
| 461 { | 474 { |
| 462 // Keep this lock to prevent WorkerThread instances from being destroyed. | 475 // Keep this lock to prevent WorkerThread instances from being destroyed. |
| 463 MutexLocker lock(threadSetMutex()); | 476 MutexLocker lock(threadSetMutex()); |
| 464 HashSet<WorkerThread*> threads = workerThreads(); | 477 HashSet<WorkerThread*> threads = workerThreads(); |
| 465 for (WorkerThread* thread : threads) | 478 for (WorkerThread* thread : threads) |
| 466 thread->stopInShutdownSequence(); | 479 thread->stopInShutdownSequence(); |
| 467 | 480 |
| 468 for (WorkerThread* thread : threads) | 481 for (WorkerThread* thread : threads) |
| 469 thread->terminationEvent()->wait(); | 482 thread->terminationEvent()->wait(); |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 500 void WorkerThread::postTask(const WebTraceLocation& location, PassOwnPtr<Executi onContextTask> task) | 513 void WorkerThread::postTask(const WebTraceLocation& location, PassOwnPtr<Executi onContextTask> task) |
| 501 { | 514 { |
| 502 backingThread().postTask(location, WorkerThreadTask::create(*this, task, tru e).leakPtr()); | 515 backingThread().postTask(location, WorkerThreadTask::create(*this, task, tru e).leakPtr()); |
| 503 } | 516 } |
| 504 | 517 |
| 505 void WorkerThread::postDelayedTask(const WebTraceLocation& location, PassOwnPtr< ExecutionContextTask> task, long long delayMs) | 518 void WorkerThread::postDelayedTask(const WebTraceLocation& location, PassOwnPtr< ExecutionContextTask> task, long long delayMs) |
| 506 { | 519 { |
| 507 backingThread().postDelayedTask(location, WorkerThreadTask::create(*this, ta sk, true).leakPtr(), delayMs); | 520 backingThread().postDelayedTask(location, WorkerThreadTask::create(*this, ta sk, true).leakPtr(), delayMs); |
| 508 } | 521 } |
| 509 | 522 |
| 510 v8::Isolate* WorkerThread::initializeIsolate() | 523 PassOwnPtr<WorkerIsolateWrapper> WorkerThread::createIsolateWrapper() |
| 511 { | 524 { |
| 512 ASSERT(isCurrentThread()); | 525 return WorkerIsolateWrapper::createDefault(); |
| 513 ASSERT(!m_isolate); | |
| 514 v8::Isolate* isolate = V8PerIsolateData::initialize(); | |
| 515 V8Initializer::initializeWorker(isolate); | |
| 516 | |
| 517 m_interruptor = adoptPtr(new V8IsolateInterruptor(isolate)); | |
| 518 ThreadState::current()->addInterruptor(m_interruptor.get()); | |
| 519 ThreadState::current()->registerTraceDOMWrappers(isolate, V8GCController::tr aceDOMWrappers); | |
| 520 | |
| 521 return isolate; | |
| 522 } | |
| 523 | |
| 524 void WorkerThread::willDestroyIsolate() | |
| 525 { | |
| 526 ASSERT(isCurrentThread()); | |
| 527 ASSERT(m_isolate); | |
| 528 V8PerIsolateData::willBeDestroyed(m_isolate); | |
| 529 ThreadState::current()->removeInterruptor(m_interruptor.get()); | |
| 530 } | |
| 531 | |
| 532 void WorkerThread::destroyIsolate() | |
| 533 { | |
| 534 ASSERT(isCurrentThread()); | |
| 535 V8PerIsolateData::destroy(m_isolate); | |
| 536 m_isolate = nullptr; | |
| 537 } | 526 } |
| 538 | 527 |
| 539 void WorkerThread::terminateV8Execution() | 528 void WorkerThread::terminateV8Execution() |
| 540 { | 529 { |
| 541 ASSERT(isMainThread()); | 530 ASSERT(isMainThread()); |
| 542 m_workerGlobalScope->script()->willScheduleExecutionTermination(); | 531 m_workerGlobalScope->script()->willScheduleExecutionTermination(); |
| 543 v8::V8::TerminateExecution(m_isolate); | 532 m_isolateWrapper->terminateExecution(); |
| 544 } | 533 } |
| 545 | 534 |
| 546 void WorkerThread::appendDebuggerTask(PassOwnPtr<WebThread::Task> task) | 535 void WorkerThread::appendDebuggerTask(PassOwnPtr<WebThread::Task> task) |
| 547 { | 536 { |
| 548 m_debuggerMessageQueue.append(task); | 537 m_debuggerMessageQueue.append(task); |
| 549 } | 538 } |
| 550 | 539 |
| 551 MessageQueueWaitResult WorkerThread::runDebuggerTask(WaitMode waitMode) | 540 MessageQueueWaitResult WorkerThread::runDebuggerTask(WaitMode waitMode) |
| 552 { | 541 { |
| 553 ASSERT(isCurrentThread()); | 542 ASSERT(isCurrentThread()); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 580 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); | 569 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); |
| 581 } | 570 } |
| 582 | 571 |
| 583 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke rInspectorController) | 572 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke rInspectorController) |
| 584 { | 573 { |
| 585 MutexLocker locker(m_workerInspectorControllerMutex); | 574 MutexLocker locker(m_workerInspectorControllerMutex); |
| 586 m_workerInspectorController = workerInspectorController; | 575 m_workerInspectorController = workerInspectorController; |
| 587 } | 576 } |
| 588 | 577 |
| 589 } // namespace blink | 578 } // namespace blink |
| OLD | NEW |