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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 } | 83 } |
84 | 84 |
85 void run() | 85 void run() |
86 { | 86 { |
87 DCHECK(isMainThread()); | 87 DCHECK(isMainThread()); |
88 MutexLocker lock(m_workerThread->m_threadStateMutex); | 88 MutexLocker lock(m_workerThread->m_threadStateMutex); |
89 if (m_workerThread->m_readyToShutdown) { | 89 if (m_workerThread->m_readyToShutdown) { |
90 // Shutdown sequence is now running. Just return. | 90 // Shutdown sequence is now running. Just return. |
91 return; | 91 return; |
92 } | 92 } |
| 93 if (m_workerThread->m_runningDebuggerTask) { |
| 94 // Any debugger task is guaranteed to finish, so we can wait for the |
| 95 // completion. Shutdown sequence will start after that. |
| 96 return; |
| 97 } |
93 | 98 |
94 m_workerThread->forciblyTerminateExecution(); | 99 m_workerThread->forciblyTerminateExecution(); |
95 DCHECK_EQ(WorkerThread::ExitCode::NotTerminated, m_workerThread->m_exitC
ode); | 100 DCHECK_EQ(WorkerThread::ExitCode::NotTerminated, m_workerThread->m_exitC
ode); |
96 m_workerThread->m_exitCode = WorkerThread::ExitCode::AsyncForciblyTermin
ated; | 101 m_workerThread->m_exitCode = WorkerThread::ExitCode::AsyncForciblyTermin
ated; |
97 } | 102 } |
98 | 103 |
99 WorkerThread* m_workerThread; | 104 WorkerThread* m_workerThread; |
100 OwnPtr<CancellableTaskFactory> m_cancellableTaskFactory; | 105 OwnPtr<CancellableTaskFactory> m_cancellableTaskFactory; |
101 }; | 106 }; |
102 | 107 |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 return workerBackingThread().isolate(); | 213 return workerBackingThread().isolate(); |
209 } | 214 } |
210 | 215 |
211 bool WorkerThread::isCurrentThread() | 216 bool WorkerThread::isCurrentThread() |
212 { | 217 { |
213 return m_started && workerBackingThread().backingThread().isCurrentThread(); | 218 return m_started && workerBackingThread().backingThread().isCurrentThread(); |
214 } | 219 } |
215 | 220 |
216 void WorkerThread::postTask(const WebTraceLocation& location, std::unique_ptr<Ex
ecutionContextTask> task) | 221 void WorkerThread::postTask(const WebTraceLocation& location, std::unique_ptr<Ex
ecutionContextTask> task) |
217 { | 222 { |
| 223 { |
| 224 MutexLocker lock(m_threadStateMutex); |
| 225 if (m_terminated || m_readyToShutdown) |
| 226 return; |
| 227 } |
218 workerBackingThread().backingThread().postTask(location, createWorkerThreadT
ask(std::move(task), true)); | 228 workerBackingThread().backingThread().postTask(location, createWorkerThreadT
ask(std::move(task), true)); |
219 } | 229 } |
220 | 230 |
221 void WorkerThread::appendDebuggerTask(std::unique_ptr<CrossThreadClosure> task) | 231 void WorkerThread::appendDebuggerTask(std::unique_ptr<CrossThreadClosure> task) |
222 { | 232 { |
| 233 DCHECK(isMainThread()); |
223 { | 234 { |
224 MutexLocker lock(m_threadStateMutex); | 235 MutexLocker lock(m_threadStateMutex); |
225 if (m_readyToShutdown) | 236 if (m_terminated) |
226 return; | 237 return; |
227 } | 238 } |
228 m_inspectorTaskRunner->appendTask(threadSafeBind(&WorkerThread::runDebuggerT
askOnWorkerThread, AllowCrossThreadAccess(this), passed(std::move(task)))); | 239 m_inspectorTaskRunner->appendTask(threadSafeBind(&WorkerThread::performDebug
gerTaskOnWorkerThread, AllowCrossThreadAccess(this), passed(std::move(task)))); |
229 { | 240 { |
230 MutexLocker lock(m_threadStateMutex); | 241 MutexLocker lock(m_threadStateMutex); |
231 if (isolate()) | 242 if (isolate() && !m_readyToShutdown) |
232 m_inspectorTaskRunner->interruptAndRunAllTasksDontWait(isolate()); | 243 m_inspectorTaskRunner->interruptAndRunAllTasksDontWait(isolate()); |
233 } | 244 } |
234 workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBi
nd(&WorkerThread::runDebuggerTaskDontWaitOnWorkerThread, AllowCrossThreadAccess(
this))); | 245 workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBi
nd(&WorkerThread::performDebuggerTaskDontWaitOnWorkerThread, AllowCrossThreadAcc
ess(this))); |
235 } | 246 } |
236 | 247 |
237 void WorkerThread::startRunningDebuggerTasksOnPause() | 248 void WorkerThread::startRunningDebuggerTasksOnPauseOnWorkerThread() |
238 { | 249 { |
| 250 DCHECK(isCurrentThread()); |
239 m_pausedInDebugger = true; | 251 m_pausedInDebugger = true; |
240 ThreadDebugger::idleStarted(isolate()); | 252 ThreadDebugger::idleStarted(isolate()); |
241 std::unique_ptr<CrossThreadClosure> task; | 253 std::unique_ptr<CrossThreadClosure> task; |
242 do { | 254 do { |
243 { | 255 { |
244 SafePointScope safePointScope(BlinkGC::HeapPointersOnStack); | 256 SafePointScope safePointScope(BlinkGC::HeapPointersOnStack); |
245 task = m_inspectorTaskRunner->takeNextTask(InspectorTaskRunner::Wait
ForTask); | 257 task = m_inspectorTaskRunner->takeNextTask(InspectorTaskRunner::Wait
ForTask); |
246 } | 258 } |
247 if (task) | 259 if (task) |
248 (*task)(); | 260 (*task)(); |
249 // Keep waiting until execution is resumed. | 261 // Keep waiting until execution is resumed. |
250 } while (task && m_pausedInDebugger); | 262 } while (task && m_pausedInDebugger); |
251 ThreadDebugger::idleFinished(isolate()); | 263 ThreadDebugger::idleFinished(isolate()); |
252 } | 264 } |
253 | 265 |
254 void WorkerThread::stopRunningDebuggerTasksOnPause() | 266 void WorkerThread::stopRunningDebuggerTasksOnPauseOnWorkerThread() |
255 { | 267 { |
| 268 DCHECK(isCurrentThread()); |
256 m_pausedInDebugger = false; | 269 m_pausedInDebugger = false; |
257 } | 270 } |
258 | 271 |
259 WorkerGlobalScope* WorkerThread::workerGlobalScope() | 272 WorkerGlobalScope* WorkerThread::workerGlobalScope() |
260 { | 273 { |
261 DCHECK(isCurrentThread()); | 274 DCHECK(isCurrentThread()); |
262 return m_workerGlobalScope.get(); | 275 return m_workerGlobalScope.get(); |
263 } | 276 } |
264 | 277 |
265 bool WorkerThread::terminated() | 278 bool WorkerThread::terminated() |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
445 ExecutionContext* executionContext = m_workerGlobalScope->getExecuti
onContext(); | 458 ExecutionContext* executionContext = m_workerGlobalScope->getExecuti
onContext(); |
446 if (executionContext) { | 459 if (executionContext) { |
447 OriginTrialContext* originTrialContext = OriginTrialContext::fro
m(executionContext); | 460 OriginTrialContext* originTrialContext = OriginTrialContext::fro
m(executionContext); |
448 if (originTrialContext) | 461 if (originTrialContext) |
449 originTrialContext->initializePendingFeatures(); | 462 originTrialContext->initializePendingFeatures(); |
450 } | 463 } |
451 } | 464 } |
452 } | 465 } |
453 | 466 |
454 if (startMode == PauseWorkerGlobalScopeOnStart) | 467 if (startMode == PauseWorkerGlobalScopeOnStart) |
455 startRunningDebuggerTasksOnPause(); | 468 startRunningDebuggerTasksOnPauseOnWorkerThread(); |
456 | 469 |
457 if (m_workerGlobalScope->scriptController()->isContextInitialized()) { | 470 if (m_workerGlobalScope->scriptController()->isContextInitialized()) { |
458 m_workerReportingProxy.didInitializeWorkerContext(); | 471 m_workerReportingProxy.didInitializeWorkerContext(); |
459 v8::HandleScope handleScope(isolate()); | 472 v8::HandleScope handleScope(isolate()); |
460 Platform::current()->workerContextCreated(m_workerGlobalScope->scriptCon
troller()->context()); | 473 Platform::current()->workerContextCreated(m_workerGlobalScope->scriptCon
troller()->context()); |
461 } | 474 } |
462 | 475 |
463 CachedMetadataHandler* handler = workerGlobalScope()->createWorkerScriptCach
edMetadataHandler(scriptURL, cachedMetaData.get()); | 476 CachedMetadataHandler* handler = workerGlobalScope()->createWorkerScriptCach
edMetadataHandler(scriptURL, cachedMetaData.get()); |
464 bool success = m_workerGlobalScope->scriptController()->evaluate(ScriptSourc
eCode(sourceCode, scriptURL), nullptr, handler, v8CacheOptions); | 477 bool success = m_workerGlobalScope->scriptController()->evaluate(ScriptSourc
eCode(sourceCode, scriptURL), nullptr, handler, v8CacheOptions); |
465 m_workerGlobalScope->didEvaluateWorkerScript(); | 478 m_workerGlobalScope->didEvaluateWorkerScript(); |
466 m_workerReportingProxy.didEvaluateWorkerScript(success); | 479 m_workerReportingProxy.didEvaluateWorkerScript(success); |
467 | 480 |
468 postInitialize(); | 481 postInitialize(); |
469 } | 482 } |
470 | 483 |
471 void WorkerThread::prepareForShutdownOnWorkerThread() | 484 void WorkerThread::prepareForShutdownOnWorkerThread() |
472 { | 485 { |
473 DCHECK(isCurrentThread()); | 486 DCHECK(isCurrentThread()); |
474 { | 487 { |
475 MutexLocker lock(m_threadStateMutex); | 488 MutexLocker lock(m_threadStateMutex); |
476 if (m_readyToShutdown) | 489 if (m_readyToShutdown) |
477 return; | 490 return; |
478 m_readyToShutdown = true; | 491 m_readyToShutdown = true; |
479 if (m_exitCode == ExitCode::NotTerminated) | 492 if (m_exitCode == ExitCode::NotTerminated) |
480 m_exitCode = ExitCode::GracefullyTerminated; | 493 m_exitCode = ExitCode::GracefullyTerminated; |
481 } | 494 } |
482 | 495 |
| 496 m_inspectorTaskRunner->kill(); |
483 workerReportingProxy().willDestroyWorkerGlobalScope(); | 497 workerReportingProxy().willDestroyWorkerGlobalScope(); |
484 InspectorInstrumentation::allAsyncTasksCanceled(workerGlobalScope()); | 498 InspectorInstrumentation::allAsyncTasksCanceled(workerGlobalScope()); |
485 workerGlobalScope()->dispose(); | 499 workerGlobalScope()->dispose(); |
486 workerBackingThread().backingThread().removeTaskObserver(m_microtaskRunner.g
et()); | 500 workerBackingThread().backingThread().removeTaskObserver(m_microtaskRunner.g
et()); |
487 } | 501 } |
488 | 502 |
489 void WorkerThread::performShutdownOnWorkerThread() | 503 void WorkerThread::performShutdownOnWorkerThread() |
490 { | 504 { |
491 DCHECK(isCurrentThread()); | 505 DCHECK(isCurrentThread()); |
492 #if DCHECK_IS_ON | 506 #if DCHECK_IS_ON |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
532 // WorkerThread::Initialize()), we mustn't run any of the posted tasks. | 546 // WorkerThread::Initialize()), we mustn't run any of the posted tasks. |
533 if (!globalScope) { | 547 if (!globalScope) { |
534 DCHECK(terminated()); | 548 DCHECK(terminated()); |
535 return; | 549 return; |
536 } | 550 } |
537 | 551 |
538 InspectorInstrumentation::AsyncTask asyncTask(globalScope, task.get(), isIns
trumented); | 552 InspectorInstrumentation::AsyncTask asyncTask(globalScope, task.get(), isIns
trumented); |
539 task->performTask(globalScope); | 553 task->performTask(globalScope); |
540 } | 554 } |
541 | 555 |
542 void WorkerThread::runDebuggerTaskOnWorkerThread(std::unique_ptr<CrossThreadClos
ure> task) | 556 void WorkerThread::performDebuggerTaskOnWorkerThread(std::unique_ptr<CrossThread
Closure> task) |
543 { | 557 { |
544 DCHECK(isCurrentThread()); | 558 DCHECK(isCurrentThread()); |
545 InspectorTaskRunner::IgnoreInterruptsScope scope(m_inspectorTaskRunner.get()
); | 559 InspectorTaskRunner::IgnoreInterruptsScope scope(m_inspectorTaskRunner.get()
); |
546 { | 560 { |
547 MutexLocker lock(m_threadStateMutex); | 561 MutexLocker lock(m_threadStateMutex); |
| 562 DCHECK(!m_readyToShutdown); |
548 m_runningDebuggerTask = true; | 563 m_runningDebuggerTask = true; |
549 } | 564 } |
550 ThreadDebugger::idleFinished(isolate()); | 565 ThreadDebugger::idleFinished(isolate()); |
551 (*task)(); | 566 (*task)(); |
552 ThreadDebugger::idleStarted(isolate()); | 567 ThreadDebugger::idleStarted(isolate()); |
553 { | 568 { |
554 MutexLocker lock(m_threadStateMutex); | 569 MutexLocker lock(m_threadStateMutex); |
555 m_runningDebuggerTask = false; | 570 m_runningDebuggerTask = false; |
556 | 571 |
557 if (!m_terminated) | 572 if (!m_terminated) |
558 return; | 573 return; |
559 // terminate() was called. Shutdown sequence will start soon. | 574 // terminate() was called. Shutdown sequence will start soon. |
560 } | 575 } |
561 // Stop further worker tasks to run after this point. | 576 // Stop further worker tasks to run after this point. |
562 prepareForShutdownOnWorkerThread(); | 577 prepareForShutdownOnWorkerThread(); |
563 } | 578 } |
564 | 579 |
565 void WorkerThread::runDebuggerTaskDontWaitOnWorkerThread() | 580 void WorkerThread::performDebuggerTaskDontWaitOnWorkerThread() |
566 { | 581 { |
567 DCHECK(isCurrentThread()); | 582 DCHECK(isCurrentThread()); |
568 std::unique_ptr<CrossThreadClosure> task = m_inspectorTaskRunner->takeNextTa
sk(InspectorTaskRunner::DontWaitForTask); | 583 std::unique_ptr<CrossThreadClosure> task = m_inspectorTaskRunner->takeNextTa
sk(InspectorTaskRunner::DontWaitForTask); |
569 if (task) | 584 if (task) |
570 (*task)(); | 585 (*task)(); |
571 } | 586 } |
572 | 587 |
573 WorkerThread::ExitCode WorkerThread::getExitCode() | 588 WorkerThread::ExitCode WorkerThread::getExitCode() |
574 { | 589 { |
575 MutexLocker lock(m_threadStateMutex); | 590 MutexLocker lock(m_threadStateMutex); |
576 return m_exitCode; | 591 return m_exitCode; |
577 } | 592 } |
578 | 593 |
579 } // namespace blink | 594 } // namespace blink |
OLD | NEW |