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 #ifndef WorkerThread_h | 27 #ifndef WorkerOrWorkletThread_h |
28 #define WorkerThread_h | 28 #define WorkerOrWorkletThread_h |
29 | 29 |
30 #include "core/CoreExport.h" | 30 #include "core/CoreExport.h" |
31 #include "core/dom/ExecutionContextTask.h" | 31 #include "core/dom/ExecutionContextTask.h" |
32 #include "core/frame/csp/ContentSecurityPolicy.h" | 32 #include "core/frame/csp/ContentSecurityPolicy.h" |
33 #include "core/workers/WorkerGlobalScope.h" | 33 #include "core/workers/WorkerGlobalScope.h" |
34 #include "core/workers/WorkerLoaderProxy.h" | 34 #include "core/workers/WorkerLoaderProxy.h" |
35 #include "wtf/Forward.h" | 35 #include "wtf/Forward.h" |
36 #include "wtf/Functional.h" | 36 #include "wtf/Functional.h" |
37 #include "wtf/OwnPtr.h" | 37 #include "wtf/OwnPtr.h" |
38 #include "wtf/PassRefPtr.h" | 38 #include "wtf/PassRefPtr.h" |
39 #include <v8.h> | 39 #include <v8.h> |
40 | 40 |
41 namespace blink { | 41 namespace blink { |
42 | 42 |
43 class InspectorTaskRunner; | 43 class InspectorTaskRunner; |
44 class WaitableEvent; | 44 class WaitableEvent; |
45 class WorkerBackingThread; | 45 class WorkerBackingThread; |
46 class WorkerGlobalScope; | 46 class WorkerGlobalScope; |
47 class WorkerInspectorController; | 47 class WorkerInspectorController; |
48 class WorkerReportingProxy; | 48 class WorkerReportingProxy; |
49 class WorkerThreadStartupData; | 49 class WorkerThreadStartupData; |
50 | 50 |
51 enum WorkerThreadStartMode { | 51 enum WorkerThreadStartMode { |
52 DontPauseWorkerGlobalScopeOnStart, | 52 DontPauseWorkerGlobalScopeOnStart, |
53 PauseWorkerGlobalScopeOnStart | 53 PauseWorkerGlobalScopeOnStart |
54 }; | 54 }; |
55 | 55 |
56 // WorkerThread is a kind of WorkerBackingThread client. Each worker mechanism | 56 // WorkerOrWorkletThread is a kind of WorkerBackingThread client. Each worker me
chanism |
57 // can access the lower thread infrastructure via an implementation of this | 57 // can access the lower thread infrastructure via an implementation of this |
58 // abstract class. Multiple WorkerThreads can share one WorkerBackingThread. | 58 // abstract class. Multiple WorkerOrWorkletThreads can share one WorkerBackingTh
read. |
59 // See WorkerBackingThread.h for more details. | 59 // See WorkerBackingThread.h for more details. |
60 // | 60 // |
61 // WorkerThread start and termination must be initiated on the main thread and | 61 // WorkerOrWorkletThread start and termination must be initiated on the main thr
ead and |
62 // an actual task is executed on the worker thread. | 62 // an actual task is executed on the worker thread. |
63 class CORE_EXPORT WorkerThread { | 63 class CORE_EXPORT WorkerOrWorkletThread { |
64 public: | 64 public: |
65 // Represents how this thread is terminated. | 65 // Represents how this thread is terminated. |
66 enum class ExitCode { | 66 enum class ExitCode { |
67 NotTerminated, | 67 NotTerminated, |
68 GracefullyTerminated, | 68 GracefullyTerminated, |
69 SyncForciblyTerminated, | 69 SyncForciblyTerminated, |
70 AsyncForciblyTerminated, | 70 AsyncForciblyTerminated, |
71 }; | 71 }; |
72 | 72 |
73 virtual ~WorkerThread(); | 73 class GlobalScopeFactory { |
| 74 STACK_ALLOCATED(); |
| 75 public: |
| 76 virtual WorkerOrWorkletGlobalScope* create() const = 0; |
| 77 }; |
| 78 |
| 79 virtual ~WorkerOrWorkletThread(); |
74 | 80 |
75 // Called on the main thread. | 81 // Called on the main thread. |
76 void start(PassOwnPtr<WorkerThreadStartupData>); | |
77 void terminate(); | 82 void terminate(); |
78 | 83 |
79 // Called on the main thread. Internally calls terminateInternal() and wait | 84 // Called on the main thread. Internally calls terminateInternal() and wait |
80 // (by *blocking* the calling thread) until the worker(s) is/are shut down. | 85 // (by *blocking* the calling thread) until the worker(s) is/are shut down. |
81 void terminateAndWait(); | 86 void terminateAndWait(); |
82 static void terminateAndWaitForAllWorkers(); | 87 static void terminateAndWaitForAllWorkers(); |
83 | 88 |
84 virtual WorkerBackingThread& workerBackingThread() = 0; | 89 virtual WorkerBackingThread& workerBackingThread() = 0; |
85 virtual bool shouldAttachThreadDebugger() const { return true; } | 90 virtual bool shouldAttachThreadDebugger() const { return true; } |
86 v8::Isolate* isolate(); | 91 v8::Isolate* isolate(); |
87 | 92 |
88 // Can be used to wait for this worker thread to terminate. | 93 // Can be used to wait for this worker thread to terminate. |
89 // (This is signaled on the main thread, so it's assumed to be waited on | 94 // (This is signaled on the main thread, so it's assumed to be waited on |
90 // the worker context thread) | 95 // the worker context thread) |
91 WaitableEvent* terminationEvent() { return m_terminationEvent.get(); } | 96 WaitableEvent* terminationEvent() { return m_terminationEvent.get(); } |
92 | 97 |
93 bool isCurrentThread(); | 98 bool isCurrentThread(); |
94 | 99 |
95 WorkerLoaderProxy* workerLoaderProxy() const | |
96 { | |
97 RELEASE_ASSERT(m_workerLoaderProxy); | |
98 return m_workerLoaderProxy.get(); | |
99 } | |
100 | |
101 WorkerReportingProxy& workerReportingProxy() const { return m_workerReportin
gProxy; } | 100 WorkerReportingProxy& workerReportingProxy() const { return m_workerReportin
gProxy; } |
102 | 101 |
103 void postTask(const WebTraceLocation&, std::unique_ptr<ExecutionContextTask>
); | 102 void postTask(const WebTraceLocation&, std::unique_ptr<ExecutionContextTask>
); |
104 void appendDebuggerTask(std::unique_ptr<CrossThreadClosure>); | 103 void appendDebuggerTask(std::unique_ptr<CrossThreadClosure>); |
105 | 104 |
106 // Runs only debugger tasks while paused in debugger, called on the worker | 105 // Runs only debugger tasks while paused in debugger, called on the worker |
107 // thread. | 106 // thread. |
108 void startRunningDebuggerTasksOnPause(); | 107 void startRunningDebuggerTasksOnPause(); |
109 void stopRunningDebuggerTasksOnPause(); | 108 void stopRunningDebuggerTasksOnPause(); |
110 bool isRunningDebuggerTasksOnPause() const { return m_pausedInDebugger; } | 109 bool isRunningDebuggerTasksOnPause() const { return m_pausedInDebugger; } |
111 | 110 |
112 // Can be called only on the worker thread, WorkerGlobalScope is not thread | 111 // Can be called only on the worker thread, WorkerGlobalScope is not thread |
113 // safe. | 112 // safe. |
114 WorkerGlobalScope* workerGlobalScope(); | 113 WorkerOrWorkletGlobalScope* globalScope(); |
115 | 114 |
116 // Returns true once one of the terminate* methods is called. | 115 // Returns true once one of the terminate* methods is called. |
117 bool terminated(); | 116 bool terminated(); |
118 | 117 |
119 // Number of active worker threads. | 118 // Number of active worker threads. |
120 static unsigned workerThreadCount(); | 119 static unsigned workerThreadCount(); |
121 | 120 |
122 PlatformThreadId platformThreadId(); | 121 PlatformThreadId platformThreadId(); |
123 | 122 |
124 ExitCode getExitCode(); | 123 ExitCode getExitCode(); |
125 | 124 |
126 protected: | 125 protected: |
127 WorkerThread(PassRefPtr<WorkerLoaderProxy>, WorkerReportingProxy&); | 126 WorkerOrWorkletThread(WorkerReportingProxy&); |
128 | 127 |
129 // Factory method for creating a new worker context for the thread. | 128 void initializeGlobalScope(GlobalScopeFactory&); |
130 // Called on the worker thread. | |
131 virtual WorkerGlobalScope* createWorkerGlobalScope(PassOwnPtr<WorkerThreadSt
artupData>) = 0; | |
132 | 129 |
133 // Called on the worker thread. | 130 bool m_started = false; |
134 virtual void postInitialize() { } | 131 bool m_terminated = false; |
135 | |
136 private: | 132 private: |
137 friend class WorkerThreadTest; | 133 friend class WorkerThreadTest; |
138 | 134 |
139 class ForceTerminationTask; | 135 class ForceTerminationTask; |
140 class WorkerMicrotaskRunner; | 136 class WorkerMicrotaskRunner; |
141 | 137 |
142 enum class TerminationMode { | 138 enum class TerminationMode { |
143 // Synchronously terminate the worker execution. Please be careful to | 139 // Synchronously terminate the worker execution. Please be careful to |
144 // use this mode, because after the synchronous termination any V8 APIs | 140 // use this mode, because after the synchronous termination any V8 APIs |
145 // may suddenly start to return empty handles and it may cause crashes. | 141 // may suddenly start to return empty handles and it may cause crashes. |
146 Forcible, | 142 Forcible, |
147 | 143 |
148 // Don't synchronously terminate the worker execution. Instead, schedule | 144 // Don't synchronously terminate the worker execution. Instead, schedule |
149 // a task to terminate it in case that the shutdown sequence does not | 145 // a task to terminate it in case that the shutdown sequence does not |
150 // start on the worker thread in a certain time period. | 146 // start on the worker thread in a certain time period. |
151 Graceful, | 147 Graceful, |
152 }; | 148 }; |
153 | 149 |
154 std::unique_ptr<CrossThreadClosure> createWorkerThreadTask(std::unique_ptr<E
xecutionContextTask>, bool isInstrumented); | 150 std::unique_ptr<CrossThreadClosure> createWorkerThreadTask(std::unique_ptr<E
xecutionContextTask>, bool isInstrumented); |
155 | 151 |
156 void terminateInternal(TerminationMode); | 152 void terminateInternal(TerminationMode); |
157 void forciblyTerminateExecution(); | 153 void forciblyTerminateExecution(); |
158 | 154 |
159 void initializeOnWorkerThread(PassOwnPtr<WorkerThreadStartupData>); | |
160 void prepareForShutdownOnWorkerThread(); | 155 void prepareForShutdownOnWorkerThread(); |
161 void performShutdownOnWorkerThread(); | 156 void performShutdownOnWorkerThread(); |
162 void performTaskOnWorkerThread(std::unique_ptr<ExecutionContextTask>, bool i
sInstrumented); | 157 void performTaskOnWorkerThread(std::unique_ptr<ExecutionContextTask>, bool i
sInstrumented); |
163 void runDebuggerTaskOnWorkerThread(std::unique_ptr<CrossThreadClosure>); | 158 void runDebuggerTaskOnWorkerThread(std::unique_ptr<CrossThreadClosure>); |
164 void runDebuggerTaskDontWaitOnWorkerThread(); | 159 void runDebuggerTaskDontWaitOnWorkerThread(); |
165 | 160 |
166 void setForceTerminationDelayInMsForTesting(long long forceTerminationDelayI
nMs) { m_forceTerminationDelayInMs = forceTerminationDelayInMs; } | 161 void setForceTerminationDelayInMsForTesting(long long forceTerminationDelayI
nMs) { m_forceTerminationDelayInMs = forceTerminationDelayInMs; } |
167 | 162 |
168 bool m_started = false; | |
169 bool m_terminated = false; | |
170 bool m_readyToShutdown = false; | 163 bool m_readyToShutdown = false; |
171 bool m_pausedInDebugger = false; | 164 bool m_pausedInDebugger = false; |
172 bool m_runningDebuggerTask = false; | 165 bool m_runningDebuggerTask = false; |
173 ExitCode m_exitCode = ExitCode::NotTerminated; | 166 ExitCode m_exitCode = ExitCode::NotTerminated; |
174 | 167 |
175 long long m_forceTerminationDelayInMs; | 168 long long m_forceTerminationDelayInMs; |
176 | 169 |
177 OwnPtr<InspectorTaskRunner> m_inspectorTaskRunner; | 170 OwnPtr<InspectorTaskRunner> m_inspectorTaskRunner; |
178 OwnPtr<WorkerMicrotaskRunner> m_microtaskRunner; | 171 OwnPtr<WorkerMicrotaskRunner> m_microtaskRunner; |
179 | 172 |
180 RefPtr<WorkerLoaderProxy> m_workerLoaderProxy; | |
181 WorkerReportingProxy& m_workerReportingProxy; | 173 WorkerReportingProxy& m_workerReportingProxy; |
182 | 174 |
183 // This lock protects |m_workerGlobalScope|, |m_terminated|, | 175 // This lock protects |m_workerGlobalScope|, |m_terminated|, |
184 // |m_readyToShutdown|, |m_runningDebuggerTask|, |m_exitCode| and | 176 // |m_readyToShutdown|, |m_runningDebuggerTask|, |m_exitCode| and |
185 // |m_microtaskRunner|. | 177 // |m_microtaskRunner|. |
186 Mutex m_threadStateMutex; | 178 Mutex m_threadStateMutex; |
187 | 179 |
188 Persistent<WorkerGlobalScope> m_workerGlobalScope; | 180 Persistent<WorkerOrWorkletGlobalScope> m_globalScope; |
189 | 181 |
190 // Signaled when the thread starts termination on the main thread. | 182 // Signaled when the thread starts termination on the main thread. |
191 OwnPtr<WaitableEvent> m_terminationEvent; | 183 OwnPtr<WaitableEvent> m_terminationEvent; |
192 | 184 |
193 // Signaled when the thread completes termination on the worker thread. | 185 // Signaled when the thread completes termination on the worker thread. |
194 OwnPtr<WaitableEvent> m_shutdownEvent; | 186 OwnPtr<WaitableEvent> m_shutdownEvent; |
195 | 187 |
196 // Scheduled when termination starts with TerminationMode::Force, and | 188 // Scheduled when termination starts with TerminationMode::Force, and |
197 // cancelled when the worker thread is gracefully shut down. | 189 // cancelled when the worker thread is gracefully shut down. |
198 OwnPtr<ForceTerminationTask> m_scheduledForceTerminationTask; | 190 OwnPtr<ForceTerminationTask> m_scheduledForceTerminationTask; |
199 }; | 191 }; |
200 | 192 |
201 } // namespace blink | 193 } // namespace blink |
202 | 194 |
203 #endif // WorkerThread_h | 195 #endif // WorkerOrWorkletThread_h |
OLD | NEW |