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