Chromium Code Reviews| 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 17 matching lines...) Expand all Loading... | |
| 28 | 28 |
| 29 #include "bindings/core/v8/Microtask.h" | 29 #include "bindings/core/v8/Microtask.h" |
| 30 #include "bindings/core/v8/ScriptSourceCode.h" | 30 #include "bindings/core/v8/ScriptSourceCode.h" |
| 31 #include "bindings/core/v8/V8GCController.h" | 31 #include "bindings/core/v8/V8GCController.h" |
| 32 #include "bindings/core/v8/V8IdleTaskRunner.h" | 32 #include "bindings/core/v8/V8IdleTaskRunner.h" |
| 33 #include "bindings/core/v8/V8Initializer.h" | 33 #include "bindings/core/v8/V8Initializer.h" |
| 34 #include "core/inspector/InspectorInstrumentation.h" | 34 #include "core/inspector/InspectorInstrumentation.h" |
| 35 #include "core/inspector/InspectorTaskRunner.h" | 35 #include "core/inspector/InspectorTaskRunner.h" |
| 36 #include "core/inspector/WorkerThreadDebugger.h" | 36 #include "core/inspector/WorkerThreadDebugger.h" |
| 37 #include "core/workers/DedicatedWorkerGlobalScope.h" | 37 #include "core/workers/DedicatedWorkerGlobalScope.h" |
| 38 #include "core/workers/WorkerBackingThread.h" | |
| 38 #include "core/workers/WorkerClients.h" | 39 #include "core/workers/WorkerClients.h" |
| 39 #include "core/workers/WorkerReportingProxy.h" | 40 #include "core/workers/WorkerReportingProxy.h" |
| 40 #include "core/workers/WorkerThreadStartupData.h" | 41 #include "core/workers/WorkerThreadStartupData.h" |
| 41 #include "platform/ThreadSafeFunctional.h" | 42 #include "platform/ThreadSafeFunctional.h" |
| 42 #include "platform/WaitableEvent.h" | 43 #include "platform/WaitableEvent.h" |
| 43 #include "platform/heap/SafePoint.h" | 44 #include "platform/heap/SafePoint.h" |
| 44 #include "platform/heap/ThreadState.h" | 45 #include "platform/heap/ThreadState.h" |
| 45 #include "platform/weborigin/KURL.h" | 46 #include "platform/weborigin/KURL.h" |
| 46 #include "public/platform/Platform.h" | |
| 47 #include "public/platform/WebScheduler.h" | 47 #include "public/platform/WebScheduler.h" |
| 48 #include "public/platform/WebThread.h" | 48 #include "public/platform/WebThread.h" |
| 49 #include "wtf/Functional.h" | 49 #include "wtf/Functional.h" |
| 50 #include "wtf/Noncopyable.h" | 50 #include "wtf/Noncopyable.h" |
| 51 #include "wtf/WeakPtr.h" | 51 #include "wtf/WeakPtr.h" |
| 52 #include "wtf/text/WTFString.h" | 52 #include "wtf/text/WTFString.h" |
| 53 #include <limits.h> | 53 #include <limits.h> |
| 54 | 54 |
| 55 namespace blink { | 55 namespace blink { |
| 56 | 56 |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 139 : m_started(false) | 139 : m_started(false) |
| 140 , m_terminated(false) | 140 , m_terminated(false) |
| 141 , m_shutdown(false) | 141 , m_shutdown(false) |
| 142 , m_pausedInDebugger(false) | 142 , m_pausedInDebugger(false) |
| 143 , m_runningDebuggerTask(false) | 143 , m_runningDebuggerTask(false) |
| 144 , m_shouldTerminateV8Execution(false) | 144 , m_shouldTerminateV8Execution(false) |
| 145 , m_inspectorTaskRunner(adoptPtr(new InspectorTaskRunner())) | 145 , m_inspectorTaskRunner(adoptPtr(new InspectorTaskRunner())) |
| 146 , m_workerLoaderProxy(workerLoaderProxy) | 146 , m_workerLoaderProxy(workerLoaderProxy) |
| 147 , m_workerReportingProxy(workerReportingProxy) | 147 , m_workerReportingProxy(workerReportingProxy) |
| 148 , m_webScheduler(nullptr) | 148 , m_webScheduler(nullptr) |
| 149 , m_isolate(nullptr) | |
| 150 , m_shutdownEvent(adoptPtr(new WaitableEvent( | 149 , m_shutdownEvent(adoptPtr(new WaitableEvent( |
| 151 WaitableEvent::ResetPolicy::Manual, | 150 WaitableEvent::ResetPolicy::Manual, |
| 152 WaitableEvent::InitialState::NonSignaled))) | 151 WaitableEvent::InitialState::NonSignaled))) |
| 153 , m_terminationEvent(adoptPtr(new WaitableEvent( | 152 , m_terminationEvent(adoptPtr(new WaitableEvent( |
| 154 WaitableEvent::ResetPolicy::Manual, | 153 WaitableEvent::ResetPolicy::Manual, |
| 155 WaitableEvent::InitialState::NonSignaled))) | 154 WaitableEvent::InitialState::NonSignaled))) |
| 156 { | 155 { |
| 157 MutexLocker lock(threadSetMutex()); | 156 MutexLocker lock(threadSetMutex()); |
| 158 workerThreads().add(this); | 157 workerThreads().add(this); |
| 159 } | 158 } |
| 160 | 159 |
| 161 WorkerThread::~WorkerThread() | 160 WorkerThread::~WorkerThread() |
| 162 { | 161 { |
| 163 MutexLocker lock(threadSetMutex()); | 162 MutexLocker lock(threadSetMutex()); |
| 164 ASSERT(workerThreads().contains(this)); | 163 ASSERT(workerThreads().contains(this)); |
| 165 workerThreads().remove(this); | 164 workerThreads().remove(this); |
| 166 } | 165 } |
| 167 | 166 |
| 168 void WorkerThread::start(PassOwnPtr<WorkerThreadStartupData> startupData) | 167 void WorkerThread::start(PassOwnPtr<WorkerThreadStartupData> startupData) |
| 169 { | 168 { |
| 170 ASSERT(isMainThread()); | 169 ASSERT(isMainThread()); |
| 171 | 170 |
| 172 if (m_started) | 171 if (m_started) |
| 173 return; | 172 return; |
| 174 | 173 |
| 175 m_started = true; | 174 m_started = true; |
| 176 backingThread().postTask(BLINK_FROM_HERE, threadSafeBind(&WorkerThread::init ialize, AllowCrossThreadAccess(this), startupData)); | 175 workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBi nd(&WorkerThread::initialize, AllowCrossThreadAccess(this), startupData)); |
| 177 } | 176 } |
| 178 | 177 |
| 179 PlatformThreadId WorkerThread::platformThreadId() | 178 PlatformThreadId WorkerThread::platformThreadId() |
| 180 { | 179 { |
| 181 if (!m_started) | 180 if (!m_started) |
| 182 return 0; | 181 return 0; |
| 183 return backingThread().platformThread().threadId(); | 182 return workerBackingThread().backingThread().platformThread().threadId(); |
| 184 } | 183 } |
| 185 | 184 |
| 186 void WorkerThread::initialize(PassOwnPtr<WorkerThreadStartupData> startupData) | 185 void WorkerThread::initialize(PassOwnPtr<WorkerThreadStartupData> startupData) |
| 187 { | 186 { |
| 188 KURL scriptURL = startupData->m_scriptURL; | 187 KURL scriptURL = startupData->m_scriptURL; |
| 189 String sourceCode = startupData->m_sourceCode; | 188 String sourceCode = startupData->m_sourceCode; |
| 190 WorkerThreadStartMode startMode = startupData->m_startMode; | 189 WorkerThreadStartMode startMode = startupData->m_startMode; |
| 191 OwnPtr<Vector<char>> cachedMetaData = startupData->m_cachedMetaData.release( ); | 190 OwnPtr<Vector<char>> cachedMetaData = startupData->m_cachedMetaData.release( ); |
| 192 V8CacheOptions v8CacheOptions = startupData->m_v8CacheOptions; | 191 V8CacheOptions v8CacheOptions = startupData->m_v8CacheOptions; |
| 193 m_webScheduler = backingThread().platformThread().scheduler(); | 192 m_webScheduler = workerBackingThread().backingThread().platformThread().sche duler(); |
| 194 | 193 |
| 195 { | 194 { |
| 196 MutexLocker lock(m_threadStateMutex); | 195 MutexLocker lock(m_threadStateMutex); |
| 197 | 196 |
| 198 // The worker was terminated before the thread had a chance to run. | 197 // The worker was terminated before the thread had a chance to run. |
| 199 if (m_terminated) { | 198 if (m_terminated) { |
| 200 // Notify the proxy that the WorkerGlobalScope has been disposed of. | 199 // Notify the proxy that the WorkerGlobalScope has been disposed of. |
| 201 // This can free this thread object, hence it must not be touched af terwards. | 200 // This can free this thread object, hence it must not be touched af terwards. |
| 202 m_workerReportingProxy.workerThreadTerminated(); | 201 m_workerReportingProxy.workerThreadTerminated(); |
| 203 // Notify the main thread that it is safe to deallocate our resource s. | 202 // Notify the main thread that it is safe to deallocate our resource s. |
| 204 m_terminationEvent->signal(); | 203 m_terminationEvent->signal(); |
| 205 return; | 204 return; |
| 206 } | 205 } |
| 207 | 206 |
| 207 workerBackingThread().attach(); | |
| 208 | |
| 209 if (shouldAttachThreadDebugger()) | |
| 210 V8PerIsolateData::from(isolate())->setThreadDebugger(adoptPtr(new Wo rkerThreadDebugger(this, isolate()))); | |
|
haraken
2016/04/06 09:23:17
It would be better to call this in WorkerBackingTh
dgozman
2016/04/06 16:50:17
I agree. We'd better pass shouldAttachDebugger to
yhirano
2016/04/07 08:12:40
I don't think so. WorkerThreadDebugger interacts w
| |
| 208 m_microtaskRunner = adoptPtr(new WorkerMicrotaskRunner(this)); | 211 m_microtaskRunner = adoptPtr(new WorkerMicrotaskRunner(this)); |
| 209 initializeBackingThread(); | 212 workerBackingThread().backingThread().addTaskObserver(m_microtaskRunner. get()); |
| 210 backingThread().addTaskObserver(m_microtaskRunner.get()); | |
| 211 | 213 |
| 212 m_isolate = initializeIsolate(); | |
| 213 // Optimize for memory usage instead of latency for the worker isolate. | 214 // Optimize for memory usage instead of latency for the worker isolate. |
| 214 m_isolate->IsolateInBackgroundNotification(); | 215 isolate()->IsolateInBackgroundNotification(); |
| 215 m_workerGlobalScope = createWorkerGlobalScope(startupData); | 216 m_workerGlobalScope = createWorkerGlobalScope(startupData); |
| 216 m_workerGlobalScope->scriptLoaded(sourceCode.length(), cachedMetaData.ge t() ? cachedMetaData->size() : 0); | 217 m_workerGlobalScope->scriptLoaded(sourceCode.length(), cachedMetaData.ge t() ? cachedMetaData->size() : 0); |
| 217 | 218 |
| 218 didStartWorkerThread(); | |
| 219 | |
| 220 // Notify proxy that a new WorkerGlobalScope has been created and starte d. | 219 // Notify proxy that a new WorkerGlobalScope has been created and starte d. |
| 221 m_workerReportingProxy.workerGlobalScopeStarted(m_workerGlobalScope.get( )); | 220 m_workerReportingProxy.workerGlobalScopeStarted(m_workerGlobalScope.get( )); |
| 222 | 221 |
| 223 WorkerOrWorkletScriptController* scriptController = m_workerGlobalScope- >scriptController(); | 222 WorkerOrWorkletScriptController* scriptController = m_workerGlobalScope- >scriptController(); |
| 224 if (!scriptController->isExecutionForbidden()) | 223 if (!scriptController->isExecutionForbidden()) |
| 225 scriptController->initializeContextIfNeeded(); | 224 scriptController->initializeContextIfNeeded(); |
| 226 } | 225 } |
| 227 | 226 |
| 228 if (startMode == PauseWorkerGlobalScopeOnStart) | 227 if (startMode == PauseWorkerGlobalScopeOnStart) |
| 229 startRunningDebuggerTasksOnPause(); | 228 startRunningDebuggerTasksOnPause(); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 248 if (m_shutdown) | 247 if (m_shutdown) |
| 249 return; | 248 return; |
| 250 m_shutdown = true; | 249 m_shutdown = true; |
| 251 } | 250 } |
| 252 | 251 |
| 253 // This should be called before we start the shutdown procedure. | 252 // This should be called before we start the shutdown procedure. |
| 254 workerReportingProxy().willDestroyWorkerGlobalScope(); | 253 workerReportingProxy().willDestroyWorkerGlobalScope(); |
| 255 | 254 |
| 256 workerGlobalScope()->dispose(); | 255 workerGlobalScope()->dispose(); |
| 257 | 256 |
| 258 // This should be called after the WorkerGlobalScope's disposed (which may | 257 workerBackingThread().backingThread().removeTaskObserver(m_microtaskRunner.g et()); |
| 259 // trigger some last-minutes cleanups) and before the thread actually stops. | |
| 260 willStopWorkerThread(); | |
| 261 | |
| 262 backingThread().removeTaskObserver(m_microtaskRunner.get()); | |
| 263 postTask(BLINK_FROM_HERE, createSameThreadTask(&WorkerThread::performShutdow nTask, this)); | 258 postTask(BLINK_FROM_HERE, createSameThreadTask(&WorkerThread::performShutdow nTask, this)); |
| 264 } | 259 } |
| 265 | 260 |
| 266 void WorkerThread::performShutdownTask() | 261 void WorkerThread::performShutdownTask() |
| 267 { | 262 { |
| 268 // The below assignment will destroy the context, which will in turn notify messaging proxy. | 263 // The below assignment will destroy the context, which will in turn notify messaging proxy. |
| 269 // We cannot let any objects survive past thread exit, because no other thre ad will run GC or otherwise destroy them. | 264 // We cannot let any objects survive past thread exit, because no other thre ad will run GC or otherwise destroy them. |
| 270 // If Oilpan is enabled, we detach of the context/global scope, with the fin al heap cleanup below sweeping it out. | 265 // If Oilpan is enabled, we detach of the context/global scope, with the fin al heap cleanup below sweeping it out. |
| 271 m_workerGlobalScope->notifyContextDestroyed(); | 266 m_workerGlobalScope->notifyContextDestroyed(); |
| 272 #if !ENABLE(OILPAN) | 267 #if !ENABLE(OILPAN) |
| 273 ASSERT(m_workerGlobalScope->hasOneRef()); | 268 ASSERT(m_workerGlobalScope->hasOneRef()); |
| 274 #endif | 269 #endif |
| 275 m_workerGlobalScope = nullptr; | 270 m_workerGlobalScope = nullptr; |
| 276 | 271 |
| 277 willDestroyIsolate(); | 272 workerBackingThread().detach(); |
| 278 shutdownBackingThread(); | 273 // We must not touch workerBackingThread() from now on. |
| 279 destroyIsolate(); | |
| 280 m_isolate = nullptr; | |
| 281 | 274 |
| 282 m_microtaskRunner = nullptr; | 275 m_microtaskRunner = nullptr; |
| 283 | 276 |
| 284 // Notify the proxy that the WorkerGlobalScope has been disposed of. | 277 // Notify the proxy that the WorkerGlobalScope has been disposed of. |
| 285 // This can free this thread object, hence it must not be touched afterwards . | 278 // This can free this thread object, hence it must not be touched afterwards . |
| 286 workerReportingProxy().workerThreadTerminated(); | 279 workerReportingProxy().workerThreadTerminated(); |
| 287 | 280 |
| 288 m_terminationEvent->signal(); | 281 m_terminationEvent->signal(); |
| 289 } | 282 } |
| 290 | 283 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 335 | 328 |
| 336 // If the worker thread was never initialized, don't start another | 329 // If the worker thread was never initialized, don't start another |
| 337 // shutdown, but still wait for the thread to signal when termination has | 330 // shutdown, but still wait for the thread to signal when termination has |
| 338 // completed. | 331 // completed. |
| 339 if (!m_workerGlobalScope) | 332 if (!m_workerGlobalScope) |
| 340 return; | 333 return; |
| 341 | 334 |
| 342 // 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. | 335 // 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. |
| 343 m_workerGlobalScope->scriptController()->willScheduleExecutionTermination(); | 336 m_workerGlobalScope->scriptController()->willScheduleExecutionTermination(); |
| 344 | 337 |
| 345 // Terminating during debugger task may lead to crash due to heavy use of v8 api in debugger. | 338 if (workerBackingThread().workerScriptCount() == 1) { |
|
haraken
2016/04/06 09:23:17
Hmm, it looks a bit weird to expose the concept of
yhirano
2016/04/07 08:12:40
I agree. I expect that the "graceful shutdown" wil
| |
| 346 // Any debugger task is guaranteed to finish, so we can postpone termination after task has finished. | 339 // This condition is not entirely correct because other scripts |
|
haraken
2016/04/06 09:23:17
scripts => worker threads ?
yhirano
2016/04/07 08:12:40
Ditto: I think it should not be called as "worker
| |
| 347 // Note: m_runningDebuggerTask and m_shouldTerminateV8Execution access must be guarded by the lock. | 340 // can be being initialized or terminated simuletaneously. Though this |
| 348 if (m_runningDebuggerTask) | 341 // function itself is protected by a mutex, it is possible that |
| 349 m_shouldTerminateV8Execution = true; | 342 // |workerScriptCount()| here is not consistent with that in |
| 350 else | 343 // |initialize| and |shutdown|. |
| 351 terminateV8Execution(); | 344 // TODO(yhirano): TerminateExecution should be called more carefully. |
| 345 // https://crbug.com/413518 | |
| 346 if (m_runningDebuggerTask) { | |
| 347 // Terminating during debugger task may lead to crash due to heavy | |
| 348 // use of v8 api in debugger. Any debugger task is guaranteed to | |
| 349 // finish, so we can postpone termination after task has finished. | |
| 350 // Note: m_runningDebuggerTask and m_shouldTerminateV8Execution | |
| 351 // access must be guarded by the lock. | |
| 352 m_shouldTerminateV8Execution = true; | |
| 353 } else { | |
| 354 isolate()->TerminateExecution(); | |
| 355 } | |
| 356 } | |
| 352 | 357 |
| 353 InspectorInstrumentation::didKillAllExecutionContextTasks(m_workerGlobalScop e.get()); | 358 InspectorInstrumentation::didKillAllExecutionContextTasks(m_workerGlobalScop e.get()); |
| 354 m_inspectorTaskRunner->kill(); | 359 m_inspectorTaskRunner->kill(); |
| 355 backingThread().postTask(BLINK_FROM_HERE, threadSafeBind(&WorkerThread::shut down, AllowCrossThreadAccess(this))); | 360 workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBi nd(&WorkerThread::shutdown, AllowCrossThreadAccess(this))); |
| 356 } | 361 } |
| 357 | 362 |
| 358 void WorkerThread::didStartWorkerThread() | 363 v8::Isolate* WorkerThread::isolate() |
| 359 { | 364 { |
| 360 ASSERT(isCurrentThread()); | 365 return workerBackingThread().isolate(); |
| 361 Platform::current()->didStartWorkerThread(); | |
| 362 } | |
| 363 | |
| 364 void WorkerThread::willStopWorkerThread() | |
| 365 { | |
| 366 ASSERT(isCurrentThread()); | |
| 367 Platform::current()->willStopWorkerThread(); | |
| 368 } | 366 } |
| 369 | 367 |
| 370 void WorkerThread::terminateAndWaitForAllWorkers() | 368 void WorkerThread::terminateAndWaitForAllWorkers() |
| 371 { | 369 { |
| 372 // Keep this lock to prevent WorkerThread instances from being destroyed. | 370 // Keep this lock to prevent WorkerThread instances from being destroyed. |
| 373 MutexLocker lock(threadSetMutex()); | 371 MutexLocker lock(threadSetMutex()); |
| 374 HashSet<WorkerThread*> threads = workerThreads(); | 372 HashSet<WorkerThread*> threads = workerThreads(); |
| 375 for (WorkerThread* thread : threads) | 373 for (WorkerThread* thread : threads) |
| 376 thread->terminateInternal(); | 374 thread->terminateInternal(); |
| 377 | 375 |
| 378 for (WorkerThread* thread : threads) | 376 for (WorkerThread* thread : threads) |
| 379 thread->m_terminationEvent->wait(); | 377 thread->m_terminationEvent->wait(); |
| 380 } | 378 } |
| 381 | 379 |
| 382 bool WorkerThread::isCurrentThread() | 380 bool WorkerThread::isCurrentThread() |
| 383 { | 381 { |
| 384 return m_started && backingThread().isCurrentThread(); | 382 return m_started && workerBackingThread().backingThread().isCurrentThread(); |
| 385 } | 383 } |
| 386 | 384 |
| 387 void WorkerThread::postTask(const WebTraceLocation& location, PassOwnPtr<Executi onContextTask> task) | 385 void WorkerThread::postTask(const WebTraceLocation& location, PassOwnPtr<Executi onContextTask> task) |
| 388 { | 386 { |
| 389 backingThread().postTask(location, createWorkerThreadTask(task, true)); | 387 workerBackingThread().backingThread().postTask(location, createWorkerThreadT ask(task, true)); |
| 390 } | |
| 391 | |
| 392 void WorkerThread::initializeBackingThread() | |
| 393 { | |
| 394 ASSERT(isCurrentThread()); | |
| 395 backingThread().initialize(); | |
| 396 } | |
| 397 | |
| 398 void WorkerThread::shutdownBackingThread() | |
| 399 { | |
| 400 ASSERT(isCurrentThread()); | |
| 401 backingThread().shutdown(); | |
| 402 } | |
| 403 | |
| 404 v8::Isolate* WorkerThread::initializeIsolate() | |
| 405 { | |
| 406 ASSERT(isCurrentThread()); | |
| 407 ASSERT(!m_isolate); | |
| 408 v8::Isolate* isolate = V8PerIsolateData::initialize(); | |
| 409 V8Initializer::initializeWorker(isolate); | |
| 410 | |
| 411 OwnPtr<V8IsolateInterruptor> interruptor = adoptPtr(new V8IsolateInterruptor (isolate)); | |
| 412 ThreadState::current()->addInterruptor(interruptor.release()); | |
| 413 ThreadState::current()->registerTraceDOMWrappers(isolate, V8GCController::tr aceDOMWrappers); | |
| 414 if (RuntimeEnabledFeatures::v8IdleTasksEnabled()) | |
| 415 V8PerIsolateData::enableIdleTasks(isolate, adoptPtr(new V8IdleTaskRunner (m_webScheduler))); | |
| 416 V8PerIsolateData::from(isolate)->setThreadDebugger(adoptPtr(new WorkerThread Debugger(this, isolate))); | |
| 417 return isolate; | |
| 418 } | |
| 419 | |
| 420 void WorkerThread::willDestroyIsolate() | |
| 421 { | |
| 422 ASSERT(isCurrentThread()); | |
| 423 ASSERT(m_isolate); | |
| 424 V8PerIsolateData::willBeDestroyed(m_isolate); | |
| 425 } | |
| 426 | |
| 427 void WorkerThread::destroyIsolate() | |
| 428 { | |
| 429 ASSERT(isCurrentThread()); | |
| 430 V8PerIsolateData::destroy(m_isolate); | |
| 431 } | |
| 432 | |
| 433 void WorkerThread::terminateV8Execution() | |
| 434 { | |
| 435 m_isolate->TerminateExecution(); | |
| 436 } | 388 } |
| 437 | 389 |
| 438 void WorkerThread::runDebuggerTaskDontWait() | 390 void WorkerThread::runDebuggerTaskDontWait() |
| 439 { | 391 { |
| 440 OwnPtr<CrossThreadClosure> task = m_inspectorTaskRunner->takeNextTask(Inspec torTaskRunner::DontWaitForTask); | 392 OwnPtr<CrossThreadClosure> task = m_inspectorTaskRunner->takeNextTask(Inspec torTaskRunner::DontWaitForTask); |
| 441 if (task) | 393 if (task) |
| 442 (*task)(); | 394 (*task)(); |
| 443 } | 395 } |
| 444 | 396 |
| 445 void WorkerThread::appendDebuggerTask(PassOwnPtr<CrossThreadClosure> task) | 397 void WorkerThread::appendDebuggerTask(PassOwnPtr<CrossThreadClosure> task) |
| 446 { | 398 { |
| 447 { | 399 { |
| 448 MutexLocker lock(m_threadStateMutex); | 400 MutexLocker lock(m_threadStateMutex); |
| 449 if (m_shutdown) | 401 if (m_shutdown) |
| 450 return; | 402 return; |
| 451 } | 403 } |
| 452 m_inspectorTaskRunner->appendTask(threadSafeBind(&WorkerThread::runDebuggerT ask, AllowCrossThreadAccess(this), task)); | 404 m_inspectorTaskRunner->appendTask(threadSafeBind(&WorkerThread::runDebuggerT ask, AllowCrossThreadAccess(this), task)); |
| 453 { | 405 { |
| 454 MutexLocker lock(m_threadStateMutex); | 406 MutexLocker lock(m_threadStateMutex); |
| 455 if (m_isolate) | 407 if (isolate()) |
|
haraken
2016/04/06 09:23:17
Nit: I don't think we need this check.
yhirano
2016/04/07 08:12:40
It's needed. Though I don't understand the mechani
| |
| 456 m_inspectorTaskRunner->interruptAndRunAllTasksDontWait(m_isolate); | 408 m_inspectorTaskRunner->interruptAndRunAllTasksDontWait(isolate()); |
| 457 } | 409 } |
| 458 backingThread().postTask(BLINK_FROM_HERE, threadSafeBind(&WorkerThread::runD ebuggerTaskDontWait, AllowCrossThreadAccess(this))); | 410 workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBi nd(&WorkerThread::runDebuggerTaskDontWait, AllowCrossThreadAccess(this))); |
| 459 } | 411 } |
| 460 | 412 |
| 461 void WorkerThread::runDebuggerTask(PassOwnPtr<CrossThreadClosure> task) | 413 void WorkerThread::runDebuggerTask(PassOwnPtr<CrossThreadClosure> task) |
| 462 { | 414 { |
| 463 ASSERT(isCurrentThread()); | 415 ASSERT(isCurrentThread()); |
| 464 InspectorTaskRunner::IgnoreInterruptsScope scope(m_inspectorTaskRunner.get() ); | 416 InspectorTaskRunner::IgnoreInterruptsScope scope(m_inspectorTaskRunner.get() ); |
| 465 { | 417 { |
| 466 MutexLocker lock(m_threadStateMutex); | 418 MutexLocker lock(m_threadStateMutex); |
| 467 m_runningDebuggerTask = true; | 419 m_runningDebuggerTask = true; |
| 468 } | 420 } |
| 469 InspectorInstrumentation::willProcessTask(workerGlobalScope()); | 421 InspectorInstrumentation::willProcessTask(workerGlobalScope()); |
| 470 (*task)(); | 422 (*task)(); |
| 471 InspectorInstrumentation::didProcessTask(workerGlobalScope()); | 423 InspectorInstrumentation::didProcessTask(workerGlobalScope()); |
| 472 { | 424 { |
| 473 MutexLocker lock(m_threadStateMutex); | 425 MutexLocker lock(m_threadStateMutex); |
| 474 m_runningDebuggerTask = false; | 426 m_runningDebuggerTask = false; |
| 475 if (m_shouldTerminateV8Execution) { | 427 if (m_shouldTerminateV8Execution) { |
| 476 m_shouldTerminateV8Execution = false; | 428 m_shouldTerminateV8Execution = false; |
| 477 terminateV8Execution(); | 429 isolate()->TerminateExecution(); |
| 478 } | 430 } |
| 479 } | 431 } |
| 480 } | 432 } |
| 481 | 433 |
| 482 void WorkerThread::startRunningDebuggerTasksOnPause() | 434 void WorkerThread::startRunningDebuggerTasksOnPause() |
| 483 { | 435 { |
| 484 m_pausedInDebugger = true; | 436 m_pausedInDebugger = true; |
| 485 InspectorInstrumentation::willEnterNestedRunLoop(m_workerGlobalScope.get()); | 437 InspectorInstrumentation::willEnterNestedRunLoop(m_workerGlobalScope.get()); |
| 486 OwnPtr<CrossThreadClosure> task; | 438 OwnPtr<CrossThreadClosure> task; |
| 487 do { | 439 do { |
| 488 { | 440 { |
| 489 SafePointScope safePointScope(BlinkGC::HeapPointersOnStack); | 441 SafePointScope safePointScope(BlinkGC::HeapPointersOnStack); |
| 490 task = m_inspectorTaskRunner->takeNextTask(InspectorTaskRunner::Wait ForTask); | 442 task = m_inspectorTaskRunner->takeNextTask(InspectorTaskRunner::Wait ForTask); |
| 491 } | 443 } |
| 492 if (task) | 444 if (task) |
| 493 (*task)(); | 445 (*task)(); |
| 494 // Keep waiting until execution is resumed. | 446 // Keep waiting until execution is resumed. |
| 495 } while (task && m_pausedInDebugger); | 447 } while (task && m_pausedInDebugger); |
| 496 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); | 448 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); |
| 497 } | 449 } |
| 498 | 450 |
| 499 void WorkerThread::stopRunningDebuggerTasksOnPause() | 451 void WorkerThread::stopRunningDebuggerTasksOnPause() |
| 500 { | 452 { |
| 501 m_pausedInDebugger = false; | 453 m_pausedInDebugger = false; |
| 502 } | 454 } |
| 503 | 455 |
| 504 } // namespace blink | 456 } // namespace blink |
| OLD | NEW |