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 |
11 * documentation and/or other materials provided with the distribution. | 11 * documentation and/or other materials provided with the distribution. |
12 * | 12 * |
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY | 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR | 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
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 "core/workers/WorkerThread.h" | 27 #include "core/workers/WorkerThread.h" |
28 | 28 |
| 29 #include <limits.h> |
| 30 #include <memory> |
29 #include "bindings/core/v8/Microtask.h" | 31 #include "bindings/core/v8/Microtask.h" |
30 #include "bindings/core/v8/ScriptSourceCode.h" | 32 #include "bindings/core/v8/ScriptSourceCode.h" |
31 #include "bindings/core/v8/WorkerOrWorkletScriptController.h" | 33 #include "bindings/core/v8/WorkerOrWorkletScriptController.h" |
| 34 #include "core/dom/TaskRunnerHelper.h" |
32 #include "core/inspector/ConsoleMessageStorage.h" | 35 #include "core/inspector/ConsoleMessageStorage.h" |
33 #include "core/inspector/InspectorInstrumentation.h" | 36 #include "core/inspector/InspectorInstrumentation.h" |
34 #include "core/inspector/InspectorTaskRunner.h" | 37 #include "core/inspector/InspectorTaskRunner.h" |
35 #include "core/inspector/WorkerInspectorController.h" | 38 #include "core/inspector/WorkerInspectorController.h" |
36 #include "core/inspector/WorkerThreadDebugger.h" | 39 #include "core/inspector/WorkerThreadDebugger.h" |
37 #include "core/origin_trials/OriginTrialContext.h" | 40 #include "core/origin_trials/OriginTrialContext.h" |
38 #include "core/workers/ThreadedWorkletGlobalScope.h" | 41 #include "core/workers/ThreadedWorkletGlobalScope.h" |
39 #include "core/workers/WorkerBackingThread.h" | 42 #include "core/workers/WorkerBackingThread.h" |
40 #include "core/workers/WorkerClients.h" | 43 #include "core/workers/WorkerClients.h" |
41 #include "core/workers/WorkerGlobalScope.h" | 44 #include "core/workers/WorkerGlobalScope.h" |
42 #include "core/workers/WorkerReportingProxy.h" | 45 #include "core/workers/WorkerReportingProxy.h" |
43 #include "core/workers/WorkerThreadStartupData.h" | 46 #include "core/workers/WorkerThreadStartupData.h" |
44 #include "platform/CrossThreadFunctional.h" | 47 #include "platform/CrossThreadFunctional.h" |
45 #include "platform/Histogram.h" | 48 #include "platform/Histogram.h" |
46 #include "platform/WaitableEvent.h" | 49 #include "platform/WaitableEvent.h" |
47 #include "platform/WebThreadSupportingGC.h" | 50 #include "platform/WebThreadSupportingGC.h" |
48 #include "platform/heap/SafePoint.h" | 51 #include "platform/heap/SafePoint.h" |
49 #include "platform/heap/ThreadState.h" | 52 #include "platform/heap/ThreadState.h" |
50 #include "platform/weborigin/KURL.h" | 53 #include "platform/weborigin/KURL.h" |
51 #include "wtf/Functional.h" | 54 #include "wtf/Functional.h" |
52 #include "wtf/Noncopyable.h" | 55 #include "wtf/Noncopyable.h" |
53 #include "wtf/PtrUtil.h" | 56 #include "wtf/PtrUtil.h" |
54 #include "wtf/Threading.h" | 57 #include "wtf/Threading.h" |
55 #include "wtf/text/WTFString.h" | 58 #include "wtf/text/WTFString.h" |
56 #include <limits.h> | |
57 #include <memory> | |
58 | 59 |
59 namespace blink { | 60 namespace blink { |
60 | 61 |
61 using ExitCode = WorkerThread::ExitCode; | 62 using ExitCode = WorkerThread::ExitCode; |
62 | 63 |
63 // TODO(nhiroki): Adjust the delay based on UMA. | 64 // TODO(nhiroki): Adjust the delay based on UMA. |
64 const long long kForcibleTerminationDelayInMs = 2000; // 2 secs | 65 const long long kForcibleTerminationDelayInMs = 2000; // 2 secs |
65 | 66 |
66 static Mutex& threadSetMutex() { | 67 static Mutex& threadSetMutex() { |
67 DEFINE_THREAD_SAFE_STATIC_LOCAL(Mutex, mutex, new Mutex); | 68 DEFINE_THREAD_SAFE_STATIC_LOCAL(Mutex, mutex, new Mutex); |
(...skipping 30 matching lines...) Expand all Loading... |
98 | 99 |
99 DCHECK_NE(ExitCode::NotTerminated, m_exitCode); | 100 DCHECK_NE(ExitCode::NotTerminated, m_exitCode); |
100 DEFINE_THREAD_SAFE_STATIC_LOCAL( | 101 DEFINE_THREAD_SAFE_STATIC_LOCAL( |
101 EnumerationHistogram, exitCodeHistogram, | 102 EnumerationHistogram, exitCodeHistogram, |
102 new EnumerationHistogram("WorkerThread.ExitCode", | 103 new EnumerationHistogram("WorkerThread.ExitCode", |
103 static_cast<int>(ExitCode::LastEnum))); | 104 static_cast<int>(ExitCode::LastEnum))); |
104 exitCodeHistogram.count(static_cast<int>(m_exitCode)); | 105 exitCodeHistogram.count(static_cast<int>(m_exitCode)); |
105 } | 106 } |
106 | 107 |
107 void WorkerThread::start(std::unique_ptr<WorkerThreadStartupData> startupData, | 108 void WorkerThread::start(std::unique_ptr<WorkerThreadStartupData> startupData, |
108 ParentFrameTaskRunners* parentFrameTaskRunners) { | 109 FrameTaskRunnersHolder* frameTaskRunners) { |
109 DCHECK(isMainThread()); | 110 DCHECK(isMainThread()); |
110 | 111 |
111 if (m_requestedToStart) | 112 if (m_requestedToStart) |
112 return; | 113 return; |
113 | 114 |
114 m_requestedToStart = true; | 115 m_requestedToStart = true; |
115 m_parentFrameTaskRunners = parentFrameTaskRunners; | 116 m_frameTaskRunners = frameTaskRunners; |
116 workerBackingThread().backingThread().postTask( | 117 workerBackingThread().backingThread().postTask( |
117 BLINK_FROM_HERE, crossThreadBind(&WorkerThread::initializeOnWorkerThread, | 118 BLINK_FROM_HERE, |
118 crossThreadUnretained(this), | 119 crossThreadBind(&WorkerThread::initializeOnWorkerThread, |
119 WTF::passed(std::move(startupData)))); | 120 crossThreadUnretained(this), |
| 121 WTF::passed(std::move(startupData)), |
| 122 wrapCrossThreadPersistent(frameTaskRunners))); |
120 } | 123 } |
121 | 124 |
122 void WorkerThread::terminate() { | 125 void WorkerThread::terminate() { |
123 DCHECK(isMainThread()); | 126 DCHECK(isMainThread()); |
124 terminateInternal(TerminationMode::Graceful); | 127 terminateInternal(TerminationMode::Graceful); |
125 } | 128 } |
126 | 129 |
127 void WorkerThread::terminateAndWait() { | 130 void WorkerThread::terminateAndWait() { |
128 DCHECK(isMainThread()); | 131 DCHECK(isMainThread()); |
129 | 132 |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 m_requestedToTerminate = true; | 337 m_requestedToTerminate = true; |
335 | 338 |
336 if (shouldScheduleToTerminateExecution(lock)) { | 339 if (shouldScheduleToTerminateExecution(lock)) { |
337 switch (mode) { | 340 switch (mode) { |
338 case TerminationMode::Forcible: | 341 case TerminationMode::Forcible: |
339 forciblyTerminateExecution(lock, ExitCode::SyncForciblyTerminated); | 342 forciblyTerminateExecution(lock, ExitCode::SyncForciblyTerminated); |
340 break; | 343 break; |
341 case TerminationMode::Graceful: | 344 case TerminationMode::Graceful: |
342 DCHECK(!m_forcibleTerminationTaskHandle.isActive()); | 345 DCHECK(!m_forcibleTerminationTaskHandle.isActive()); |
343 m_forcibleTerminationTaskHandle = | 346 m_forcibleTerminationTaskHandle = |
344 m_parentFrameTaskRunners->get(TaskType::UnspecedTimer) | 347 m_frameTaskRunners->get(TaskType::UnspecedTimer) |
345 ->postDelayedCancellableTask( | 348 ->postDelayedCancellableTask( |
346 BLINK_FROM_HERE, | 349 BLINK_FROM_HERE, |
347 WTF::bind(&WorkerThread::mayForciblyTerminateExecution, | 350 WTF::bind(&WorkerThread::mayForciblyTerminateExecution, |
348 WTF::unretained(this)), | 351 WTF::unretained(this)), |
349 m_forcibleTerminationDelayInMs); | 352 m_forcibleTerminationDelayInMs); |
350 break; | 353 break; |
351 } | 354 } |
352 } | 355 } |
353 } | 356 } |
354 | 357 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 // |m_requestedToTerminate| on the main thread or |m_threadState| on the | 426 // |m_requestedToTerminate| on the main thread or |m_threadState| on the |
424 // worker thread is safe as the flag is set only on the thread. | 427 // worker thread is safe as the flag is set only on the thread. |
425 if (isMainThread() && m_requestedToTerminate) | 428 if (isMainThread() && m_requestedToTerminate) |
426 return true; | 429 return true; |
427 if (isCurrentThread() && m_threadState == ThreadState::ReadyToShutdown) | 430 if (isCurrentThread() && m_threadState == ThreadState::ReadyToShutdown) |
428 return true; | 431 return true; |
429 return false; | 432 return false; |
430 } | 433 } |
431 | 434 |
432 void WorkerThread::initializeOnWorkerThread( | 435 void WorkerThread::initializeOnWorkerThread( |
433 std::unique_ptr<WorkerThreadStartupData> startupData) { | 436 std::unique_ptr<WorkerThreadStartupData> startupData, |
| 437 FrameTaskRunnersHolder* frameTaskRunners) { |
434 DCHECK(isCurrentThread()); | 438 DCHECK(isCurrentThread()); |
435 DCHECK_EQ(ThreadState::NotStarted, m_threadState); | 439 DCHECK_EQ(ThreadState::NotStarted, m_threadState); |
436 | 440 |
437 KURL scriptURL = startupData->m_scriptURL; | 441 KURL scriptURL = startupData->m_scriptURL; |
438 String sourceCode = startupData->m_sourceCode; | 442 String sourceCode = startupData->m_sourceCode; |
439 WorkerThreadStartMode startMode = startupData->m_startMode; | 443 WorkerThreadStartMode startMode = startupData->m_startMode; |
440 std::unique_ptr<Vector<char>> cachedMetaData = | 444 std::unique_ptr<Vector<char>> cachedMetaData = |
441 std::move(startupData->m_cachedMetaData); | 445 std::move(startupData->m_cachedMetaData); |
442 V8CacheOptions v8CacheOptions = | 446 V8CacheOptions v8CacheOptions = |
443 startupData->m_workerV8Settings.m_v8CacheOptions; | 447 startupData->m_workerV8Settings.m_v8CacheOptions; |
(...skipping 10 matching lines...) Expand all Loading... |
454 | 458 |
455 // Optimize for memory usage instead of latency for the worker isolate. | 459 // Optimize for memory usage instead of latency for the worker isolate. |
456 isolate()->IsolateInBackgroundNotification(); | 460 isolate()->IsolateInBackgroundNotification(); |
457 | 461 |
458 if (heapLimitIncreasedForDebugging) { | 462 if (heapLimitIncreasedForDebugging) { |
459 isolate()->IncreaseHeapLimitForDebugging(); | 463 isolate()->IncreaseHeapLimitForDebugging(); |
460 } | 464 } |
461 | 465 |
462 m_consoleMessageStorage = new ConsoleMessageStorage(); | 466 m_consoleMessageStorage = new ConsoleMessageStorage(); |
463 m_globalScope = createWorkerGlobalScope(std::move(startupData)); | 467 m_globalScope = createWorkerGlobalScope(std::move(startupData)); |
| 468 FrameTaskRunnerHelper::setTaskRunners(globalScope(), frameTaskRunners); |
464 m_workerReportingProxy.didCreateWorkerGlobalScope(globalScope()); | 469 m_workerReportingProxy.didCreateWorkerGlobalScope(globalScope()); |
465 m_workerInspectorController = WorkerInspectorController::create(this); | 470 m_workerInspectorController = WorkerInspectorController::create(this); |
466 | 471 |
467 // TODO(nhiroki): Handle a case where the script controller fails to | 472 // TODO(nhiroki): Handle a case where the script controller fails to |
468 // initialize the context. | 473 // initialize the context. |
469 if (globalScope()->scriptController()->initializeContextIfNeeded()) { | 474 if (globalScope()->scriptController()->initializeContextIfNeeded()) { |
470 m_workerReportingProxy.didInitializeWorkerContext(); | 475 m_workerReportingProxy.didInitializeWorkerContext(); |
471 v8::HandleScope handleScope(isolate()); | 476 v8::HandleScope handleScope(isolate()); |
472 Platform::current()->workerContextCreated( | 477 Platform::current()->workerContextCreated( |
473 globalScope()->scriptController()->context()); | 478 globalScope()->scriptController()->context()); |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
642 MutexLocker lock(m_threadStateMutex); | 647 MutexLocker lock(m_threadStateMutex); |
643 return m_requestedToTerminate; | 648 return m_requestedToTerminate; |
644 } | 649 } |
645 | 650 |
646 ExitCode WorkerThread::getExitCodeForTesting() { | 651 ExitCode WorkerThread::getExitCodeForTesting() { |
647 MutexLocker lock(m_threadStateMutex); | 652 MutexLocker lock(m_threadStateMutex); |
648 return m_exitCode; | 653 return m_exitCode; |
649 } | 654 } |
650 | 655 |
651 } // namespace blink | 656 } // namespace blink |
OLD | NEW |