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

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

Issue 1100413004: workers: Move ownership of WebThread from WorkerThread (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: reference 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 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 ASSERT(context->isWorkerGlobalScope()); 249 ASSERT(context->isWorkerGlobalScope());
250 m_thread->runDebuggerTask(WorkerThread::DontWaitForMessage); 250 m_thread->runDebuggerTask(WorkerThread::DontWaitForMessage);
251 } 251 }
252 252
253 private: 253 private:
254 explicit RunDebuggerQueueTask(WorkerThread* thread) : m_thread(thread) { } 254 explicit RunDebuggerQueueTask(WorkerThread* thread) : m_thread(thread) { }
255 255
256 WorkerThread* m_thread; 256 WorkerThread* m_thread;
257 }; 257 };
258 258
259 WorkerThread::WorkerThread(const char* threadName, PassRefPtr<WorkerLoaderProxy> workerLoaderProxy, WorkerReportingProxy& workerReportingProxy, PassOwnPtr<Worke rThreadStartupData> startupData) 259 WorkerThread::WorkerThread(PassRefPtr<WorkerLoaderProxy> workerLoaderProxy, Work erReportingProxy& workerReportingProxy, PassOwnPtr<WorkerThreadStartupData> star tupData)
260 : m_threadName(threadName) 260 : m_started(false)
261 , m_terminated(false) 261 , m_terminated(false)
262 , m_workerLoaderProxy(workerLoaderProxy) 262 , m_workerLoaderProxy(workerLoaderProxy)
263 , m_workerReportingProxy(workerReportingProxy) 263 , m_workerReportingProxy(workerReportingProxy)
264 , m_startupData(startupData) 264 , m_startupData(startupData)
265 , m_isolate(nullptr) 265 , m_isolate(nullptr)
266 , m_shutdownEvent(adoptPtr(Platform::current()->createWaitableEvent())) 266 , m_shutdownEvent(adoptPtr(Platform::current()->createWaitableEvent()))
267 , m_terminationEvent(adoptPtr(Platform::current()->createWaitableEvent())) 267 , m_terminationEvent(adoptPtr(Platform::current()->createWaitableEvent()))
268 { 268 {
269 MutexLocker lock(threadSetMutex()); 269 MutexLocker lock(threadSetMutex());
270 workerThreads().add(this); 270 workerThreads().add(this);
271 } 271 }
272 272
273 WorkerThread::~WorkerThread() 273 WorkerThread::~WorkerThread()
274 { 274 {
275 MutexLocker lock(threadSetMutex()); 275 MutexLocker lock(threadSetMutex());
276 ASSERT(workerThreads().contains(this)); 276 ASSERT(workerThreads().contains(this));
277 workerThreads().remove(this); 277 workerThreads().remove(this);
278 } 278 }
279 279
280 void WorkerThread::start() 280 void WorkerThread::start()
281 { 281 {
282 if (m_thread) 282 if (m_started)
283 return; 283 return;
284 284
285 m_thread = createWebThreadSupportingGC(); 285 m_started = true;
286 m_thread->postTask(FROM_HERE, new Task(threadSafeBind(&WorkerThread::initial ize, AllowCrossThreadAccess(this)))); 286 backingThread().postTask(FROM_HERE, new Task(threadSafeBind(&WorkerThread::i nitialize, AllowCrossThreadAccess(this))));
287 } 287 }
288 288
289 void WorkerThread::interruptAndDispatchInspectorCommands() 289 void WorkerThread::interruptAndDispatchInspectorCommands()
290 { 290 {
291 MutexLocker locker(m_workerInspectorControllerMutex); 291 MutexLocker locker(m_workerInspectorControllerMutex);
292 if (m_workerInspectorController) 292 if (m_workerInspectorController)
293 m_workerInspectorController->interruptAndDispatchInspectorCommands(); 293 m_workerInspectorController->interruptAndDispatchInspectorCommands();
294 } 294 }
295 295
296 PlatformThreadId WorkerThread::platformThreadId() const 296 PlatformThreadId WorkerThread::platformThreadId()
297 { 297 {
298 if (!m_thread) 298 if (!m_started)
299 return 0; 299 return 0;
300 return m_thread->platformThread().threadId(); 300 return backingThread().platformThread().threadId();
301 } 301 }
302 302
303 void WorkerThread::initialize() 303 void WorkerThread::initialize()
304 { 304 {
305 KURL scriptURL = m_startupData->m_scriptURL; 305 KURL scriptURL = m_startupData->m_scriptURL;
306 String sourceCode = m_startupData->m_sourceCode; 306 String sourceCode = m_startupData->m_sourceCode;
307 WorkerThreadStartMode startMode = m_startupData->m_startMode; 307 WorkerThreadStartMode startMode = m_startupData->m_startMode;
308 OwnPtr<Vector<char>> cachedMetaData = m_startupData->m_cachedMetaData.releas e(); 308 OwnPtr<Vector<char>> cachedMetaData = m_startupData->m_cachedMetaData.releas e();
309 V8CacheOptions v8CacheOptions = m_startupData->m_v8CacheOptions; 309 V8CacheOptions v8CacheOptions = m_startupData->m_v8CacheOptions;
310 310
311 { 311 {
312 MutexLocker lock(m_threadCreationMutex); 312 MutexLocker lock(m_threadCreationMutex);
313 313
314 // The worker was terminated before the thread had a chance to run. 314 // The worker was terminated before the thread had a chance to run.
315 if (m_terminated) { 315 if (m_terminated) {
316 // Notify the proxy that the WorkerGlobalScope has been disposed of. 316 // Notify the proxy that the WorkerGlobalScope has been disposed of.
317 // This can free this thread object, hence it must not be touched af terwards. 317 // This can free this thread object, hence it must not be touched af terwards.
318 m_workerReportingProxy.workerThreadTerminated(); 318 m_workerReportingProxy.workerThreadTerminated();
319 return; 319 return;
320 } 320 }
321 321
322 m_microtaskRunner = adoptPtr(new MicrotaskRunner(this)); 322 m_microtaskRunner = adoptPtr(new MicrotaskRunner(this));
323 m_thread->addTaskObserver(m_microtaskRunner.get()); 323 backingThread().addTaskObserver(m_microtaskRunner.get());
324 m_thread->attachGC(); 324 backingThread().attachGC();
325 325
326 m_isolate = initializeIsolate(); 326 m_isolate = initializeIsolate();
327 m_workerGlobalScope = createWorkerGlobalScope(m_startupData.release()); 327 m_workerGlobalScope = createWorkerGlobalScope(m_startupData.release());
328 m_workerGlobalScope->scriptLoaded(sourceCode.length(), cachedMetaData.ge t() ? cachedMetaData->size() : 0); 328 m_workerGlobalScope->scriptLoaded(sourceCode.length(), cachedMetaData.ge t() ? cachedMetaData->size() : 0);
329 329
330 PlatformThreadData::current().threadTimers().setSharedTimer(adoptPtr(new WorkerSharedTimer(this))); 330 PlatformThreadData::current().threadTimers().setSharedTimer(adoptPtr(new WorkerSharedTimer(this)));
331 } 331 }
332 332
333 // The corresponding call to stopRunLoop() is in ~WorkerScriptController(). 333 // The corresponding call to stopRunLoop() is in ~WorkerScriptController().
334 didStartRunLoop(); 334 didStartRunLoop();
(...skipping 10 matching lines...) Expand all
345 OwnPtr<CachedMetadataHandler> handler(workerGlobalScope()->createWorkerScrip tCachedMetadataHandler(scriptURL, cachedMetaData.get())); 345 OwnPtr<CachedMetadataHandler> handler(workerGlobalScope()->createWorkerScrip tCachedMetadataHandler(scriptURL, cachedMetaData.get()));
346 bool success = script->evaluate(ScriptSourceCode(sourceCode, scriptURL), nul lptr, handler.get(), v8CacheOptions); 346 bool success = script->evaluate(ScriptSourceCode(sourceCode, scriptURL), nul lptr, handler.get(), v8CacheOptions);
347 m_workerGlobalScope->didEvaluateWorkerScript(); 347 m_workerGlobalScope->didEvaluateWorkerScript();
348 m_workerReportingProxy.didEvaluateWorkerScript(success); 348 m_workerReportingProxy.didEvaluateWorkerScript(success);
349 349
350 postInitialize(); 350 postInitialize();
351 351
352 postDelayedTask(FROM_HERE, createSameThreadTask(&WorkerThread::idleHandler, this), kShortIdleHandlerDelayMs); 352 postDelayedTask(FROM_HERE, createSameThreadTask(&WorkerThread::idleHandler, this), kShortIdleHandlerDelayMs);
353 } 353 }
354 354
355 PassOwnPtr<WebThreadSupportingGC> WorkerThread::createWebThreadSupportingGC()
356 {
357 return WebThreadSupportingGC::create(m_threadName);
358 }
359
360 void WorkerThread::cleanup() 355 void WorkerThread::cleanup()
361 { 356 {
362 // This should be called before we start the shutdown procedure. 357 // This should be called before we start the shutdown procedure.
363 workerReportingProxy().willDestroyWorkerGlobalScope(); 358 workerReportingProxy().willDestroyWorkerGlobalScope();
364 359
365 // The below assignment will destroy the context, which will in turn notify messaging proxy. 360 // 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. 361 // 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. 362 // 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) 363 #if !ENABLE(OILPAN)
369 ASSERT(m_workerGlobalScope->hasOneRef()); 364 ASSERT(m_workerGlobalScope->hasOneRef());
370 #endif 365 #endif
371 m_workerGlobalScope->notifyContextDestroyed(); 366 m_workerGlobalScope->notifyContextDestroyed();
372 m_workerGlobalScope = nullptr; 367 m_workerGlobalScope = nullptr;
373 368
374 m_thread->detachGC(); 369 backingThread().detachGC();
375 destroyIsolate(); 370 destroyIsolate();
376 371
377 m_thread->removeTaskObserver(m_microtaskRunner.get()); 372 backingThread().removeTaskObserver(m_microtaskRunner.get());
378 m_microtaskRunner = nullptr; 373 m_microtaskRunner = nullptr;
379 374
380 // Notify the proxy that the WorkerGlobalScope has been disposed of. 375 // Notify the proxy that the WorkerGlobalScope has been disposed of.
381 // This can free this thread object, hence it must not be touched afterwards . 376 // This can free this thread object, hence it must not be touched afterwards .
382 workerReportingProxy().workerThreadTerminated(); 377 workerReportingProxy().workerThreadTerminated();
383 378
384 m_terminationEvent->signal(); 379 m_terminationEvent->signal();
385 380
386 // Clean up PlatformThreadData before WTF::WTFThreadData goes away! 381 // Clean up PlatformThreadData before WTF::WTFThreadData goes away!
387 PlatformThreadData::current().destroy(); 382 PlatformThreadData::current().destroy();
388 } 383 }
389 384
390 class WorkerThreadShutdownFinishTask : public ExecutionContextTask { 385 class WorkerThreadShutdownFinishTask : public ExecutionContextTask {
391 public: 386 public:
392 static PassOwnPtr<WorkerThreadShutdownFinishTask> create() 387 static PassOwnPtr<WorkerThreadShutdownFinishTask> create()
393 { 388 {
394 return adoptPtr(new WorkerThreadShutdownFinishTask()); 389 return adoptPtr(new WorkerThreadShutdownFinishTask());
395 } 390 }
396 391
397 virtual void performTask(ExecutionContext *context) 392 virtual void performTask(ExecutionContext *context)
398 { 393 {
399 WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context); 394 WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context);
400 workerGlobalScope->dispose(); 395 workerGlobalScope->dispose();
401 396
402 WorkerThread* workerThread = workerGlobalScope->thread(); 397 WorkerThread* workerThread = workerGlobalScope->thread();
403 workerThread->willDestroyIsolate(); 398 workerThread->willDestroyIsolate();
404 workerThread->m_thread->postTask(FROM_HERE, new Task(WTF::bind(&WorkerTh read::cleanup, workerThread))); 399 workerThread->backingThread().postTask(FROM_HERE, new Task(WTF::bind(&Wo rkerThread::cleanup, workerThread)));
405 } 400 }
406 401
407 virtual bool isCleanupTask() const { return true; } 402 virtual bool isCleanupTask() const { return true; }
408 }; 403 };
409 404
410 class WorkerThreadShutdownStartTask : public ExecutionContextTask { 405 class WorkerThreadShutdownStartTask : public ExecutionContextTask {
411 public: 406 public:
412 static PassOwnPtr<WorkerThreadShutdownStartTask> create() 407 static PassOwnPtr<WorkerThreadShutdownStartTask> create()
413 { 408 {
414 return adoptPtr(new WorkerThreadShutdownStartTask()); 409 return adoptPtr(new WorkerThreadShutdownStartTask());
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 // Keep this lock to prevent WorkerThread instances from being destroyed. 493 // Keep this lock to prevent WorkerThread instances from being destroyed.
499 MutexLocker lock(threadSetMutex()); 494 MutexLocker lock(threadSetMutex());
500 HashSet<WorkerThread*> threads = workerThreads(); 495 HashSet<WorkerThread*> threads = workerThreads();
501 for (WorkerThread* thread : threads) 496 for (WorkerThread* thread : threads)
502 thread->stopInShutdownSequence(); 497 thread->stopInShutdownSequence();
503 498
504 for (WorkerThread* thread : threads) 499 for (WorkerThread* thread : threads)
505 thread->terminationEvent()->wait(); 500 thread->terminationEvent()->wait();
506 } 501 }
507 502
508 bool WorkerThread::isCurrentThread() const 503 bool WorkerThread::isCurrentThread()
509 { 504 {
510 return m_thread && m_thread->isCurrentThread(); 505 return m_started && backingThread().isCurrentThread();
511 } 506 }
512 507
513 void WorkerThread::idleHandler() 508 void WorkerThread::idleHandler()
514 { 509 {
515 ASSERT(m_workerGlobalScope.get()); 510 ASSERT(m_workerGlobalScope.get());
516 int64_t delay = kLongIdleHandlerDelayMs; 511 int64_t delay = kLongIdleHandlerDelayMs;
517 512
518 // Do a script engine idle notification if the next event is distant enough. 513 // Do a script engine idle notification if the next event is distant enough.
519 const double kMinIdleTimespan = 0.3; 514 const double kMinIdleTimespan = 0.3;
520 const double nextFireTime = PlatformThreadData::current().threadTimers().nex tFireTime(); 515 const double nextFireTime = PlatformThreadData::current().threadTimers().nex tFireTime();
521 if (nextFireTime == 0.0 || nextFireTime > currentTime() + kMinIdleTimespan) { 516 if (nextFireTime == 0.0 || nextFireTime > currentTime() + kMinIdleTimespan) {
522 bool hasMoreWork = !isolate()->IdleNotificationDeadline(Platform::curren t()->monotonicallyIncreasingTime() + 1.0); 517 bool hasMoreWork = !isolate()->IdleNotificationDeadline(Platform::curren t()->monotonicallyIncreasingTime() + 1.0);
523 if (hasMoreWork) 518 if (hasMoreWork)
524 delay = kShortIdleHandlerDelayMs; 519 delay = kShortIdleHandlerDelayMs;
525 } 520 }
526 521
527 postDelayedTask(FROM_HERE, createSameThreadTask(&WorkerThread::idleHandler, this), delay); 522 postDelayedTask(FROM_HERE, createSameThreadTask(&WorkerThread::idleHandler, this), delay);
528 } 523 }
529 524
530 void WorkerThread::postTask(const WebTraceLocation& location, PassOwnPtr<Executi onContextTask> task) 525 void WorkerThread::postTask(const WebTraceLocation& location, PassOwnPtr<Executi onContextTask> task)
531 { 526 {
532 m_thread->postTask(location, WorkerThreadTask::create(*this, task, true).lea kPtr()); 527 backingThread().postTask(location, WorkerThreadTask::create(*this, task, tru e).leakPtr());
533 } 528 }
534 529
535 void WorkerThread::postDelayedTask(const WebTraceLocation& location, PassOwnPtr< ExecutionContextTask> task, long long delayMs) 530 void WorkerThread::postDelayedTask(const WebTraceLocation& location, PassOwnPtr< ExecutionContextTask> task, long long delayMs)
536 { 531 {
537 m_thread->postDelayedTask(location, WorkerThreadTask::create(*this, task, tr ue).leakPtr(), delayMs); 532 backingThread().postDelayedTask(location, WorkerThreadTask::create(*this, ta sk, true).leakPtr(), delayMs);
538 } 533 }
539 534
540 v8::Isolate* WorkerThread::initializeIsolate() 535 v8::Isolate* WorkerThread::initializeIsolate()
541 { 536 {
542 ASSERT(isCurrentThread()); 537 ASSERT(isCurrentThread());
543 ASSERT(!m_isolate); 538 ASSERT(!m_isolate);
544 v8::Isolate* isolate = V8PerIsolateData::initialize(); 539 v8::Isolate* isolate = V8PerIsolateData::initialize();
545 V8Initializer::initializeWorker(isolate); 540 V8Initializer::initializeWorker(isolate);
546 541
547 m_interruptor = adoptPtr(new V8IsolateInterruptor(isolate)); 542 m_interruptor = adoptPtr(new V8IsolateInterruptor(isolate));
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get()); 606 InspectorInstrumentation::didLeaveNestedRunLoop(m_workerGlobalScope.get());
612 } 607 }
613 608
614 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke rInspectorController) 609 void WorkerThread::setWorkerInspectorController(WorkerInspectorController* worke rInspectorController)
615 { 610 {
616 MutexLocker locker(m_workerInspectorControllerMutex); 611 MutexLocker locker(m_workerInspectorControllerMutex);
617 m_workerInspectorController = workerInspectorController; 612 m_workerInspectorController = workerInspectorController;
618 } 613 }
619 614
620 } // namespace blink 615 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/workers/WorkerThread.h ('k') | Source/modules/compositorworker/CompositorWorkerThread.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698