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