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 |