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

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

Issue 1111693003: Remove the concept of a cleanup task (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 7 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 | Annotate | Revision Log
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 28 matching lines...) Expand all
39 #include "core/workers/WorkerReportingProxy.h" 39 #include "core/workers/WorkerReportingProxy.h"
40 #include "core/workers/WorkerThreadStartupData.h" 40 #include "core/workers/WorkerThreadStartupData.h"
41 #include "platform/PlatformThreadData.h" 41 #include "platform/PlatformThreadData.h"
42 #include "platform/Task.h" 42 #include "platform/Task.h"
43 #include "platform/ThreadSafeFunctional.h" 43 #include "platform/ThreadSafeFunctional.h"
44 #include "platform/ThreadTimers.h" 44 #include "platform/ThreadTimers.h"
45 #include "platform/heap/SafePoint.h" 45 #include "platform/heap/SafePoint.h"
46 #include "platform/heap/ThreadState.h" 46 #include "platform/heap/ThreadState.h"
47 #include "platform/weborigin/KURL.h" 47 #include "platform/weborigin/KURL.h"
48 #include "public/platform/Platform.h" 48 #include "public/platform/Platform.h"
49 #include "public/platform/WebScheduler.h"
49 #include "public/platform/WebThread.h" 50 #include "public/platform/WebThread.h"
50 #include "public/platform/WebWaitableEvent.h" 51 #include "public/platform/WebWaitableEvent.h"
51 #include "wtf/Noncopyable.h" 52 #include "wtf/Noncopyable.h"
52 #include "wtf/WeakPtr.h" 53 #include "wtf/WeakPtr.h"
53 #include "wtf/text/WTFString.h" 54 #include "wtf/text/WTFString.h"
54 55
55 namespace blink { 56 namespace blink {
56 57
57 namespace { 58 namespace {
58 const int64_t kShortIdleHandlerDelayMs = 1000; 59 const int64_t kShortIdleHandlerDelayMs = 1000;
59 const int64_t kLongIdleHandlerDelayMs = 10*1000; 60 const int64_t kLongIdleHandlerDelayMs = 10*1000;
60 61
61 class MicrotaskRunner : public WebThread::TaskObserver { 62 class MicrotaskRunner : public WebThread::TaskObserver {
62 public: 63 public:
63 explicit MicrotaskRunner(WorkerThread* workerThread) 64 explicit MicrotaskRunner(WorkerThread* workerThread)
64 : m_workerThread(workerThread) 65 : m_workerThread(workerThread)
65 { 66 {
66 } 67 }
67 68
68 virtual void willProcessTask() override { } 69 virtual void willProcessTask() override { }
69 virtual void didProcessTask() override 70 virtual void didProcessTask() override
70 { 71 {
71 Microtask::performCheckpoint(); 72 Microtask::performCheckpoint();
72 if (WorkerGlobalScope* globalScope = m_workerThread->workerGlobalScope() ) { 73 if (WorkerGlobalScope* globalScope = m_workerThread->workerGlobalScope() ) {
73 if (WorkerScriptController* scriptController = globalScope->script() ) 74 if (WorkerScriptController* scriptController = globalScope->script() )
74 scriptController->rejectedPromises()->processQueue(); 75 scriptController->rejectedPromises()->processQueue();
76 if (globalScope->isClosing())
77 m_workerThread->workerReportingProxy().workerGlobalScopeClosed() ;
75 } 78 }
76 } 79 }
77 80
78 private: 81 private:
79 // Thread owns the microtask runner; reference remains 82 // Thread owns the microtask runner; reference remains
80 // valid for the lifetime of this object. 83 // valid for the lifetime of this object.
81 WorkerThread* m_workerThread; 84 WorkerThread* m_workerThread;
82 }; 85 };
83 86
84 } // namespace 87 } // namespace
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 static PassOwnPtr<WorkerThreadTask> create(WorkerThread& workerThread, PassO wnPtr<ExecutionContextTask> task, bool isInstrumented) 204 static PassOwnPtr<WorkerThreadTask> create(WorkerThread& workerThread, PassO wnPtr<ExecutionContextTask> task, bool isInstrumented)
202 { 205 {
203 return adoptPtr(new WorkerThreadTask(workerThread, task, isInstrumented) ); 206 return adoptPtr(new WorkerThreadTask(workerThread, task, isInstrumented) );
204 } 207 }
205 208
206 virtual ~WorkerThreadTask() { } 209 virtual ~WorkerThreadTask() { }
207 210
208 virtual void run() override 211 virtual void run() override
209 { 212 {
210 WorkerGlobalScope* workerGlobalScope = m_workerThread.workerGlobalScope( ); 213 WorkerGlobalScope* workerGlobalScope = m_workerThread.workerGlobalScope( );
211 // Tasks could be put on the message loop after the cleanup task, 214 ASSERT(workerGlobalScope);
212 // ensure none of those are ran.
213 if (!workerGlobalScope)
214 return;
215 215
216 if (m_isInstrumented) 216 if (m_isInstrumented)
217 InspectorInstrumentation::willPerformExecutionContextTask(workerGlob alScope, m_task.get()); 217 InspectorInstrumentation::willPerformExecutionContextTask(workerGlob alScope, m_task.get());
218 if ((!workerGlobalScope->isClosing() && !m_workerThread.terminated()) || m_task->isCleanupTask()) 218 m_task->performTask(workerGlobalScope);
219 m_task->performTask(workerGlobalScope);
220 if (m_isInstrumented) 219 if (m_isInstrumented)
221 InspectorInstrumentation::didPerformExecutionContextTask(workerGloba lScope); 220 InspectorInstrumentation::didPerformExecutionContextTask(workerGloba lScope);
222 } 221 }
223 222
224 private: 223 private:
225 WorkerThreadTask(WorkerThread& workerThread, PassOwnPtr<ExecutionContextTask > task, bool isInstrumented) 224 WorkerThreadTask(WorkerThread& workerThread, PassOwnPtr<ExecutionContextTask > task, bool isInstrumented)
226 : m_workerThread(workerThread) 225 : m_workerThread(workerThread)
227 , m_task(task) 226 , m_task(task)
228 , m_isInstrumented(isInstrumented) 227 , m_isInstrumented(isInstrumented)
229 { 228 {
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 PassOwnPtr<WebThreadSupportingGC> WorkerThread::createWebThreadSupportingGC() 354 PassOwnPtr<WebThreadSupportingGC> WorkerThread::createWebThreadSupportingGC()
356 { 355 {
357 return WebThreadSupportingGC::create(m_threadName); 356 return WebThreadSupportingGC::create(m_threadName);
358 } 357 }
359 358
360 void WorkerThread::cleanup() 359 void WorkerThread::cleanup()
361 { 360 {
362 // This should be called before we start the shutdown procedure. 361 // This should be called before we start the shutdown procedure.
363 workerReportingProxy().willDestroyWorkerGlobalScope(); 362 workerReportingProxy().willDestroyWorkerGlobalScope();
364 363
364 // Ensure no posted tasks will run from this point on.
365 m_thread->platformThread().scheduler()->shutdown();
366
365 // The below assignment will destroy the context, which will in turn notify messaging proxy. 367 // The below assignment will destroy the context, which will in turn notify messaging proxy.
366 // We cannot let any objects survive past thread exit, because no other thre ad will run GC or otherwise destroy them. 368 // We cannot let any objects survive past thread exit, because no other thre ad will run GC or otherwise destroy them.
367 // If Oilpan is enabled, we detach of the context/global scope, with the fin al heap cleanup below sweeping it out. 369 // If Oilpan is enabled, we detach of the context/global scope, with the fin al heap cleanup below sweeping it out.
368 #if !ENABLE(OILPAN) 370 #if !ENABLE(OILPAN)
369 ASSERT(m_workerGlobalScope->hasOneRef()); 371 ASSERT(m_workerGlobalScope->hasOneRef());
370 #endif 372 #endif
371 m_workerGlobalScope->notifyContextDestroyed(); 373 m_workerGlobalScope->notifyContextDestroyed();
372 m_workerGlobalScope = nullptr; 374 m_workerGlobalScope = nullptr;
373 375
374 m_thread->detachGC(); 376 m_thread->detachGC();
375 destroyIsolate(); 377 destroyIsolate();
376 378
377 m_thread->removeTaskObserver(m_microtaskRunner.get()); 379 m_thread->removeTaskObserver(m_microtaskRunner.get());
378 m_microtaskRunner = nullptr; 380 m_microtaskRunner = nullptr;
379 381
380 // Notify the proxy that the WorkerGlobalScope has been disposed of. 382 // Notify the proxy that the WorkerGlobalScope has been disposed of.
381 // This can free this thread object, hence it must not be touched afterwards . 383 // This can free this thread object, hence it must not be touched afterwards .
382 workerReportingProxy().workerThreadTerminated(); 384 workerReportingProxy().workerThreadTerminated();
383 385
384 m_terminationEvent->signal(); 386 m_terminationEvent->signal();
385 387
386 // Clean up PlatformThreadData before WTF::WTFThreadData goes away! 388 // Clean up PlatformThreadData before WTF::WTFThreadData goes away!
387 PlatformThreadData::current().destroy(); 389 PlatformThreadData::current().destroy();
388 } 390 }
389 391
390 class WorkerThreadShutdownFinishTask : public ExecutionContextTask {
391 public:
392 static PassOwnPtr<WorkerThreadShutdownFinishTask> create()
393 {
394 return adoptPtr(new WorkerThreadShutdownFinishTask());
395 }
396
397 virtual void performTask(ExecutionContext *context)
398 {
399 WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context);
400 workerGlobalScope->dispose();
401
402 WorkerThread* workerThread = workerGlobalScope->thread();
403 workerThread->willDestroyIsolate();
404 workerThread->m_thread->postTask(FROM_HERE, new Task(WTF::bind(&WorkerTh read::cleanup, workerThread)));
405 }
406
407 virtual bool isCleanupTask() const { return true; }
408 };
409
410 class WorkerThreadShutdownStartTask : public ExecutionContextTask {
411 public:
412 static PassOwnPtr<WorkerThreadShutdownStartTask> create()
413 {
414 return adoptPtr(new WorkerThreadShutdownStartTask());
415 }
416
417 virtual void performTask(ExecutionContext *context)
418 {
419 WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context);
420 workerGlobalScope->stopActiveDOMObjects();
421 PlatformThreadData::current().threadTimers().setSharedTimer(nullptr);
422
423 // Event listeners would keep DOMWrapperWorld objects alive for too long . Also, they have references to JS objects,
424 // which become dangling once Heap is destroyed.
425 workerGlobalScope->removeAllEventListeners();
426
427 // Stick a shutdown command at the end of the queue, so that we deal
428 // with all the cleanup tasks the databases post first.
429 workerGlobalScope->postTask(FROM_HERE, WorkerThreadShutdownFinishTask::c reate());
430 }
431
432 virtual bool isCleanupTask() const { return true; }
433 };
434
435 void WorkerThread::stop() 392 void WorkerThread::stop()
436 { 393 {
437 // Prevent the deadlock between GC and an attempt to stop a thread. 394 // Prevent the deadlock between GC and an attempt to stop a thread.
438 SafePointScope safePointScope(ThreadState::HeapPointersOnStack); 395 SafePointScope safePointScope(ThreadState::HeapPointersOnStack);
439 stopInternal(); 396 stopInternal();
440 } 397 }
441 398
442 void WorkerThread::stopInShutdownSequence() 399 void WorkerThread::stopInShutdownSequence()
443 { 400 {
444 stopInternal(); 401 stopInternal();
(...skipping 26 matching lines...) Expand all
471 m_shutdownEvent->signal(); 428 m_shutdownEvent->signal();
472 429
473 if (!m_workerGlobalScope) 430 if (!m_workerGlobalScope)
474 return; 431 return;
475 432
476 // 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. 433 // 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.
477 terminateV8Execution(); 434 terminateV8Execution();
478 435
479 InspectorInstrumentation::didKillAllExecutionContextTasks(m_workerGlobalScop e.get()); 436 InspectorInstrumentation::didKillAllExecutionContextTasks(m_workerGlobalScop e.get());
480 m_debuggerMessageQueue.kill(); 437 m_debuggerMessageQueue.kill();
481 postTask(FROM_HERE, WorkerThreadShutdownStartTask::create()); 438
439 m_workerGlobalScope->stopActiveDOMObjects();
440 PlatformThreadData::current().threadTimers().setSharedTimer(nullptr);
441
442 // Event listeners would keep DOMWrapperWorld objects alive for too long. Al so, they have references to JS objects,
443 // which become dangling once Heap is destroyed.
444 m_workerGlobalScope->removeAllEventListeners();
445 m_workerGlobalScope->dispose();
446
447 willDestroyIsolate();
448 cleanup();
kinuko 2015/04/30 04:03:44 stopInternal() is called on the main thread while
Sami 2015/05/06 17:37:32 Thanks for the hint! It took a while for me to wor
482 } 449 }
483 450
484 void WorkerThread::didStartRunLoop() 451 void WorkerThread::didStartRunLoop()
485 { 452 {
486 ASSERT(isCurrentThread()); 453 ASSERT(isCurrentThread());
487 blink::Platform::current()->didStartWorkerRunLoop(); 454 blink::Platform::current()->didStartWorkerRunLoop();
488 } 455 }
489 456
490 void WorkerThread::didStopRunLoop() 457 void WorkerThread::didStopRunLoop()
491 { 458 {
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); 578 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get());
612 } 579 }
613 580
614 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke rInspectorController) 581 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke rInspectorController)
615 { 582 {
616 MutexLocker locker(m_workerInspectorControllerMutex); 583 MutexLocker locker(m_workerInspectorControllerMutex);
617 m_workerInspectorController = workerInspectorController; 584 m_workerInspectorController = workerInspectorController;
618 } 585 }
619 586
620 } // namespace blink 587 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/workers/WorkerGlobalScope.cpp ('k') | Source/modules/webdatabase/DatabaseTracker.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698