Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: third_party/WebKit/Source/core/workers/WorkerThread.cpp

Issue 2015453002: Worker: Reorder function definitions of WorkerThread (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix typo Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/core/workers/WorkerThread.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 Microtask::performCheckpoint(m_workerThread->isolate()); 69 Microtask::performCheckpoint(m_workerThread->isolate());
70 if (WorkerGlobalScope* globalScope = m_workerThread->workerGlobalScope() ) { 70 if (WorkerGlobalScope* globalScope = m_workerThread->workerGlobalScope() ) {
71 if (WorkerOrWorkletScriptController* scriptController = globalScope- >scriptController()) 71 if (WorkerOrWorkletScriptController* scriptController = globalScope- >scriptController())
72 scriptController->getRejectedPromises()->processQueue(); 72 scriptController->getRejectedPromises()->processQueue();
73 if (globalScope->isClosing()) { 73 if (globalScope->isClosing()) {
74 // |m_workerThread| will eventually be requested to terminate. 74 // |m_workerThread| will eventually be requested to terminate.
75 m_workerThread->workerReportingProxy().workerGlobalScopeClosed() ; 75 m_workerThread->workerReportingProxy().workerGlobalScopeClosed() ;
76 76
77 // Dispose WorkerGlobalScope to stop associated ActiveDOMObjects 77 // Dispose WorkerGlobalScope to stop associated ActiveDOMObjects
78 // and close the event queue. 78 // and close the event queue.
79 m_workerThread->prepareForShutdown(); 79 m_workerThread->prepareForShutdownOnWorkerThread();
80 } 80 }
81 } 81 }
82 } 82 }
83 83
84 private: 84 private:
85 // Thread owns the microtask runner; reference remains 85 // Thread owns the microtask runner; reference remains
86 // valid for the lifetime of this object. 86 // valid for the lifetime of this object.
87 WorkerThread* m_workerThread; 87 WorkerThread* m_workerThread;
88 }; 88 };
89 89
90 static Mutex& threadSetMutex() 90 static Mutex& threadSetMutex()
91 { 91 {
92 DEFINE_THREAD_SAFE_STATIC_LOCAL(Mutex, mutex, new Mutex); 92 DEFINE_THREAD_SAFE_STATIC_LOCAL(Mutex, mutex, new Mutex);
93 return mutex; 93 return mutex;
94 } 94 }
95 95
96 static HashSet<WorkerThread*>& workerThreads() 96 static HashSet<WorkerThread*>& workerThreads()
97 { 97 {
98 DEFINE_STATIC_LOCAL(HashSet<WorkerThread*>, threads, ()); 98 DEFINE_STATIC_LOCAL(HashSet<WorkerThread*>, threads, ());
99 return threads; 99 return threads;
100 } 100 }
101 101
102 WorkerThread::~WorkerThread()
103 {
104 MutexLocker lock(threadSetMutex());
105 DCHECK(workerThreads().contains(this));
106 workerThreads().remove(this);
107 }
108
109 void WorkerThread::start(PassOwnPtr<WorkerThreadStartupData> startupData)
110 {
111 DCHECK(isMainThread());
112
113 if (m_started)
114 return;
115
116 m_started = true;
117 workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBi nd(&WorkerThread::initializeOnWorkerThread, AllowCrossThreadAccess(this), passed (std::move(startupData))));
118 }
119
120 void WorkerThread::terminate()
121 {
122 DCHECK(isMainThread());
123
124 // Prevent the deadlock between GC and an attempt to terminate a thread.
125 SafePointScope safePointScope(BlinkGC::HeapPointersOnStack);
126
127 // Protect against this method, initializeOnWorkerThread() or termination
128 // via the global scope racing each other.
129 MutexLocker lock(m_threadStateMutex);
130
131 // If terminate has already been called, just return.
132 if (m_terminated)
133 return;
134 m_terminated = true;
135
136 // Signal the thread to notify that the thread's stopping.
137 if (m_terminationEvent)
138 m_terminationEvent->signal();
139
140 // If the worker thread was never initialized, don't start another
141 // shutdown, but still wait for the thread to signal when shutdown has
142 // completed on initializeOnWorkerThread().
143 if (!m_workerGlobalScope)
144 return;
145
146 if (!m_readyToShutdown) {
147 // Ensure that tasks are being handled by thread event loop. If script
148 // execution weren't forbidden, a while(1) loop in JS could keep the
149 // thread alive forever.
150 // If |m_readyToShutdown| is set, the worker thread has already noticed
151 // that the thread is about to be terminated and the worker global scope
152 // is already disposed, so we don't have to explicitly terminate the
153 // execution.
154 m_workerGlobalScope->scriptController()->willScheduleExecutionTerminatio n();
155
156 // This condition is not entirely correct because other scripts can
157 // be being initialized or terminated simuletaneously. Though this
158 // function itself is protected by a mutex, it is possible that
159 // |workerScriptCount()| here is not consistent with that in
160 // |initialize| and |shutdown|.
161 if (workerBackingThread().workerScriptCount() == 1) {
162 if (m_runningDebuggerTask) {
163 // Terminating during debugger task may lead to crash due to
164 // heavy use of v8 api in debugger. Any debugger task is
165 // guaranteed to finish, so we can postpone termination after
166 // task has finished.
167 // Note: m_runningDebuggerTask and m_shouldTerminateV8Execution
168 // access must be guarded by the lock.
169 m_shouldTerminateV8Execution = true;
170 } else {
171 // TODO(yhirano): TerminateExecution should be called more
172 // carefully (https://crbug.com/413518).
173 isolate()->TerminateExecution();
174 }
175 }
176 }
177
178 m_inspectorTaskRunner->kill();
179 workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBi nd(&WorkerThread::prepareForShutdownOnWorkerThread, AllowCrossThreadAccess(this) ));
180 workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBi nd(&WorkerThread::performShutdownOnWorkerThread, AllowCrossThreadAccess(this)));
181 }
182
183 void WorkerThread::terminateAndWait()
184 {
185 DCHECK(isMainThread());
186 terminate();
187 m_shutdownEvent->wait();
188 }
189
190 void WorkerThread::terminateAndWaitForAllWorkers()
191 {
192 DCHECK(isMainThread());
193
194 // Keep this lock to prevent WorkerThread instances from being destroyed.
195 MutexLocker lock(threadSetMutex());
196 HashSet<WorkerThread*> threads = workerThreads();
197 for (WorkerThread* thread : threads)
198 thread->terminate();
199
200 for (WorkerThread* thread : threads)
201 thread->m_shutdownEvent->wait();
202 }
203
204 v8::Isolate* WorkerThread::isolate()
205 {
206 return workerBackingThread().isolate();
207 }
208
209 bool WorkerThread::isCurrentThread()
210 {
211 return m_started && workerBackingThread().backingThread().isCurrentThread();
212 }
213
214 void WorkerThread::postTask(const WebTraceLocation& location, std::unique_ptr<Ex ecutionContextTask> task)
215 {
216 workerBackingThread().backingThread().postTask(location, createWorkerThreadT ask(std::move(task), true));
217 }
218
219 void WorkerThread::appendDebuggerTask(std::unique_ptr<CrossThreadClosure> task)
220 {
221 {
222 MutexLocker lock(m_threadStateMutex);
223 if (m_readyToShutdown)
224 return;
225 }
226 m_inspectorTaskRunner->appendTask(threadSafeBind(&WorkerThread::runDebuggerT askOnWorkerThread, AllowCrossThreadAccess(this), passed(std::move(task))));
227 {
228 MutexLocker lock(m_threadStateMutex);
229 if (isolate())
230 m_inspectorTaskRunner->interruptAndRunAllTasksDontWait(isolate());
231 }
232 workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBi nd(&WorkerThread::runDebuggerTaskDontWaitOnWorkerThread, AllowCrossThreadAccess( this)));
233 }
234
235 void WorkerThread::startRunningDebuggerTasksOnPause()
236 {
237 m_pausedInDebugger = true;
238 ThreadDebugger::idleStarted(isolate());
239 std::unique_ptr<CrossThreadClosure> task;
240 do {
241 {
242 SafePointScope safePointScope(BlinkGC::HeapPointersOnStack);
243 task = m_inspectorTaskRunner->takeNextTask(InspectorTaskRunner::Wait ForTask);
244 }
245 if (task)
246 (*task)();
247 // Keep waiting until execution is resumed.
248 } while (task && m_pausedInDebugger);
249 ThreadDebugger::idleFinished(isolate());
250 }
251
252 void WorkerThread::stopRunningDebuggerTasksOnPause()
253 {
254 m_pausedInDebugger = false;
255 }
256
257 WorkerGlobalScope* WorkerThread::workerGlobalScope()
258 {
259 DCHECK(isCurrentThread());
260 return m_workerGlobalScope.get();
261 }
262
263 bool WorkerThread::terminated()
264 {
265 MutexLocker lock(m_threadStateMutex);
266 return m_terminated;
267 }
268
102 unsigned WorkerThread::workerThreadCount() 269 unsigned WorkerThread::workerThreadCount()
103 { 270 {
104 MutexLocker lock(threadSetMutex()); 271 MutexLocker lock(threadSetMutex());
105 return workerThreads().size(); 272 return workerThreads().size();
106 } 273 }
107 274
108 void WorkerThread::performTask(std::unique_ptr<ExecutionContextTask> task, bool isInstrumented) 275 PlatformThreadId WorkerThread::platformThreadId()
109 { 276 {
110 DCHECK(isCurrentThread()); 277 if (!m_started)
111 { 278 return 0;
112 MutexLocker lock(m_threadStateMutex); 279 return workerBackingThread().backingThread().platformThread().threadId();
113 if (m_readyToShutdown)
114 return;
115 }
116
117 WorkerGlobalScope* globalScope = workerGlobalScope();
118 // If the thread is terminated before it had a chance initialize (see
119 // WorkerThread::Initialize()), we mustn't run any of the posted tasks.
120 if (!globalScope) {
121 DCHECK(terminated());
122 return;
123 }
124
125 InspectorInstrumentation::AsyncTask asyncTask(globalScope, task.get(), isIns trumented);
126 task->performTask(globalScope);
127 }
128
129 std::unique_ptr<CrossThreadClosure> WorkerThread::createWorkerThreadTask(std::un ique_ptr<ExecutionContextTask> task, bool isInstrumented)
130 {
131 if (isInstrumented)
132 isInstrumented = !task->taskNameForInstrumentation().isEmpty();
133 if (isInstrumented) {
134 DCHECK(isCurrentThread());
135 InspectorInstrumentation::asyncTaskScheduled(workerGlobalScope(), "Worke r task", task.get());
136 }
137 return threadSafeBind(&WorkerThread::performTask, AllowCrossThreadAccess(thi s), passed(std::move(task)), isInstrumented);
138 } 280 }
139 281
140 WorkerThread::WorkerThread(PassRefPtr<WorkerLoaderProxy> workerLoaderProxy, Work erReportingProxy& workerReportingProxy) 282 WorkerThread::WorkerThread(PassRefPtr<WorkerLoaderProxy> workerLoaderProxy, Work erReportingProxy& workerReportingProxy)
141 : m_inspectorTaskRunner(adoptPtr(new InspectorTaskRunner())) 283 : m_inspectorTaskRunner(adoptPtr(new InspectorTaskRunner()))
142 , m_workerLoaderProxy(workerLoaderProxy) 284 , m_workerLoaderProxy(workerLoaderProxy)
143 , m_workerReportingProxy(workerReportingProxy) 285 , m_workerReportingProxy(workerReportingProxy)
144 , m_terminationEvent(adoptPtr(new WaitableEvent( 286 , m_terminationEvent(adoptPtr(new WaitableEvent(
145 WaitableEvent::ResetPolicy::Manual, 287 WaitableEvent::ResetPolicy::Manual,
146 WaitableEvent::InitialState::NonSignaled))) 288 WaitableEvent::InitialState::NonSignaled)))
147 , m_shutdownEvent(adoptPtr(new WaitableEvent( 289 , m_shutdownEvent(adoptPtr(new WaitableEvent(
148 WaitableEvent::ResetPolicy::Manual, 290 WaitableEvent::ResetPolicy::Manual,
149 WaitableEvent::InitialState::NonSignaled))) 291 WaitableEvent::InitialState::NonSignaled)))
150 { 292 {
151 MutexLocker lock(threadSetMutex()); 293 MutexLocker lock(threadSetMutex());
152 workerThreads().add(this); 294 workerThreads().add(this);
153 } 295 }
154 296
155 WorkerThread::~WorkerThread() 297 std::unique_ptr<CrossThreadClosure> WorkerThread::createWorkerThreadTask(std::un ique_ptr<ExecutionContextTask> task, bool isInstrumented)
156 { 298 {
157 MutexLocker lock(threadSetMutex()); 299 if (isInstrumented)
158 DCHECK(workerThreads().contains(this)); 300 isInstrumented = !task->taskNameForInstrumentation().isEmpty();
159 workerThreads().remove(this); 301 if (isInstrumented) {
302 DCHECK(isCurrentThread());
303 InspectorInstrumentation::asyncTaskScheduled(workerGlobalScope(), "Worke r task", task.get());
304 }
305 return threadSafeBind(&WorkerThread::performTaskOnWorkerThread, AllowCrossTh readAccess(this), passed(std::move(task)), isInstrumented);
160 } 306 }
161 307
162 void WorkerThread::start(PassOwnPtr<WorkerThreadStartupData> startupData) 308 void WorkerThread::initializeOnWorkerThread(PassOwnPtr<WorkerThreadStartupData> startupData)
163 {
164 DCHECK(isMainThread());
165
166 if (m_started)
167 return;
168
169 m_started = true;
170 workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBi nd(&WorkerThread::initialize, AllowCrossThreadAccess(this), passed(std::move(sta rtupData))));
171 }
172
173 PlatformThreadId WorkerThread::platformThreadId()
174 {
175 if (!m_started)
176 return 0;
177 return workerBackingThread().backingThread().platformThread().threadId();
178 }
179
180 void WorkerThread::initialize(PassOwnPtr<WorkerThreadStartupData> startupData)
181 { 309 {
182 KURL scriptURL = startupData->m_scriptURL; 310 KURL scriptURL = startupData->m_scriptURL;
183 String sourceCode = startupData->m_sourceCode; 311 String sourceCode = startupData->m_sourceCode;
184 WorkerThreadStartMode startMode = startupData->m_startMode; 312 WorkerThreadStartMode startMode = startupData->m_startMode;
185 OwnPtr<Vector<char>> cachedMetaData = std::move(startupData->m_cachedMetaDat a); 313 OwnPtr<Vector<char>> cachedMetaData = std::move(startupData->m_cachedMetaDat a);
186 V8CacheOptions v8CacheOptions = startupData->m_v8CacheOptions; 314 V8CacheOptions v8CacheOptions = startupData->m_v8CacheOptions;
187 315
188 { 316 {
189 MutexLocker lock(m_threadStateMutex); 317 MutexLocker lock(m_threadStateMutex);
190 318
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 } 359 }
232 360
233 CachedMetadataHandler* handler = workerGlobalScope()->createWorkerScriptCach edMetadataHandler(scriptURL, cachedMetaData.get()); 361 CachedMetadataHandler* handler = workerGlobalScope()->createWorkerScriptCach edMetadataHandler(scriptURL, cachedMetaData.get());
234 bool success = m_workerGlobalScope->scriptController()->evaluate(ScriptSourc eCode(sourceCode, scriptURL), nullptr, handler, v8CacheOptions); 362 bool success = m_workerGlobalScope->scriptController()->evaluate(ScriptSourc eCode(sourceCode, scriptURL), nullptr, handler, v8CacheOptions);
235 m_workerGlobalScope->didEvaluateWorkerScript(); 363 m_workerGlobalScope->didEvaluateWorkerScript();
236 m_workerReportingProxy.didEvaluateWorkerScript(success); 364 m_workerReportingProxy.didEvaluateWorkerScript(success);
237 365
238 postInitialize(); 366 postInitialize();
239 } 367 }
240 368
241 void WorkerThread::prepareForShutdown() 369 void WorkerThread::prepareForShutdownOnWorkerThread()
242 { 370 {
243 DCHECK(isCurrentThread()); 371 DCHECK(isCurrentThread());
244 { 372 {
245 MutexLocker lock(m_threadStateMutex); 373 MutexLocker lock(m_threadStateMutex);
246 if (m_readyToShutdown) 374 if (m_readyToShutdown)
247 return; 375 return;
248 m_readyToShutdown = true; 376 m_readyToShutdown = true;
249 } 377 }
250 378
251 workerReportingProxy().willDestroyWorkerGlobalScope(); 379 workerReportingProxy().willDestroyWorkerGlobalScope();
252 InspectorInstrumentation::allAsyncTasksCanceled(workerGlobalScope()); 380 InspectorInstrumentation::allAsyncTasksCanceled(workerGlobalScope());
253 workerGlobalScope()->dispose(); 381 workerGlobalScope()->dispose();
254 workerBackingThread().backingThread().removeTaskObserver(m_microtaskRunner.g et()); 382 workerBackingThread().backingThread().removeTaskObserver(m_microtaskRunner.g et());
255 } 383 }
256 384
257 void WorkerThread::performShutdown() 385 void WorkerThread::performShutdownOnWorkerThread()
258 { 386 {
259 DCHECK(isCurrentThread()); 387 DCHECK(isCurrentThread());
260 #if DCHECK_IS_ON 388 #if DCHECK_IS_ON
261 { 389 {
262 MutexLocker lock(m_threadStateMutex); 390 MutexLocker lock(m_threadStateMutex);
263 DCHECK(m_terminated); 391 DCHECK(m_terminated);
264 DCHECK(m_readyToShutdown); 392 DCHECK(m_readyToShutdown);
265 } 393 }
266 #endif 394 #endif
267 395
(...skipping 10 matching lines...) Expand all
278 406
279 m_microtaskRunner = nullptr; 407 m_microtaskRunner = nullptr;
280 408
281 // Notify the proxy that the WorkerGlobalScope has been disposed of. 409 // Notify the proxy that the WorkerGlobalScope has been disposed of.
282 // This can free this thread object, hence it must not be touched afterwards . 410 // This can free this thread object, hence it must not be touched afterwards .
283 workerReportingProxy().workerThreadTerminated(); 411 workerReportingProxy().workerThreadTerminated();
284 412
285 m_shutdownEvent->signal(); 413 m_shutdownEvent->signal();
286 } 414 }
287 415
288 void WorkerThread::terminate() 416 void WorkerThread::performTaskOnWorkerThread(std::unique_ptr<ExecutionContextTas k> task, bool isInstrumented)
289 {
290 DCHECK(isMainThread());
291
292 // Prevent the deadlock between GC and an attempt to terminate a thread.
293 SafePointScope safePointScope(BlinkGC::HeapPointersOnStack);
294
295 // Protect against this method, initialize() or termination via the global
296 // scope racing each other.
297 MutexLocker lock(m_threadStateMutex);
298
299 // If terminate has already been called, just return.
300 if (m_terminated)
301 return;
302 m_terminated = true;
303
304 // Signal the thread to notify that the thread's stopping.
305 if (m_terminationEvent)
306 m_terminationEvent->signal();
307
308 // If the worker thread was never initialized, don't start another
309 // shutdown, but still wait for the thread to signal when shutdown has
310 // completed on initialize().
311 if (!m_workerGlobalScope)
312 return;
313
314 if (!m_readyToShutdown) {
315 // Ensure that tasks are being handled by thread event loop. If script
316 // execution weren't forbidden, a while(1) loop in JS could keep the
317 // thread alive forever.
318 // If |m_readyToShutdown| is set, the worker thread has already noticed
319 // that the thread is about to be terminated and the worker global scope
320 // is already disposed, so we don't have to explicitly terminate the
321 // execution.
322 m_workerGlobalScope->scriptController()->willScheduleExecutionTerminatio n();
323
324 // This condition is not entirely correct because other scripts can
325 // be being initialized or terminated simuletaneously. Though this
326 // function itself is protected by a mutex, it is possible that
327 // |workerScriptCount()| here is not consistent with that in
328 // |initialize| and |shutdown|.
329 if (workerBackingThread().workerScriptCount() == 1) {
330 if (m_runningDebuggerTask) {
331 // Terminating during debugger task may lead to crash due to
332 // heavy use of v8 api in debugger. Any debugger task is
333 // guaranteed to finish, so we can postpone termination after
334 // task has finished.
335 // Note: m_runningDebuggerTask and m_shouldTerminateV8Execution
336 // access must be guarded by the lock.
337 m_shouldTerminateV8Execution = true;
338 } else {
339 // TODO(yhirano): TerminateExecution should be called more
340 // carefully (https://crbug.com/413518).
341 isolate()->TerminateExecution();
342 }
343 }
344 }
345
346 m_inspectorTaskRunner->kill();
347 workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBi nd(&WorkerThread::prepareForShutdown, AllowCrossThreadAccess(this)));
348 workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBi nd(&WorkerThread::performShutdown, AllowCrossThreadAccess(this)));
349 }
350
351 void WorkerThread::terminateAndWait()
352 {
353 DCHECK(isMainThread());
354 terminate();
355 m_shutdownEvent->wait();
356 }
357
358 void WorkerThread::terminateAndWaitForAllWorkers()
359 {
360 DCHECK(isMainThread());
361
362 // Keep this lock to prevent WorkerThread instances from being destroyed.
363 MutexLocker lock(threadSetMutex());
364 HashSet<WorkerThread*> threads = workerThreads();
365 for (WorkerThread* thread : threads)
366 thread->terminate();
367
368 for (WorkerThread* thread : threads)
369 thread->m_shutdownEvent->wait();
370 }
371
372 WorkerGlobalScope* WorkerThread::workerGlobalScope()
373 { 417 {
374 DCHECK(isCurrentThread()); 418 DCHECK(isCurrentThread());
375 return m_workerGlobalScope.get();
376 }
377
378 bool WorkerThread::terminated()
379 {
380 MutexLocker lock(m_threadStateMutex);
381 return m_terminated;
382 }
383
384 v8::Isolate* WorkerThread::isolate()
385 {
386 return workerBackingThread().isolate();
387 }
388
389 bool WorkerThread::isCurrentThread()
390 {
391 return m_started && workerBackingThread().backingThread().isCurrentThread();
392 }
393
394 void WorkerThread::postTask(const WebTraceLocation& location, std::unique_ptr<Ex ecutionContextTask> task)
395 {
396 workerBackingThread().backingThread().postTask(location, createWorkerThreadT ask(std::move(task), true));
397 }
398
399 void WorkerThread::runDebuggerTaskDontWait()
400 {
401 DCHECK(isCurrentThread());
402 std::unique_ptr<CrossThreadClosure> task = m_inspectorTaskRunner->takeNextTa sk(InspectorTaskRunner::DontWaitForTask);
403 if (task)
404 (*task)();
405 }
406
407 void WorkerThread::appendDebuggerTask(std::unique_ptr<CrossThreadClosure> task)
408 {
409 { 419 {
410 MutexLocker lock(m_threadStateMutex); 420 MutexLocker lock(m_threadStateMutex);
411 if (m_readyToShutdown) 421 if (m_readyToShutdown)
412 return; 422 return;
413 } 423 }
414 m_inspectorTaskRunner->appendTask(threadSafeBind(&WorkerThread::runDebuggerT ask, AllowCrossThreadAccess(this), passed(std::move(task)))); 424
415 { 425 WorkerGlobalScope* globalScope = workerGlobalScope();
416 MutexLocker lock(m_threadStateMutex); 426 // If the thread is terminated before it had a chance initialize (see
417 if (isolate()) 427 // WorkerThread::Initialize()), we mustn't run any of the posted tasks.
418 m_inspectorTaskRunner->interruptAndRunAllTasksDontWait(isolate()); 428 if (!globalScope) {
429 DCHECK(terminated());
430 return;
419 } 431 }
420 workerBackingThread().backingThread().postTask(BLINK_FROM_HERE, threadSafeBi nd(&WorkerThread::runDebuggerTaskDontWait, AllowCrossThreadAccess(this))); 432
433 InspectorInstrumentation::AsyncTask asyncTask(globalScope, task.get(), isIns trumented);
434 task->performTask(globalScope);
421 } 435 }
422 436
423 void WorkerThread::runDebuggerTask(std::unique_ptr<CrossThreadClosure> task) 437 void WorkerThread::runDebuggerTaskOnWorkerThread(std::unique_ptr<CrossThreadClos ure> task)
424 { 438 {
425 DCHECK(isCurrentThread()); 439 DCHECK(isCurrentThread());
426 InspectorTaskRunner::IgnoreInterruptsScope scope(m_inspectorTaskRunner.get() ); 440 InspectorTaskRunner::IgnoreInterruptsScope scope(m_inspectorTaskRunner.get() );
427 { 441 {
428 MutexLocker lock(m_threadStateMutex); 442 MutexLocker lock(m_threadStateMutex);
429 m_runningDebuggerTask = true; 443 m_runningDebuggerTask = true;
430 } 444 }
431 ThreadDebugger::idleFinished(isolate()); 445 ThreadDebugger::idleFinished(isolate());
432 (*task)(); 446 (*task)();
433 ThreadDebugger::idleStarted(isolate()); 447 ThreadDebugger::idleStarted(isolate());
434 { 448 {
435 MutexLocker lock(m_threadStateMutex); 449 MutexLocker lock(m_threadStateMutex);
436 m_runningDebuggerTask = false; 450 m_runningDebuggerTask = false;
437 if (m_shouldTerminateV8Execution) { 451 if (m_shouldTerminateV8Execution) {
438 m_shouldTerminateV8Execution = false; 452 m_shouldTerminateV8Execution = false;
439 isolate()->TerminateExecution(); 453 isolate()->TerminateExecution();
440 } 454 }
441 } 455 }
442 } 456 }
443 457
444 void WorkerThread::startRunningDebuggerTasksOnPause() 458 void WorkerThread::runDebuggerTaskDontWaitOnWorkerThread()
445 { 459 {
446 m_pausedInDebugger = true; 460 DCHECK(isCurrentThread());
447 ThreadDebugger::idleStarted(isolate()); 461 std::unique_ptr<CrossThreadClosure> task = m_inspectorTaskRunner->takeNextTa sk(InspectorTaskRunner::DontWaitForTask);
448 std::unique_ptr<CrossThreadClosure> task; 462 if (task)
449 do { 463 (*task)();
450 {
451 SafePointScope safePointScope(BlinkGC::HeapPointersOnStack);
452 task = m_inspectorTaskRunner->takeNextTask(InspectorTaskRunner::Wait ForTask);
453 }
454 if (task)
455 (*task)();
456 // Keep waiting until execution is resumed.
457 } while (task && m_pausedInDebugger);
458 ThreadDebugger::idleFinished(isolate());
459 }
460
461 void WorkerThread::stopRunningDebuggerTasksOnPause()
462 {
463 m_pausedInDebugger = false;
464 } 464 }
465 465
466 } // namespace blink 466 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/workers/WorkerThread.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698