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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 | 55 |
56 // WorkerThread is a kind of WorkerBackingThread client. Each worker mechanism | 56 // WorkerThread is a kind of WorkerBackingThread client. Each worker mechanism |
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 WorkerThreads can share one WorkerBackingThread. |
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 // WorkerThread start and termination must be initiated on the main thread 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 WorkerThread { |
64 public: | 64 public: |
| 65 // Represents how this thread is terminated. |
| 66 enum class ExitCode { |
| 67 NotTerminated, |
| 68 GracefullyTerminated, |
| 69 SyncForciblyTerminated, |
| 70 AsyncForciblyTerminated, |
| 71 }; |
| 72 |
65 virtual ~WorkerThread(); | 73 virtual ~WorkerThread(); |
66 | 74 |
67 // Called on the main thread. | 75 // Called on the main thread. |
68 void start(PassOwnPtr<WorkerThreadStartupData>); | 76 void start(PassOwnPtr<WorkerThreadStartupData>); |
69 void terminate(); | 77 void terminate(); |
70 | 78 |
71 // Called in shutdown sequence on the main thread. Internally calls | 79 // Called on the main thread. Internally calls terminateInternal() and wait |
72 // terminate() and wait (by *blocking* the calling thread) until the | 80 // (by *blocking* the calling thread) until the worker(s) is/are shut down. |
73 // worker(s) is/are shut down. | |
74 void terminateAndWait(); | 81 void terminateAndWait(); |
75 static void terminateAndWaitForAllWorkers(); | 82 static void terminateAndWaitForAllWorkers(); |
76 | 83 |
77 virtual WorkerBackingThread& workerBackingThread() = 0; | 84 virtual WorkerBackingThread& workerBackingThread() = 0; |
78 virtual bool shouldAttachThreadDebugger() const { return true; } | 85 virtual bool shouldAttachThreadDebugger() const { return true; } |
79 v8::Isolate* isolate(); | 86 v8::Isolate* isolate(); |
80 | 87 |
81 // Can be used to wait for this worker thread to terminate. | 88 // Can be used to wait for this worker thread to terminate. |
82 // (This is signaled on the main thread, so it's assumed to be waited on | 89 // (This is signaled on the main thread, so it's assumed to be waited on |
83 // the worker context thread) | 90 // the worker context thread) |
(...skipping 23 matching lines...) Expand all Loading... |
107 WorkerGlobalScope* workerGlobalScope(); | 114 WorkerGlobalScope* workerGlobalScope(); |
108 | 115 |
109 // Returns true once one of the terminate* methods is called. | 116 // Returns true once one of the terminate* methods is called. |
110 bool terminated(); | 117 bool terminated(); |
111 | 118 |
112 // Number of active worker threads. | 119 // Number of active worker threads. |
113 static unsigned workerThreadCount(); | 120 static unsigned workerThreadCount(); |
114 | 121 |
115 PlatformThreadId platformThreadId(); | 122 PlatformThreadId platformThreadId(); |
116 | 123 |
| 124 ExitCode getExitCode(); |
| 125 |
117 protected: | 126 protected: |
118 WorkerThread(PassRefPtr<WorkerLoaderProxy>, WorkerReportingProxy&); | 127 WorkerThread(PassRefPtr<WorkerLoaderProxy>, WorkerReportingProxy&); |
119 | 128 |
120 // Factory method for creating a new worker context for the thread. | 129 // Factory method for creating a new worker context for the thread. |
121 // Called on the worker thread. | 130 // Called on the worker thread. |
122 virtual WorkerGlobalScope* createWorkerGlobalScope(PassOwnPtr<WorkerThreadSt
artupData>) = 0; | 131 virtual WorkerGlobalScope* createWorkerGlobalScope(PassOwnPtr<WorkerThreadSt
artupData>) = 0; |
123 | 132 |
124 // Called on the worker thread. | 133 // Called on the worker thread. |
125 virtual void postInitialize() { } | 134 virtual void postInitialize() { } |
126 | 135 |
127 private: | 136 private: |
| 137 friend class WorkerThreadTest; |
| 138 |
| 139 class ForceTerminationTask; |
128 class WorkerMicrotaskRunner; | 140 class WorkerMicrotaskRunner; |
129 | 141 |
| 142 enum class TerminationMode { |
| 143 // Synchronously terminate the worker execution. Please be careful to |
| 144 // use this mode, because after the synchronous termination any V8 APIs |
| 145 // may suddenly start to return empty handles and it may cause crashes. |
| 146 Forcible, |
| 147 |
| 148 // Don't synchronously terminate the worker execution. Instead, schedule |
| 149 // a task to terminate it in case that the shutdown sequence does not |
| 150 // start on the worker thread in a certain time period. |
| 151 Graceful, |
| 152 }; |
| 153 |
130 std::unique_ptr<CrossThreadClosure> createWorkerThreadTask(std::unique_ptr<E
xecutionContextTask>, bool isInstrumented); | 154 std::unique_ptr<CrossThreadClosure> createWorkerThreadTask(std::unique_ptr<E
xecutionContextTask>, bool isInstrumented); |
131 | 155 |
| 156 void terminateInternal(TerminationMode); |
| 157 void forciblyTerminateExecution(); |
| 158 |
132 void initializeOnWorkerThread(PassOwnPtr<WorkerThreadStartupData>); | 159 void initializeOnWorkerThread(PassOwnPtr<WorkerThreadStartupData>); |
133 void prepareForShutdownOnWorkerThread(); | 160 void prepareForShutdownOnWorkerThread(); |
134 void performShutdownOnWorkerThread(); | 161 void performShutdownOnWorkerThread(); |
135 void performTaskOnWorkerThread(std::unique_ptr<ExecutionContextTask>, bool i
sInstrumented); | 162 void performTaskOnWorkerThread(std::unique_ptr<ExecutionContextTask>, bool i
sInstrumented); |
136 void runDebuggerTaskOnWorkerThread(std::unique_ptr<CrossThreadClosure>); | 163 void runDebuggerTaskOnWorkerThread(std::unique_ptr<CrossThreadClosure>); |
137 void runDebuggerTaskDontWaitOnWorkerThread(); | 164 void runDebuggerTaskDontWaitOnWorkerThread(); |
138 | 165 |
| 166 void setForceTerminationDelayInMsForTesting(long long forceTerminationDelayI
nMs) { m_forceTerminationDelayInMs = forceTerminationDelayInMs; } |
| 167 |
139 bool m_started = false; | 168 bool m_started = false; |
140 bool m_terminated = false; | 169 bool m_terminated = false; |
141 bool m_readyToShutdown = false; | 170 bool m_readyToShutdown = false; |
142 bool m_pausedInDebugger = false; | 171 bool m_pausedInDebugger = false; |
143 bool m_runningDebuggerTask = false; | 172 bool m_runningDebuggerTask = false; |
| 173 ExitCode m_exitCode = ExitCode::NotTerminated; |
| 174 |
| 175 long long m_forceTerminationDelayInMs; |
144 | 176 |
145 OwnPtr<InspectorTaskRunner> m_inspectorTaskRunner; | 177 OwnPtr<InspectorTaskRunner> m_inspectorTaskRunner; |
146 OwnPtr<WorkerMicrotaskRunner> m_microtaskRunner; | 178 OwnPtr<WorkerMicrotaskRunner> m_microtaskRunner; |
147 | 179 |
148 RefPtr<WorkerLoaderProxy> m_workerLoaderProxy; | 180 RefPtr<WorkerLoaderProxy> m_workerLoaderProxy; |
149 WorkerReportingProxy& m_workerReportingProxy; | 181 WorkerReportingProxy& m_workerReportingProxy; |
150 | 182 |
151 // This lock protects |m_workerGlobalScope|, |m_terminated|, | 183 // This lock protects |m_workerGlobalScope|, |m_terminated|, |
152 // |m_readyToShutdown|, |m_runningDebuggerTask| and |m_microtaskRunner|. | 184 // |m_readyToShutdown|, |m_runningDebuggerTask|, |m_exitCode| and |
| 185 // |m_microtaskRunner|. |
153 Mutex m_threadStateMutex; | 186 Mutex m_threadStateMutex; |
154 | 187 |
155 Persistent<WorkerGlobalScope> m_workerGlobalScope; | 188 Persistent<WorkerGlobalScope> m_workerGlobalScope; |
156 | 189 |
157 // Signaled when the thread starts termination on the main thread. | 190 // Signaled when the thread starts termination on the main thread. |
158 OwnPtr<WaitableEvent> m_terminationEvent; | 191 OwnPtr<WaitableEvent> m_terminationEvent; |
159 | 192 |
160 // Signaled when the thread completes termination on the worker thread. | 193 // Signaled when the thread completes termination on the worker thread. |
161 OwnPtr<WaitableEvent> m_shutdownEvent; | 194 OwnPtr<WaitableEvent> m_shutdownEvent; |
| 195 |
| 196 // Scheduled when termination starts with TerminationMode::Force, and |
| 197 // cancelled when the worker thread is gracefully shut down. |
| 198 OwnPtr<ForceTerminationTask> m_scheduledForceTerminationTask; |
162 }; | 199 }; |
163 | 200 |
164 } // namespace blink | 201 } // namespace blink |
165 | 202 |
166 #endif // WorkerThread_h | 203 #endif // WorkerThread_h |
OLD | NEW |