| 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 "config.h" | 27 #include "config.h" |
| 28 | 28 |
| 29 #include "core/workers/WorkerThread.h" | 29 #include "core/workers/WorkerScript.h" |
| 30 | 30 |
| 31 #include "bindings/core/v8/ScriptSourceCode.h" | 31 #include "bindings/core/v8/ScriptSourceCode.h" |
| 32 #include "bindings/core/v8/V8GCController.h" | 32 #include "bindings/core/v8/V8GCController.h" |
| 33 #include "bindings/core/v8/V8Initializer.h" | 33 #include "bindings/core/v8/V8Initializer.h" |
| 34 #include "core/dom/Microtask.h" | 34 #include "core/dom/Microtask.h" |
| 35 #include "core/inspector/InspectorInstrumentation.h" | 35 #include "core/inspector/InspectorInstrumentation.h" |
| 36 #include "core/inspector/WorkerInspectorController.h" | 36 #include "core/inspector/WorkerInspectorController.h" |
| 37 #include "core/workers/DedicatedWorkerGlobalScope.h" | 37 #include "core/workers/DedicatedWorkerGlobalScope.h" |
| 38 #include "core/workers/WorkerClients.h" | 38 #include "core/workers/WorkerClients.h" |
| 39 #include "core/workers/WorkerReportingProxy.h" | 39 #include "core/workers/WorkerReportingProxy.h" |
| 40 #include "core/workers/WorkerThreadStartupData.h" | 40 #include "core/workers/WorkerScriptStartupData.h" |
| 41 #include "platform/PlatformThreadData.h" | 41 #include "platform/PlatformThreadData.h" |
| 42 #include "platform/Task.h" | 42 #include "platform/Task.h" |
| 43 #include "platform/ThreadSafeFunctional.h" | 43 #include "platform/ThreadSafeFunctional.h" |
| 44 #include "platform/ThreadTimers.h" | 44 #include "platform/ThreadTimers.h" |
| 45 #include "platform/heap/SafePoint.h" | 45 #include "platform/heap/SafePoint.h" |
| 46 #include "platform/heap/ThreadState.h" | 46 #include "platform/heap/ThreadState.h" |
| 47 #include "platform/weborigin/KURL.h" | 47 #include "platform/weborigin/KURL.h" |
| 48 #include "public/platform/Platform.h" | 48 #include "public/platform/Platform.h" |
| 49 #include "public/platform/WebThread.h" | 49 #include "public/platform/WebThread.h" |
| 50 #include "public/platform/WebWaitableEvent.h" | 50 #include "public/platform/WebWaitableEvent.h" |
| 51 #include "wtf/Noncopyable.h" | 51 #include "wtf/Noncopyable.h" |
| 52 #include "wtf/WeakPtr.h" | 52 #include "wtf/WeakPtr.h" |
| 53 #include "wtf/text/WTFString.h" | 53 #include "wtf/text/WTFString.h" |
| 54 | 54 |
| 55 namespace blink { | 55 namespace blink { |
| 56 | 56 |
| 57 namespace { | 57 namespace { |
| 58 const int64_t kShortIdleHandlerDelayMs = 1000; | 58 const int64_t kShortIdleHandlerDelayMs = 1000; |
| 59 const int64_t kLongIdleHandlerDelayMs = 10*1000; | 59 const int64_t kLongIdleHandlerDelayMs = 10*1000; |
| 60 | 60 |
| 61 class MicrotaskRunner : public WebThread::TaskObserver { | 61 class MicrotaskRunner : public WebThread::TaskObserver { |
| 62 public: | 62 public: |
| 63 explicit MicrotaskRunner(WorkerThread* workerThread) | 63 explicit MicrotaskRunner(WorkerScript* workerScript) |
| 64 : m_workerThread(workerThread) | 64 : m_workerScript(workerScript) |
| 65 { | 65 { |
| 66 } | 66 } |
| 67 | 67 |
| 68 virtual void willProcessTask() override { } | 68 virtual void willProcessTask() override { } |
| 69 virtual void didProcessTask() override | 69 virtual void didProcessTask() override |
| 70 { | 70 { |
| 71 Microtask::performCheckpoint(); | 71 Microtask::performCheckpoint(); |
| 72 if (WorkerGlobalScope* globalScope = m_workerThread->workerGlobalScope()
) { | 72 if (WorkerGlobalScope* globalScope = m_workerScript->workerGlobalScope()
) { |
| 73 if (WorkerScriptController* scriptController = globalScope->script()
) | 73 if (WorkerScriptController* scriptController = globalScope->scriptCo
ntroller()) |
| 74 scriptController->rejectedPromises()->processQueue(); | 74 scriptController->rejectedPromises()->processQueue(); |
| 75 } | 75 } |
| 76 } | 76 } |
| 77 | 77 |
| 78 private: | 78 private: |
| 79 // Thread owns the microtask runner; reference remains | 79 // Thread owns the microtask runner; reference remains |
| 80 // valid for the lifetime of this object. | 80 // valid for the lifetime of this object. |
| 81 WorkerThread* m_workerThread; | 81 WorkerScript* m_workerScript; |
| 82 }; | 82 }; |
| 83 | 83 |
| 84 } // namespace | 84 } // namespace |
| 85 | 85 |
| 86 static Mutex& threadSetMutex() | 86 static Mutex& threadSetMutex() |
| 87 { | 87 { |
| 88 AtomicallyInitializedStaticReference(Mutex, mutex, new Mutex); | 88 AtomicallyInitializedStaticReference(Mutex, mutex, new Mutex); |
| 89 return mutex; | 89 return mutex; |
| 90 } | 90 } |
| 91 | 91 |
| 92 static HashSet<WorkerThread*>& workerThreads() | 92 static HashSet<WorkerScript*>& workerScripts() |
| 93 { | 93 { |
| 94 DEFINE_STATIC_LOCAL(HashSet<WorkerThread*>, threads, ()); | 94 DEFINE_STATIC_LOCAL(HashSet<WorkerScript*>, threads, ()); |
| 95 return threads; | 95 return threads; |
| 96 } | 96 } |
| 97 | 97 |
| 98 unsigned WorkerThread::workerThreadCount() | 98 unsigned WorkerScript::workerScriptCount() |
| 99 { | 99 { |
| 100 MutexLocker lock(threadSetMutex()); | 100 MutexLocker lock(threadSetMutex()); |
| 101 return workerThreads().size(); | 101 return workerScripts().size(); |
| 102 } | 102 } |
| 103 | 103 |
| 104 class WorkerThreadCancelableTask final : public ExecutionContextTask { | 104 class WorkerScriptCancelableTask final : public ExecutionContextTask { |
| 105 WTF_MAKE_NONCOPYABLE(WorkerThreadCancelableTask); WTF_MAKE_FAST_ALLOCATED(Wo
rkerThreadCancelableTask); | 105 WTF_MAKE_NONCOPYABLE(WorkerScriptCancelableTask); WTF_MAKE_FAST_ALLOCATED(Wo
rkerScriptCancelableTask); |
| 106 public: | 106 public: |
| 107 static PassOwnPtr<WorkerThreadCancelableTask> create(PassOwnPtr<Closure> clo
sure) | 107 static PassOwnPtr<WorkerScriptCancelableTask> create(PassOwnPtr<Closure> clo
sure) |
| 108 { | 108 { |
| 109 return adoptPtr(new WorkerThreadCancelableTask(closure)); | 109 return adoptPtr(new WorkerScriptCancelableTask(closure)); |
| 110 } | 110 } |
| 111 | 111 |
| 112 virtual ~WorkerThreadCancelableTask() { } | 112 virtual ~WorkerScriptCancelableTask() { } |
| 113 | 113 |
| 114 virtual void performTask(ExecutionContext*) override | 114 virtual void performTask(ExecutionContext*) override |
| 115 { | 115 { |
| 116 if (!m_taskCanceled) | 116 if (!m_taskCanceled) |
| 117 (*m_closure)(); | 117 (*m_closure)(); |
| 118 } | 118 } |
| 119 | 119 |
| 120 WeakPtr<WorkerThreadCancelableTask> createWeakPtr() { return m_weakFactory.c
reateWeakPtr(); } | 120 WeakPtr<WorkerScriptCancelableTask> createWeakPtr() { return m_weakFactory.c
reateWeakPtr(); } |
| 121 void cancelTask() { m_taskCanceled = true; } | 121 void cancelTask() { m_taskCanceled = true; } |
| 122 | 122 |
| 123 private: | 123 private: |
| 124 explicit WorkerThreadCancelableTask(PassOwnPtr<Closure> closure) | 124 explicit WorkerScriptCancelableTask(PassOwnPtr<Closure> closure) |
| 125 : m_closure(closure) | 125 : m_closure(closure) |
| 126 , m_weakFactory(this) | 126 , m_weakFactory(this) |
| 127 , m_taskCanceled(false) | 127 , m_taskCanceled(false) |
| 128 { } | 128 { } |
| 129 | 129 |
| 130 OwnPtr<Closure> m_closure; | 130 OwnPtr<Closure> m_closure; |
| 131 WeakPtrFactory<WorkerThreadCancelableTask> m_weakFactory; | 131 WeakPtrFactory<WorkerScriptCancelableTask> m_weakFactory; |
| 132 bool m_taskCanceled; | 132 bool m_taskCanceled; |
| 133 }; | 133 }; |
| 134 | 134 |
| 135 class WorkerSharedTimer : public SharedTimer { | 135 class WorkerSharedTimer : public SharedTimer { |
| 136 public: | 136 public: |
| 137 explicit WorkerSharedTimer(WorkerThread* workerThread) | 137 explicit WorkerSharedTimer(WorkerScript* workerScript) |
| 138 : m_workerThread(workerThread) | 138 : m_workerScript(workerScript) |
| 139 , m_running(false) | 139 , m_running(false) |
| 140 { } | 140 { } |
| 141 | 141 |
| 142 typedef void (*SharedTimerFunction)(); | 142 typedef void (*SharedTimerFunction)(); |
| 143 virtual void setFiredFunction(SharedTimerFunction func) | 143 virtual void setFiredFunction(SharedTimerFunction func) |
| 144 { | 144 { |
| 145 m_sharedTimerFunction = func; | 145 m_sharedTimerFunction = func; |
| 146 } | 146 } |
| 147 | 147 |
| 148 virtual void setFireInterval(double interval) | 148 virtual void setFireInterval(double interval) |
| 149 { | 149 { |
| 150 ASSERT(m_sharedTimerFunction); | 150 ASSERT(m_sharedTimerFunction); |
| 151 | 151 |
| 152 // See BlinkPlatformImpl::setSharedTimerFireInterval for explanation of | 152 // See BlinkPlatformImpl::setSharedTimerFireInterval for explanation of |
| 153 // why ceil is used in the interval calculation. | 153 // why ceil is used in the interval calculation. |
| 154 int64_t delay = static_cast<int64_t>(ceil(interval * 1000)); | 154 int64_t delay = static_cast<int64_t>(ceil(interval * 1000)); |
| 155 | 155 |
| 156 if (delay < 0) { | 156 if (delay < 0) { |
| 157 delay = 0; | 157 delay = 0; |
| 158 } | 158 } |
| 159 | 159 |
| 160 m_running = true; | 160 m_running = true; |
| 161 | 161 |
| 162 if (m_lastQueuedTask.get()) | 162 if (m_lastQueuedTask.get()) |
| 163 m_lastQueuedTask->cancelTask(); | 163 m_lastQueuedTask->cancelTask(); |
| 164 | 164 |
| 165 // Now queue the task as a cancellable one. | 165 // Now queue the task as a cancellable one. |
| 166 OwnPtr<WorkerThreadCancelableTask> task = WorkerThreadCancelableTask::cr
eate(bind(&WorkerSharedTimer::OnTimeout, this)); | 166 OwnPtr<WorkerScriptCancelableTask> task = WorkerScriptCancelableTask::cr
eate(bind(&WorkerSharedTimer::OnTimeout, this)); |
| 167 m_lastQueuedTask = task->createWeakPtr(); | 167 m_lastQueuedTask = task->createWeakPtr(); |
| 168 m_workerThread->postDelayedTask(FROM_HERE, task.release(), delay); | 168 m_workerScript->postDelayedTask(FROM_HERE, task.release(), delay); |
| 169 } | 169 } |
| 170 | 170 |
| 171 virtual void stop() | 171 virtual void stop() |
| 172 { | 172 { |
| 173 m_running = false; | 173 m_running = false; |
| 174 m_lastQueuedTask = nullptr; | 174 m_lastQueuedTask = nullptr; |
| 175 } | 175 } |
| 176 | 176 |
| 177 private: | 177 private: |
| 178 void OnTimeout() | 178 void OnTimeout() |
| 179 { | 179 { |
| 180 ASSERT(m_workerThread->workerGlobalScope()); | 180 ASSERT(m_workerScript->workerGlobalScope()); |
| 181 | 181 |
| 182 m_lastQueuedTask = nullptr; | 182 m_lastQueuedTask = nullptr; |
| 183 | 183 |
| 184 if (m_sharedTimerFunction && m_running && !m_workerThread->workerGlobalS
cope()->isClosing()) | 184 if (m_sharedTimerFunction && m_running && !m_workerScript->workerGlobalS
cope()->isClosing()) |
| 185 m_sharedTimerFunction(); | 185 m_sharedTimerFunction(); |
| 186 } | 186 } |
| 187 | 187 |
| 188 WorkerThread* m_workerThread; | 188 WorkerScript* m_workerScript; |
| 189 SharedTimerFunction m_sharedTimerFunction; | 189 SharedTimerFunction m_sharedTimerFunction; |
| 190 bool m_running; | 190 bool m_running; |
| 191 | 191 |
| 192 // The task to run OnTimeout, if any. While OnTimeout resets | 192 // The task to run OnTimeout, if any. While OnTimeout resets |
| 193 // m_lastQueuedTask, this must be a weak pointer because the | 193 // m_lastQueuedTask, this must be a weak pointer because the |
| 194 // worker runloop may delete the task as it is shutting down. | 194 // worker runloop may delete the task as it is shutting down. |
| 195 WeakPtr<WorkerThreadCancelableTask> m_lastQueuedTask; | 195 WeakPtr<WorkerScriptCancelableTask> m_lastQueuedTask; |
| 196 }; | 196 }; |
| 197 | 197 |
| 198 class WorkerThreadTask : public WebThread::Task { | 198 class WorkerScriptTask : public WebThread::Task { |
| 199 WTF_MAKE_NONCOPYABLE(WorkerThreadTask); WTF_MAKE_FAST_ALLOCATED(WorkerThread
Task); | 199 WTF_MAKE_NONCOPYABLE(WorkerScriptTask); WTF_MAKE_FAST_ALLOCATED(WorkerScript
Task); |
| 200 public: | 200 public: |
| 201 static PassOwnPtr<WorkerThreadTask> create(WorkerThread& workerThread, PassO
wnPtr<ExecutionContextTask> task, bool isInstrumented) | 201 static PassOwnPtr<WorkerScriptTask> create(WorkerScript& workerScript, PassO
wnPtr<ExecutionContextTask> task, bool isInstrumented) |
| 202 { | 202 { |
| 203 return adoptPtr(new WorkerThreadTask(workerThread, task, isInstrumented)
); | 203 return adoptPtr(new WorkerScriptTask(workerScript, task, isInstrumented)
); |
| 204 } | 204 } |
| 205 | 205 |
| 206 virtual ~WorkerThreadTask() { } | 206 virtual ~WorkerScriptTask() { } |
| 207 | 207 |
| 208 virtual void run() override | 208 virtual void run() override |
| 209 { | 209 { |
| 210 WorkerGlobalScope* workerGlobalScope = m_workerThread.workerGlobalScope(
); | 210 WorkerGlobalScope* workerGlobalScope = m_workerScript.workerGlobalScope(
); |
| 211 // Tasks could be put on the message loop after the cleanup task, | 211 // Tasks could be put on the message loop after the cleanup task, |
| 212 // ensure none of those are ran. | 212 // ensure none of those are ran. |
| 213 if (!workerGlobalScope) | 213 if (!workerGlobalScope) |
| 214 return; | 214 return; |
| 215 | 215 |
| 216 if (m_isInstrumented) | 216 if (m_isInstrumented) |
| 217 InspectorInstrumentation::willPerformExecutionContextTask(workerGlob
alScope, m_task.get()); | 217 InspectorInstrumentation::willPerformExecutionContextTask(workerGlob
alScope, m_task.get()); |
| 218 if ((!workerGlobalScope->isClosing() && !m_workerThread.terminated()) ||
m_task->isCleanupTask()) | 218 if ((!workerGlobalScope->isClosing() && !m_workerScript.terminated()) ||
m_task->isCleanupTask()) |
| 219 m_task->performTask(workerGlobalScope); | 219 m_task->performTask(workerGlobalScope); |
| 220 if (m_isInstrumented) | 220 if (m_isInstrumented) |
| 221 InspectorInstrumentation::didPerformExecutionContextTask(workerGloba
lScope); | 221 InspectorInstrumentation::didPerformExecutionContextTask(workerGloba
lScope); |
| 222 } | 222 } |
| 223 | 223 |
| 224 private: | 224 private: |
| 225 WorkerThreadTask(WorkerThread& workerThread, PassOwnPtr<ExecutionContextTask
> task, bool isInstrumented) | 225 WorkerScriptTask(WorkerScript& workerScript, PassOwnPtr<ExecutionContextTask
> task, bool isInstrumented) |
| 226 : m_workerThread(workerThread) | 226 : m_workerScript(workerScript) |
| 227 , m_task(task) | 227 , m_task(task) |
| 228 , m_isInstrumented(isInstrumented) | 228 , m_isInstrumented(isInstrumented) |
| 229 { | 229 { |
| 230 if (m_isInstrumented) | 230 if (m_isInstrumented) |
| 231 m_isInstrumented = !m_task->taskNameForInstrumentation().isEmpty(); | 231 m_isInstrumented = !m_task->taskNameForInstrumentation().isEmpty(); |
| 232 if (m_isInstrumented) | 232 if (m_isInstrumented) |
| 233 InspectorInstrumentation::didPostExecutionContextTask(m_workerThread
.workerGlobalScope(), m_task.get()); | 233 InspectorInstrumentation::didPostExecutionContextTask(m_workerScript
.workerGlobalScope(), m_task.get()); |
| 234 } | 234 } |
| 235 | 235 |
| 236 WorkerThread& m_workerThread; | 236 WorkerScript& m_workerScript; |
| 237 OwnPtr<ExecutionContextTask> m_task; | 237 OwnPtr<ExecutionContextTask> m_task; |
| 238 bool m_isInstrumented; | 238 bool m_isInstrumented; |
| 239 }; | 239 }; |
| 240 | 240 |
| 241 class RunDebuggerQueueTask final : public ExecutionContextTask { | 241 class RunDebuggerQueueTask final : public ExecutionContextTask { |
| 242 public: | 242 public: |
| 243 static PassOwnPtr<RunDebuggerQueueTask> create(WorkerThread* thread) | 243 static PassOwnPtr<RunDebuggerQueueTask> create(WorkerScript* thread) |
| 244 { | 244 { |
| 245 return adoptPtr(new RunDebuggerQueueTask(thread)); | 245 return adoptPtr(new RunDebuggerQueueTask(thread)); |
| 246 } | 246 } |
| 247 virtual void performTask(ExecutionContext* context) override | 247 virtual void performTask(ExecutionContext* context) override |
| 248 { | 248 { |
| 249 ASSERT(context->isWorkerGlobalScope()); | 249 ASSERT(context->isWorkerGlobalScope()); |
| 250 m_thread->runDebuggerTask(WorkerThread::DontWaitForMessage); | 250 m_thread->runDebuggerTask(WorkerScript::DontWaitForMessage); |
| 251 } | 251 } |
| 252 | 252 |
| 253 private: | 253 private: |
| 254 explicit RunDebuggerQueueTask(WorkerThread* thread) : m_thread(thread) { } | 254 explicit RunDebuggerQueueTask(WorkerScript* thread) : m_thread(thread) { } |
| 255 | 255 |
| 256 WorkerThread* m_thread; | 256 WorkerScript* m_thread; |
| 257 }; | 257 }; |
| 258 | 258 |
| 259 WorkerThread::WorkerThread(PassRefPtr<WorkerLoaderProxy> workerLoaderProxy, Work
erReportingProxy& workerReportingProxy, PassOwnPtr<WorkerThreadStartupData> star
tupData) | 259 WorkerScript::WorkerScript(PassRefPtr<WorkerLoaderProxy> workerLoaderProxy, Work
erReportingProxy& workerReportingProxy, PassOwnPtr<WorkerScriptStartupData> star
tupData) |
| 260 : m_started(false) | 260 : m_started(false) |
| 261 , m_terminated(false) | 261 , m_terminated(false) |
| 262 , m_workerLoaderProxy(workerLoaderProxy) | 262 , m_workerLoaderProxy(workerLoaderProxy) |
| 263 , m_workerReportingProxy(workerReportingProxy) | 263 , m_workerReportingProxy(workerReportingProxy) |
| 264 , m_startupData(startupData) | 264 , m_startupData(startupData) |
| 265 , m_isolate(nullptr) | 265 , m_isolate(nullptr) |
| 266 , m_shutdownEvent(adoptPtr(Platform::current()->createWaitableEvent())) | 266 , m_shutdownEvent(adoptPtr(Platform::current()->createWaitableEvent())) |
| 267 , m_terminationEvent(adoptPtr(Platform::current()->createWaitableEvent())) | 267 , m_terminationEvent(adoptPtr(Platform::current()->createWaitableEvent())) |
| 268 { | 268 { |
| 269 MutexLocker lock(threadSetMutex()); | 269 MutexLocker lock(threadSetMutex()); |
| 270 workerThreads().add(this); | 270 workerScripts().add(this); |
| 271 } | 271 } |
| 272 | 272 |
| 273 WorkerThread::~WorkerThread() | 273 WorkerScript::~WorkerScript() |
| 274 { | 274 { |
| 275 MutexLocker lock(threadSetMutex()); | 275 MutexLocker lock(threadSetMutex()); |
| 276 ASSERT(workerThreads().contains(this)); | 276 ASSERT(workerScripts().contains(this)); |
| 277 workerThreads().remove(this); | 277 workerScripts().remove(this); |
| 278 } | 278 } |
| 279 | 279 |
| 280 void WorkerThread::start() | 280 void WorkerScript::start() |
| 281 { | 281 { |
| 282 if (m_started) | 282 if (m_started) |
| 283 return; | 283 return; |
| 284 | 284 |
| 285 m_started = true; | 285 m_started = true; |
| 286 backingThread().postTask(FROM_HERE, new Task(threadSafeBind(&WorkerThread::i
nitialize, AllowCrossThreadAccess(this)))); | 286 backingThread().postTask(FROM_HERE, new Task(threadSafeBind(&WorkerScript::i
nitialize, AllowCrossThreadAccess(this)))); |
| 287 } | 287 } |
| 288 | 288 |
| 289 void WorkerThread::interruptAndDispatchInspectorCommands() | 289 void WorkerScript::interruptAndDispatchInspectorCommands() |
| 290 { | 290 { |
| 291 MutexLocker locker(m_workerInspectorControllerMutex); | 291 MutexLocker locker(m_workerInspectorControllerMutex); |
| 292 if (m_workerInspectorController) | 292 if (m_workerInspectorController) |
| 293 m_workerInspectorController->interruptAndDispatchInspectorCommands(); | 293 m_workerInspectorController->interruptAndDispatchInspectorCommands(); |
| 294 } | 294 } |
| 295 | 295 |
| 296 PlatformThreadId WorkerThread::platformThreadId() | 296 PlatformThreadId WorkerScript::platformThreadId() |
| 297 { | 297 { |
| 298 if (!m_started) | 298 if (!m_started) |
| 299 return 0; | 299 return 0; |
| 300 return backingThread().platformThread().threadId(); | 300 return backingThread().platformThread().threadId(); |
| 301 } | 301 } |
| 302 | 302 |
| 303 void WorkerThread::initialize() | 303 void WorkerScript::initialize() |
| 304 { | 304 { |
| 305 KURL scriptURL = m_startupData->m_scriptURL; | 305 KURL scriptURL = m_startupData->m_scriptURL; |
| 306 String sourceCode = m_startupData->m_sourceCode; | 306 String sourceCode = m_startupData->m_sourceCode; |
| 307 WorkerThreadStartMode startMode = m_startupData->m_startMode; | 307 WorkerThreadStartMode startMode = m_startupData->m_startMode; |
| 308 OwnPtr<Vector<char>> cachedMetaData = m_startupData->m_cachedMetaData.releas
e(); | 308 OwnPtr<Vector<char>> cachedMetaData = m_startupData->m_cachedMetaData.releas
e(); |
| 309 V8CacheOptions v8CacheOptions = m_startupData->m_v8CacheOptions; | 309 V8CacheOptions v8CacheOptions = m_startupData->m_v8CacheOptions; |
| 310 | 310 |
| 311 { | 311 { |
| 312 MutexLocker lock(m_threadCreationMutex); | 312 MutexLocker lock(m_threadCreationMutex); |
| 313 | 313 |
| 314 // The worker was terminated before the thread had a chance to run. | 314 // The worker was terminated before the thread had a chance to run. |
| 315 if (m_terminated) { | 315 if (m_terminated) { |
| 316 // Notify the proxy that the WorkerGlobalScope has been disposed of. | 316 // Notify the proxy that the WorkerGlobalScope has been disposed of. |
| 317 // This can free this thread object, hence it must not be touched af
terwards. | 317 // This can free this thread object, hence it must not be touched af
terwards. |
| 318 m_workerReportingProxy.workerThreadTerminated(); | 318 m_workerReportingProxy.workerScriptTerminated(); |
| 319 return; | 319 return; |
| 320 } | 320 } |
| 321 | 321 |
| 322 m_microtaskRunner = adoptPtr(new MicrotaskRunner(this)); | 322 m_microtaskRunner = adoptPtr(new MicrotaskRunner(this)); |
| 323 backingThread().addTaskObserver(m_microtaskRunner.get()); | 323 backingThread().addTaskObserver(m_microtaskRunner.get()); |
| 324 backingThread().attachGC(); | 324 backingThread().attachGC(); |
| 325 | 325 |
| 326 m_isolate = initializeIsolate(); | 326 m_isolate = initializeIsolate(); |
| 327 m_workerGlobalScope = createWorkerGlobalScope(m_startupData.release()); | 327 m_workerGlobalScope = createWorkerGlobalScope(m_startupData.release()); |
| 328 m_workerGlobalScope->scriptLoaded(sourceCode.length(), cachedMetaData.ge
t() ? cachedMetaData->size() : 0); | 328 m_workerGlobalScope->scriptLoaded(sourceCode.length(), cachedMetaData.ge
t() ? cachedMetaData->size() : 0); |
| 329 | 329 |
| 330 PlatformThreadData::current().threadTimers().setSharedTimer(adoptPtr(new
WorkerSharedTimer(this))); | 330 PlatformThreadData::current().threadTimers().setSharedTimer(adoptPtr(new
WorkerSharedTimer(this))); |
| 331 } | 331 } |
| 332 | 332 |
| 333 // The corresponding call to stopRunLoop() is in ~WorkerScriptController(). | 333 // The corresponding call to stopRunLoop() is in ~WorkerScriptController(). |
| 334 didStartRunLoop(); | 334 didStartRunLoop(); |
| 335 | 335 |
| 336 // Notify proxy that a new WorkerGlobalScope has been created and started. | 336 // Notify proxy that a new WorkerGlobalScope has been created and started. |
| 337 m_workerReportingProxy.workerGlobalScopeStarted(m_workerGlobalScope.get()); | 337 m_workerReportingProxy.workerGlobalScopeStarted(m_workerGlobalScope.get()); |
| 338 | 338 |
| 339 WorkerScriptController* script = m_workerGlobalScope->script(); | 339 WorkerScriptController* script = m_workerGlobalScope->scriptController(); |
| 340 if (!script->isExecutionForbidden()) | 340 if (!script->isExecutionForbidden()) |
| 341 script->initializeContextIfNeeded(); | 341 script->initializeContextIfNeeded(); |
| 342 if (startMode == PauseWorkerGlobalScopeOnStart) | 342 if (startMode == PauseWorkerGlobalScopeOnStart) |
| 343 m_workerGlobalScope->workerInspectorController()->pauseOnStart(); | 343 m_workerGlobalScope->workerInspectorController()->pauseOnStart(); |
| 344 | 344 |
| 345 OwnPtr<CachedMetadataHandler> handler(workerGlobalScope()->createWorkerScrip
tCachedMetadataHandler(scriptURL, cachedMetaData.get())); | 345 OwnPtr<CachedMetadataHandler> handler(workerGlobalScope()->createWorkerScrip
tCachedMetadataHandler(scriptURL, cachedMetaData.get())); |
| 346 bool success = script->evaluate(ScriptSourceCode(sourceCode, scriptURL), nul
lptr, handler.get(), v8CacheOptions); | 346 bool success = script->evaluate(ScriptSourceCode(sourceCode, scriptURL), nul
lptr, handler.get(), v8CacheOptions); |
| 347 m_workerGlobalScope->didEvaluateWorkerScript(); | 347 m_workerGlobalScope->didEvaluateWorkerScript(); |
| 348 m_workerReportingProxy.didEvaluateWorkerScript(success); | 348 m_workerReportingProxy.didEvaluateWorkerScript(success); |
| 349 | 349 |
| 350 postInitialize(); | 350 postInitialize(); |
| 351 | 351 |
| 352 postDelayedTask(FROM_HERE, createSameThreadTask(&WorkerThread::idleHandler,
this), kShortIdleHandlerDelayMs); | 352 postDelayedTask(FROM_HERE, createSameThreadTask(&WorkerScript::idleHandler,
this), kShortIdleHandlerDelayMs); |
| 353 } | 353 } |
| 354 | 354 |
| 355 void WorkerThread::cleanup() | 355 void WorkerScript::cleanup() |
| 356 { | 356 { |
| 357 // This should be called before we start the shutdown procedure. | 357 // This should be called before we start the shutdown procedure. |
| 358 workerReportingProxy().willDestroyWorkerGlobalScope(); | 358 workerReportingProxy().willDestroyWorkerGlobalScope(); |
| 359 | 359 |
| 360 // The below assignment will destroy the context, which will in turn notify
messaging proxy. | 360 // The below assignment will destroy the context, which will in turn notify
messaging proxy. |
| 361 // We cannot let any objects survive past thread exit, because no other thre
ad will run GC or otherwise destroy them. | 361 // We cannot let any objects survive past thread exit, because no other thre
ad will run GC or otherwise destroy them. |
| 362 // If Oilpan is enabled, we detach of the context/global scope, with the fin
al heap cleanup below sweeping it out. | 362 // If Oilpan is enabled, we detach of the context/global scope, with the fin
al heap cleanup below sweeping it out. |
| 363 #if !ENABLE(OILPAN) | 363 #if !ENABLE(OILPAN) |
| 364 ASSERT(m_workerGlobalScope->hasOneRef()); | 364 ASSERT(m_workerGlobalScope->hasOneRef()); |
| 365 #endif | 365 #endif |
| 366 m_workerGlobalScope->notifyContextDestroyed(); | 366 m_workerGlobalScope->notifyContextDestroyed(); |
| 367 m_workerGlobalScope = nullptr; | 367 m_workerGlobalScope = nullptr; |
| 368 | 368 |
| 369 backingThread().detachGC(); | 369 backingThread().detachGC(); |
| 370 destroyIsolate(); | 370 destroyIsolate(); |
| 371 | 371 |
| 372 backingThread().removeTaskObserver(m_microtaskRunner.get()); | 372 backingThread().removeTaskObserver(m_microtaskRunner.get()); |
| 373 m_microtaskRunner = nullptr; | 373 m_microtaskRunner = nullptr; |
| 374 | 374 |
| 375 // Notify the proxy that the WorkerGlobalScope has been disposed of. | 375 // Notify the proxy that the WorkerGlobalScope has been disposed of. |
| 376 // This can free this thread object, hence it must not be touched afterwards
. | 376 // This can free this thread object, hence it must not be touched afterwards
. |
| 377 workerReportingProxy().workerThreadTerminated(); | 377 workerReportingProxy().workerScriptTerminated(); |
| 378 | 378 |
| 379 m_terminationEvent->signal(); | 379 m_terminationEvent->signal(); |
| 380 | 380 |
| 381 // Clean up PlatformThreadData before WTF::WTFThreadData goes away! | 381 // Clean up PlatformThreadData before WTF::WTFThreadData goes away! |
| 382 PlatformThreadData::current().destroy(); | 382 PlatformThreadData::current().destroy(); |
| 383 } | 383 } |
| 384 | 384 |
| 385 class WorkerThreadShutdownFinishTask : public ExecutionContextTask { | 385 class WorkerScriptShutdownFinishTask : public ExecutionContextTask { |
| 386 public: | 386 public: |
| 387 static PassOwnPtr<WorkerThreadShutdownFinishTask> create() | 387 static PassOwnPtr<WorkerScriptShutdownFinishTask> create() |
| 388 { | 388 { |
| 389 return adoptPtr(new WorkerThreadShutdownFinishTask()); | 389 return adoptPtr(new WorkerScriptShutdownFinishTask()); |
| 390 } | 390 } |
| 391 | 391 |
| 392 virtual void performTask(ExecutionContext *context) | 392 virtual void performTask(ExecutionContext *context) |
| 393 { | 393 { |
| 394 WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context); | 394 WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context); |
| 395 workerGlobalScope->dispose(); | 395 workerGlobalScope->dispose(); |
| 396 | 396 |
| 397 WorkerThread* workerThread = workerGlobalScope->thread(); | 397 WorkerScript* workerScript = workerGlobalScope->script(); |
| 398 workerThread->willDestroyIsolate(); | 398 workerScript->willDestroyIsolate(); |
| 399 workerThread->backingThread().postTask(FROM_HERE, new Task(WTF::bind(&Wo
rkerThread::cleanup, workerThread))); | 399 workerScript->backingThread().postTask(FROM_HERE, new Task(WTF::bind(&Wo
rkerScript::cleanup, workerScript))); |
| 400 } | 400 } |
| 401 | 401 |
| 402 virtual bool isCleanupTask() const { return true; } | 402 virtual bool isCleanupTask() const { return true; } |
| 403 }; | 403 }; |
| 404 | 404 |
| 405 class WorkerThreadShutdownStartTask : public ExecutionContextTask { | 405 class WorkerScriptShutdownStartTask : public ExecutionContextTask { |
| 406 public: | 406 public: |
| 407 static PassOwnPtr<WorkerThreadShutdownStartTask> create() | 407 static PassOwnPtr<WorkerScriptShutdownStartTask> create() |
| 408 { | 408 { |
| 409 return adoptPtr(new WorkerThreadShutdownStartTask()); | 409 return adoptPtr(new WorkerScriptShutdownStartTask()); |
| 410 } | 410 } |
| 411 | 411 |
| 412 virtual void performTask(ExecutionContext *context) | 412 virtual void performTask(ExecutionContext *context) |
| 413 { | 413 { |
| 414 WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context); | 414 WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context); |
| 415 workerGlobalScope->stopActiveDOMObjects(); | 415 workerGlobalScope->stopActiveDOMObjects(); |
| 416 PlatformThreadData::current().threadTimers().setSharedTimer(nullptr); | 416 PlatformThreadData::current().threadTimers().setSharedTimer(nullptr); |
| 417 | 417 |
| 418 // Event listeners would keep DOMWrapperWorld objects alive for too long
. Also, they have references to JS objects, | 418 // Event listeners would keep DOMWrapperWorld objects alive for too long
. Also, they have references to JS objects, |
| 419 // which become dangling once Heap is destroyed. | 419 // which become dangling once Heap is destroyed. |
| 420 workerGlobalScope->removeAllEventListeners(); | 420 workerGlobalScope->removeAllEventListeners(); |
| 421 | 421 |
| 422 // Stick a shutdown command at the end of the queue, so that we deal | 422 // Stick a shutdown command at the end of the queue, so that we deal |
| 423 // with all the cleanup tasks the databases post first. | 423 // with all the cleanup tasks the databases post first. |
| 424 workerGlobalScope->postTask(FROM_HERE, WorkerThreadShutdownFinishTask::c
reate()); | 424 workerGlobalScope->postTask(FROM_HERE, WorkerScriptShutdownFinishTask::c
reate()); |
| 425 } | 425 } |
| 426 | 426 |
| 427 virtual bool isCleanupTask() const { return true; } | 427 virtual bool isCleanupTask() const { return true; } |
| 428 }; | 428 }; |
| 429 | 429 |
| 430 void WorkerThread::stop() | 430 void WorkerScript::stop() |
| 431 { | 431 { |
| 432 // Prevent the deadlock between GC and an attempt to stop a thread. | 432 // Prevent the deadlock between GC and an attempt to stop a thread. |
| 433 SafePointScope safePointScope(ThreadState::HeapPointersOnStack); | 433 SafePointScope safePointScope(ThreadState::HeapPointersOnStack); |
| 434 stopInternal(); | 434 stopInternal(); |
| 435 } | 435 } |
| 436 | 436 |
| 437 void WorkerThread::stopInShutdownSequence() | 437 void WorkerScript::stopInShutdownSequence() |
| 438 { | 438 { |
| 439 stopInternal(); | 439 stopInternal(); |
| 440 } | 440 } |
| 441 | 441 |
| 442 void WorkerThread::terminateAndWait() | 442 void WorkerScript::terminateAndWait() |
| 443 { | 443 { |
| 444 stop(); | 444 stop(); |
| 445 m_terminationEvent->wait(); | 445 m_terminationEvent->wait(); |
| 446 } | 446 } |
| 447 | 447 |
| 448 bool WorkerThread::terminated() | 448 bool WorkerScript::terminated() |
| 449 { | 449 { |
| 450 MutexLocker lock(m_threadCreationMutex); | 450 MutexLocker lock(m_threadCreationMutex); |
| 451 return m_terminated; | 451 return m_terminated; |
| 452 } | 452 } |
| 453 | 453 |
| 454 void WorkerThread::stopInternal() | 454 void WorkerScript::stopInternal() |
| 455 { | 455 { |
| 456 // Protect against this method and initialize() racing each other. | 456 // Protect against this method and initialize() racing each other. |
| 457 MutexLocker lock(m_threadCreationMutex); | 457 MutexLocker lock(m_threadCreationMutex); |
| 458 | 458 |
| 459 // If stop has already been called, just return. | 459 // If stop has already been called, just return. |
| 460 if (m_terminated) | 460 if (m_terminated) |
| 461 return; | 461 return; |
| 462 m_terminated = true; | 462 m_terminated = true; |
| 463 | 463 |
| 464 // Signal the thread to notify that the thread's stopping. | 464 // Signal the thread to notify that the thread's stopping. |
| 465 if (m_shutdownEvent) | 465 if (m_shutdownEvent) |
| 466 m_shutdownEvent->signal(); | 466 m_shutdownEvent->signal(); |
| 467 | 467 |
| 468 if (!m_workerGlobalScope) | 468 if (!m_workerGlobalScope) |
| 469 return; | 469 return; |
| 470 | 470 |
| 471 // Ensure that tasks are being handled by thread event loop. If script execu
tion weren't forbidden, a while(1) loop in JS could keep the thread alive foreve
r. | 471 // Ensure that tasks are being handled by thread event loop. If script execu
tion weren't forbidden, a while(1) loop in JS could keep the thread alive foreve
r. |
| 472 terminateV8Execution(); | 472 terminateV8Execution(); |
| 473 | 473 |
| 474 InspectorInstrumentation::didKillAllExecutionContextTasks(m_workerGlobalScop
e.get()); | 474 InspectorInstrumentation::didKillAllExecutionContextTasks(m_workerGlobalScop
e.get()); |
| 475 m_debuggerMessageQueue.kill(); | 475 m_debuggerMessageQueue.kill(); |
| 476 postTask(FROM_HERE, WorkerThreadShutdownStartTask::create()); | 476 postTask(FROM_HERE, WorkerScriptShutdownStartTask::create()); |
| 477 } | 477 } |
| 478 | 478 |
| 479 void WorkerThread::didStartRunLoop() | 479 void WorkerScript::didStartRunLoop() |
| 480 { | 480 { |
| 481 ASSERT(isCurrentThread()); | 481 ASSERT(isCurrentThread()); |
| 482 Platform::current()->didStartWorkerRunLoop(); | 482 Platform::current()->didStartWorkerRunLoop(); |
| 483 } | 483 } |
| 484 | 484 |
| 485 void WorkerThread::didStopRunLoop() | 485 void WorkerScript::didStopRunLoop() |
| 486 { | 486 { |
| 487 ASSERT(isCurrentThread()); | 487 ASSERT(isCurrentThread()); |
| 488 Platform::current()->didStopWorkerRunLoop(); | 488 Platform::current()->didStopWorkerRunLoop(); |
| 489 } | 489 } |
| 490 | 490 |
| 491 void WorkerThread::terminateAndWaitForAllWorkers() | 491 void WorkerScript::terminateAndWaitForAllWorkers() |
| 492 { | 492 { |
| 493 // Keep this lock to prevent WorkerThread instances from being destroyed. | 493 // Keep this lock to prevent WorkerScript instances from being destroyed. |
| 494 MutexLocker lock(threadSetMutex()); | 494 MutexLocker lock(threadSetMutex()); |
| 495 HashSet<WorkerThread*> threads = workerThreads(); | 495 HashSet<WorkerScript*> threads = workerScripts(); |
| 496 for (WorkerThread* thread : threads) | 496 for (WorkerScript* thread : threads) |
| 497 thread->stopInShutdownSequence(); | 497 thread->stopInShutdownSequence(); |
| 498 | 498 |
| 499 for (WorkerThread* thread : threads) | 499 for (WorkerScript* thread : threads) |
| 500 thread->terminationEvent()->wait(); | 500 thread->terminationEvent()->wait(); |
| 501 } | 501 } |
| 502 | 502 |
| 503 bool WorkerThread::isCurrentThread() | 503 bool WorkerScript::isCurrentThread() |
| 504 { | 504 { |
| 505 return m_started && backingThread().isCurrentThread(); | 505 return m_started && backingThread().isCurrentThread(); |
| 506 } | 506 } |
| 507 | 507 |
| 508 void WorkerThread::idleHandler() | 508 void WorkerScript::idleHandler() |
| 509 { | 509 { |
| 510 ASSERT(m_workerGlobalScope.get()); | 510 ASSERT(m_workerGlobalScope.get()); |
| 511 int64_t delay = kLongIdleHandlerDelayMs; | 511 int64_t delay = kLongIdleHandlerDelayMs; |
| 512 | 512 |
| 513 // Do a script engine idle notification if the next event is distant enough. | 513 // Do a script engine idle notification if the next event is distant enough. |
| 514 const double kMinIdleTimespan = 0.3; | 514 const double kMinIdleTimespan = 0.3; |
| 515 const double nextFireTime = PlatformThreadData::current().threadTimers().nex
tFireTime(); | 515 const double nextFireTime = PlatformThreadData::current().threadTimers().nex
tFireTime(); |
| 516 if (nextFireTime == 0.0 || nextFireTime > currentTime() + kMinIdleTimespan)
{ | 516 if (nextFireTime == 0.0 || nextFireTime > currentTime() + kMinIdleTimespan)
{ |
| 517 bool hasMoreWork = !isolate()->IdleNotificationDeadline(Platform::curren
t()->monotonicallyIncreasingTime() + 1.0); | 517 bool hasMoreWork = !isolate()->IdleNotificationDeadline(Platform::curren
t()->monotonicallyIncreasingTime() + 1.0); |
| 518 if (hasMoreWork) | 518 if (hasMoreWork) |
| 519 delay = kShortIdleHandlerDelayMs; | 519 delay = kShortIdleHandlerDelayMs; |
| 520 } | 520 } |
| 521 | 521 |
| 522 postDelayedTask(FROM_HERE, createSameThreadTask(&WorkerThread::idleHandler,
this), delay); | 522 postDelayedTask(FROM_HERE, createSameThreadTask(&WorkerScript::idleHandler,
this), delay); |
| 523 } | 523 } |
| 524 | 524 |
| 525 void WorkerThread::postTask(const WebTraceLocation& location, PassOwnPtr<Executi
onContextTask> task) | 525 void WorkerScript::postTask(const WebTraceLocation& location, PassOwnPtr<Executi
onContextTask> task) |
| 526 { | 526 { |
| 527 backingThread().postTask(location, WorkerThreadTask::create(*this, task, tru
e).leakPtr()); | 527 backingThread().postTask(location, WorkerScriptTask::create(*this, task, tru
e).leakPtr()); |
| 528 } | 528 } |
| 529 | 529 |
| 530 void WorkerThread::postDelayedTask(const WebTraceLocation& location, PassOwnPtr<
ExecutionContextTask> task, long long delayMs) | 530 void WorkerScript::postDelayedTask(const WebTraceLocation& location, PassOwnPtr<
ExecutionContextTask> task, long long delayMs) |
| 531 { | 531 { |
| 532 backingThread().postDelayedTask(location, WorkerThreadTask::create(*this, ta
sk, true).leakPtr(), delayMs); | 532 backingThread().postDelayedTask(location, WorkerScriptTask::create(*this, ta
sk, true).leakPtr(), delayMs); |
| 533 } | 533 } |
| 534 | 534 |
| 535 v8::Isolate* WorkerThread::initializeIsolate() | 535 v8::Isolate* WorkerScript::initializeIsolate() |
| 536 { | 536 { |
| 537 ASSERT(isCurrentThread()); | 537 ASSERT(isCurrentThread()); |
| 538 ASSERT(!m_isolate); | 538 ASSERT(!m_isolate); |
| 539 v8::Isolate* isolate = V8PerIsolateData::initialize(); | 539 v8::Isolate* isolate = V8PerIsolateData::initialize(); |
| 540 V8Initializer::initializeWorker(isolate); | 540 V8Initializer::initializeWorker(isolate); |
| 541 | 541 |
| 542 m_interruptor = adoptPtr(new V8IsolateInterruptor(isolate)); | 542 m_interruptor = adoptPtr(new V8IsolateInterruptor(isolate)); |
| 543 ThreadState::current()->addInterruptor(m_interruptor.get()); | 543 ThreadState::current()->addInterruptor(m_interruptor.get()); |
| 544 ThreadState::current()->registerTraceDOMWrappers(isolate, V8GCController::tr
aceDOMWrappers); | 544 ThreadState::current()->registerTraceDOMWrappers(isolate, V8GCController::tr
aceDOMWrappers); |
| 545 | 545 |
| 546 return isolate; | 546 return isolate; |
| 547 } | 547 } |
| 548 | 548 |
| 549 void WorkerThread::willDestroyIsolate() | 549 void WorkerScript::willDestroyIsolate() |
| 550 { | 550 { |
| 551 ASSERT(isCurrentThread()); | 551 ASSERT(isCurrentThread()); |
| 552 ASSERT(m_isolate); | 552 ASSERT(m_isolate); |
| 553 V8PerIsolateData::willBeDestroyed(m_isolate); | 553 V8PerIsolateData::willBeDestroyed(m_isolate); |
| 554 ThreadState::current()->removeInterruptor(m_interruptor.get()); | 554 ThreadState::current()->removeInterruptor(m_interruptor.get()); |
| 555 } | 555 } |
| 556 | 556 |
| 557 void WorkerThread::destroyIsolate() | 557 void WorkerScript::destroyIsolate() |
| 558 { | 558 { |
| 559 ASSERT(isCurrentThread()); | 559 ASSERT(isCurrentThread()); |
| 560 V8PerIsolateData::destroy(m_isolate); | 560 V8PerIsolateData::destroy(m_isolate); |
| 561 m_isolate = nullptr; | 561 m_isolate = nullptr; |
| 562 } | 562 } |
| 563 | 563 |
| 564 void WorkerThread::terminateV8Execution() | 564 void WorkerScript::terminateV8Execution() |
| 565 { | 565 { |
| 566 ASSERT(isMainThread()); | 566 ASSERT(isMainThread()); |
| 567 m_workerGlobalScope->script()->willScheduleExecutionTermination(); | 567 m_workerGlobalScope->scriptController()->willScheduleExecutionTermination(); |
| 568 v8::V8::TerminateExecution(m_isolate); | 568 v8::V8::TerminateExecution(m_isolate); |
| 569 } | 569 } |
| 570 | 570 |
| 571 void WorkerThread::postDebuggerTask(const WebTraceLocation& location, PassOwnPtr
<ExecutionContextTask> task) | 571 void WorkerScript::postDebuggerTask(const WebTraceLocation& location, PassOwnPtr
<ExecutionContextTask> task) |
| 572 { | 572 { |
| 573 m_debuggerMessageQueue.append(WorkerThreadTask::create(*this, task, false)); | 573 m_debuggerMessageQueue.append(WorkerScriptTask::create(*this, task, false)); |
| 574 postTask(location, RunDebuggerQueueTask::create(this)); | 574 postTask(location, RunDebuggerQueueTask::create(this)); |
| 575 } | 575 } |
| 576 | 576 |
| 577 MessageQueueWaitResult WorkerThread::runDebuggerTask(WaitMode waitMode) | 577 MessageQueueWaitResult WorkerScript::runDebuggerTask(WaitMode waitMode) |
| 578 { | 578 { |
| 579 ASSERT(isCurrentThread()); | 579 ASSERT(isCurrentThread()); |
| 580 MessageQueueWaitResult result; | 580 MessageQueueWaitResult result; |
| 581 double absoluteTime = MessageQueue<WebThread::Task>::infiniteTime(); | 581 double absoluteTime = MessageQueue<WebThread::Task>::infiniteTime(); |
| 582 OwnPtr<WebThread::Task> task; | 582 OwnPtr<WebThread::Task> task; |
| 583 { | 583 { |
| 584 if (waitMode == DontWaitForMessage) | 584 if (waitMode == DontWaitForMessage) |
| 585 absoluteTime = 0.0; | 585 absoluteTime = 0.0; |
| 586 SafePointScope safePointScope(ThreadState::NoHeapPointersOnStack); | 586 SafePointScope safePointScope(ThreadState::NoHeapPointersOnStack); |
| 587 task = m_debuggerMessageQueue.waitForMessageWithTimeout(result, absolute
Time); | 587 task = m_debuggerMessageQueue.waitForMessageWithTimeout(result, absolute
Time); |
| 588 } | 588 } |
| 589 | 589 |
| 590 if (result == MessageQueueMessageReceived) { | 590 if (result == MessageQueueMessageReceived) { |
| 591 InspectorInstrumentation::willProcessTask(workerGlobalScope()); | 591 InspectorInstrumentation::willProcessTask(workerGlobalScope()); |
| 592 task->run(); | 592 task->run(); |
| 593 InspectorInstrumentation::didProcessTask(workerGlobalScope()); | 593 InspectorInstrumentation::didProcessTask(workerGlobalScope()); |
| 594 } | 594 } |
| 595 | 595 |
| 596 return result; | 596 return result; |
| 597 } | 597 } |
| 598 | 598 |
| 599 void WorkerThread::willEnterNestedLoop() | 599 void WorkerScript::willEnterNestedLoop() |
| 600 { | 600 { |
| 601 InspectorInstrumentation::willEnterNestedRunLoop(m_workerGlobalScope.get()); | 601 InspectorInstrumentation::willEnterNestedRunLoop(m_workerGlobalScope.get()); |
| 602 } | 602 } |
| 603 | 603 |
| 604 void WorkerThread::didLeaveNestedLoop() | 604 void WorkerScript::didLeaveNestedLoop() |
| 605 { | 605 { |
| 606 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); | 606 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); |
| 607 } | 607 } |
| 608 | 608 |
| 609 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke
rInspectorController) | 609 void WorkerScript::setWorkerInspectorController(WorkerInspectorController* worke
rInspectorController) |
| 610 { | 610 { |
| 611 MutexLocker locker(m_workerInspectorControllerMutex); | 611 MutexLocker locker(m_workerInspectorControllerMutex); |
| 612 m_workerInspectorController = workerInspectorController; | 612 m_workerInspectorController = workerInspectorController; |
| 613 } | 613 } |
| 614 | 614 |
| 615 } // namespace blink | 615 } // namespace blink |
| OLD | NEW |