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(); | |
319 ASSERT(m_isolateWrapper); | |
kinuko
2015/06/01 13:15:41
(This assert is probably not that desirable / help
sadrul
2015/06/01 14:21:16
Removed.
| |
321 m_workerGlobalScope = createWorkerGlobalScope(startupData); | 320 m_workerGlobalScope = createWorkerGlobalScope(startupData); |
322 m_workerGlobalScope->scriptLoaded(sourceCode.length(), cachedMetaData.ge t() ? cachedMetaData->size() : 0); | 321 m_workerGlobalScope->scriptLoaded(sourceCode.length(), cachedMetaData.ge t() ? cachedMetaData->size() : 0); |
323 | 322 |
324 PlatformThreadData::current().threadTimers().setSharedTimer(adoptPtr(new WorkerSharedTimer(this))); | 323 PlatformThreadData::current().threadTimers().setSharedTimer(adoptPtr(new WorkerSharedTimer(this))); |
325 } | 324 } |
326 m_webScheduler = backingThread().platformThread().scheduler(); | 325 m_webScheduler = backingThread().platformThread().scheduler(); |
327 | 326 |
328 // The corresponding call to stopRunLoop() is in ~WorkerScriptController(). | 327 // The corresponding call to stopRunLoop() is in ~WorkerScriptController(). |
329 didStartRunLoop(); | 328 didStartRunLoop(); |
330 | 329 |
(...skipping 20 matching lines...) Expand all Loading... | |
351 { | 350 { |
352 ASSERT(isCurrentThread()); | 351 ASSERT(isCurrentThread()); |
353 { | 352 { |
354 MutexLocker lock(m_threadStateMutex); | 353 MutexLocker lock(m_threadStateMutex); |
355 ASSERT(!m_shutdown); | 354 ASSERT(!m_shutdown); |
356 m_shutdown = true; | 355 m_shutdown = true; |
357 } | 356 } |
358 | 357 |
359 PlatformThreadData::current().threadTimers().setSharedTimer(nullptr); | 358 PlatformThreadData::current().threadTimers().setSharedTimer(nullptr); |
360 workerGlobalScope()->dispose(); | 359 workerGlobalScope()->dispose(); |
361 willDestroyIsolate(); | 360 m_isolateWrapper->willDestroy(); |
362 | 361 |
363 // This should be called before we start the shutdown procedure. | 362 // This should be called before we start the shutdown procedure. |
364 workerReportingProxy().willDestroyWorkerGlobalScope(); | 363 workerReportingProxy().willDestroyWorkerGlobalScope(); |
365 | 364 |
366 // The below assignment will destroy the context, which will in turn notify messaging proxy. | 365 // 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. | 366 // 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. | 367 // 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) | 368 #if !ENABLE(OILPAN) |
370 ASSERT(m_workerGlobalScope->hasOneRef()); | 369 ASSERT(m_workerGlobalScope->hasOneRef()); |
371 #endif | 370 #endif |
372 m_workerGlobalScope->notifyContextDestroyed(); | 371 m_workerGlobalScope->notifyContextDestroyed(); |
373 m_workerGlobalScope = nullptr; | 372 m_workerGlobalScope = nullptr; |
374 | 373 |
375 backingThread().removeTaskObserver(m_microtaskRunner.get()); | 374 backingThread().removeTaskObserver(m_microtaskRunner.get()); |
376 backingThread().shutdown(); | 375 shutdownBackingThread(); |
377 destroyIsolate(); | 376 m_isolateWrapper.clear(); |
378 | 377 |
379 m_microtaskRunner = nullptr; | 378 m_microtaskRunner = nullptr; |
380 | 379 |
381 // Notify the proxy that the WorkerGlobalScope has been disposed of. | 380 // Notify the proxy that the WorkerGlobalScope has been disposed of. |
382 // This can free this thread object, hence it must not be touched afterwards . | 381 // This can free this thread object, hence it must not be touched afterwards . |
383 workerReportingProxy().workerThreadTerminated(); | 382 workerReportingProxy().workerThreadTerminated(); |
384 | 383 |
385 m_terminationEvent->signal(); | 384 m_terminationEvent->signal(); |
386 | 385 |
387 // Clean up PlatformThreadData before WTF::WTFThreadData goes away! | 386 // Clean up PlatformThreadData before WTF::WTFThreadData goes away! |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
450 ASSERT(isCurrentThread()); | 449 ASSERT(isCurrentThread()); |
451 Platform::current()->didStartWorkerRunLoop(); | 450 Platform::current()->didStartWorkerRunLoop(); |
452 } | 451 } |
453 | 452 |
454 void WorkerThread::didStopRunLoop() | 453 void WorkerThread::didStopRunLoop() |
455 { | 454 { |
456 ASSERT(isCurrentThread()); | 455 ASSERT(isCurrentThread()); |
457 Platform::current()->didStopWorkerRunLoop(); | 456 Platform::current()->didStopWorkerRunLoop(); |
458 } | 457 } |
459 | 458 |
459 v8::Isolate* WorkerThread::isolate() | |
460 { | |
461 return m_shutdown ? nullptr : m_isolateWrapper->isolate(); | |
kinuko
2015/06/01 13:15:41
Any reason this is not m_isolateWrapper ? m_isolat
sadrul
2015/06/01 14:21:16
Nope. Done.
| |
462 } | |
463 | |
464 void WorkerThread::initializeBackingThread() | |
465 { | |
466 backingThread().initialize(); | |
467 } | |
468 | |
469 void WorkerThread::shutdownBackingThread() | |
470 { | |
471 backingThread().shutdown(); | |
472 } | |
473 | |
460 void WorkerThread::terminateAndWaitForAllWorkers() | 474 void WorkerThread::terminateAndWaitForAllWorkers() |
461 { | 475 { |
462 // Keep this lock to prevent WorkerThread instances from being destroyed. | 476 // Keep this lock to prevent WorkerThread instances from being destroyed. |
463 MutexLocker lock(threadSetMutex()); | 477 MutexLocker lock(threadSetMutex()); |
464 HashSet<WorkerThread*> threads = workerThreads(); | 478 HashSet<WorkerThread*> threads = workerThreads(); |
465 for (WorkerThread* thread : threads) | 479 for (WorkerThread* thread : threads) |
466 thread->stopInShutdownSequence(); | 480 thread->stopInShutdownSequence(); |
467 | 481 |
468 for (WorkerThread* thread : threads) | 482 for (WorkerThread* thread : threads) |
469 thread->terminationEvent()->wait(); | 483 thread->terminationEvent()->wait(); |
(...skipping 30 matching lines...) Expand all Loading... | |
500 void WorkerThread::postTask(const WebTraceLocation& location, PassOwnPtr<Executi onContextTask> task) | 514 void WorkerThread::postTask(const WebTraceLocation& location, PassOwnPtr<Executi onContextTask> task) |
501 { | 515 { |
502 backingThread().postTask(location, WorkerThreadTask::create(*this, task, tru e).leakPtr()); | 516 backingThread().postTask(location, WorkerThreadTask::create(*this, task, tru e).leakPtr()); |
503 } | 517 } |
504 | 518 |
505 void WorkerThread::postDelayedTask(const WebTraceLocation& location, PassOwnPtr< ExecutionContextTask> task, long long delayMs) | 519 void WorkerThread::postDelayedTask(const WebTraceLocation& location, PassOwnPtr< ExecutionContextTask> task, long long delayMs) |
506 { | 520 { |
507 backingThread().postDelayedTask(location, WorkerThreadTask::create(*this, ta sk, true).leakPtr(), delayMs); | 521 backingThread().postDelayedTask(location, WorkerThreadTask::create(*this, ta sk, true).leakPtr(), delayMs); |
508 } | 522 } |
509 | 523 |
510 v8::Isolate* WorkerThread::initializeIsolate() | |
511 { | |
512 ASSERT(isCurrentThread()); | |
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 } | |
538 | |
539 void WorkerThread::terminateV8Execution() | 524 void WorkerThread::terminateV8Execution() |
540 { | 525 { |
541 ASSERT(isMainThread()); | 526 ASSERT(isMainThread()); |
542 m_workerGlobalScope->script()->willScheduleExecutionTermination(); | 527 m_workerGlobalScope->script()->willScheduleExecutionTermination(); |
543 v8::V8::TerminateExecution(m_isolate); | 528 m_isolateWrapper->terminateExecution(); |
544 } | 529 } |
545 | 530 |
546 void WorkerThread::appendDebuggerTask(PassOwnPtr<WebThread::Task> task) | 531 void WorkerThread::appendDebuggerTask(PassOwnPtr<WebThread::Task> task) |
547 { | 532 { |
548 m_debuggerMessageQueue.append(task); | 533 m_debuggerMessageQueue.append(task); |
549 } | 534 } |
550 | 535 |
551 MessageQueueWaitResult WorkerThread::runDebuggerTask(WaitMode waitMode) | 536 MessageQueueWaitResult WorkerThread::runDebuggerTask(WaitMode waitMode) |
552 { | 537 { |
553 ASSERT(isCurrentThread()); | 538 ASSERT(isCurrentThread()); |
(...skipping 26 matching lines...) Expand all Loading... | |
580 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); | 565 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); |
581 } | 566 } |
582 | 567 |
583 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke rInspectorController) | 568 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke rInspectorController) |
584 { | 569 { |
585 MutexLocker locker(m_workerInspectorControllerMutex); | 570 MutexLocker locker(m_workerInspectorControllerMutex); |
586 m_workerInspectorController = workerInspectorController; | 571 m_workerInspectorController = workerInspectorController; |
587 } | 572 } |
588 | 573 |
589 } // namespace blink | 574 } // namespace blink |
OLD | NEW |