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

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

Issue 2831843002: Revert of Worker: Introduce per-global-scope task scheduler (Closed)
Patch Set: Created 3 years, 8 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
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 13 matching lines...) Expand all
24 * 24 *
25 */ 25 */
26 26
27 #include "core/workers/WorkerThread.h" 27 #include "core/workers/WorkerThread.h"
28 28
29 #include <limits.h> 29 #include <limits.h>
30 #include <memory> 30 #include <memory>
31 #include "bindings/core/v8/Microtask.h" 31 #include "bindings/core/v8/Microtask.h"
32 #include "bindings/core/v8/ScriptSourceCode.h" 32 #include "bindings/core/v8/ScriptSourceCode.h"
33 #include "bindings/core/v8/WorkerOrWorkletScriptController.h" 33 #include "bindings/core/v8/WorkerOrWorkletScriptController.h"
34 #include "core/dom/TaskRunnerHelper.h"
35 #include "core/inspector/ConsoleMessageStorage.h" 34 #include "core/inspector/ConsoleMessageStorage.h"
36 #include "core/inspector/InspectorTaskRunner.h" 35 #include "core/inspector/InspectorTaskRunner.h"
37 #include "core/inspector/WorkerInspectorController.h" 36 #include "core/inspector/WorkerInspectorController.h"
38 #include "core/inspector/WorkerThreadDebugger.h" 37 #include "core/inspector/WorkerThreadDebugger.h"
39 #include "core/origin_trials/OriginTrialContext.h" 38 #include "core/origin_trials/OriginTrialContext.h"
40 #include "core/probe/CoreProbes.h" 39 #include "core/probe/CoreProbes.h"
41 #include "core/workers/ThreadedWorkletGlobalScope.h" 40 #include "core/workers/ThreadedWorkletGlobalScope.h"
42 #include "core/workers/WorkerBackingThread.h" 41 #include "core/workers/WorkerBackingThread.h"
43 #include "core/workers/WorkerClients.h" 42 #include "core/workers/WorkerClients.h"
44 #include "core/workers/WorkerGlobalScope.h" 43 #include "core/workers/WorkerGlobalScope.h"
45 #include "core/workers/WorkerReportingProxy.h" 44 #include "core/workers/WorkerReportingProxy.h"
46 #include "core/workers/WorkerThreadStartupData.h" 45 #include "core/workers/WorkerThreadStartupData.h"
47 #include "platform/CrossThreadFunctional.h" 46 #include "platform/CrossThreadFunctional.h"
48 #include "platform/Histogram.h" 47 #include "platform/Histogram.h"
49 #include "platform/WaitableEvent.h" 48 #include "platform/WaitableEvent.h"
50 #include "platform/WebThreadSupportingGC.h" 49 #include "platform/WebThreadSupportingGC.h"
51 #include "platform/heap/SafePoint.h" 50 #include "platform/heap/SafePoint.h"
52 #include "platform/heap/ThreadState.h" 51 #include "platform/heap/ThreadState.h"
53 #include "platform/scheduler/child/webthread_impl_for_worker_scheduler.h"
54 #include "platform/scheduler/child/worker_global_scope_scheduler.h"
55 #include "platform/weborigin/KURL.h" 52 #include "platform/weborigin/KURL.h"
56 #include "platform/wtf/Functional.h" 53 #include "platform/wtf/Functional.h"
57 #include "platform/wtf/Noncopyable.h" 54 #include "platform/wtf/Noncopyable.h"
58 #include "platform/wtf/PtrUtil.h" 55 #include "platform/wtf/PtrUtil.h"
59 #include "platform/wtf/Threading.h" 56 #include "platform/wtf/Threading.h"
60 #include "platform/wtf/text/WTFString.h" 57 #include "platform/wtf/text/WTFString.h"
61 58
62 namespace blink { 59 namespace blink {
63 60
64 using ExitCode = WorkerThread::ExitCode; 61 using ExitCode = WorkerThread::ExitCode;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 DEFINE_THREAD_SAFE_STATIC_LOCAL( 100 DEFINE_THREAD_SAFE_STATIC_LOCAL(
104 EnumerationHistogram, exit_code_histogram, 101 EnumerationHistogram, exit_code_histogram,
105 new EnumerationHistogram("WorkerThread.ExitCode", 102 new EnumerationHistogram("WorkerThread.ExitCode",
106 static_cast<int>(ExitCode::kLastEnum))); 103 static_cast<int>(ExitCode::kLastEnum)));
107 exit_code_histogram.Count(static_cast<int>(exit_code_)); 104 exit_code_histogram.Count(static_cast<int>(exit_code_));
108 } 105 }
109 106
110 void WorkerThread::Start(std::unique_ptr<WorkerThreadStartupData> startup_data, 107 void WorkerThread::Start(std::unique_ptr<WorkerThreadStartupData> startup_data,
111 ParentFrameTaskRunners* parent_frame_task_runners) { 108 ParentFrameTaskRunners* parent_frame_task_runners) {
112 DCHECK(IsMainThread()); 109 DCHECK(IsMainThread());
110
113 if (requested_to_start_) 111 if (requested_to_start_)
114 return; 112 return;
115 113
116 requested_to_start_ = true; 114 requested_to_start_ = true;
117 parent_frame_task_runners_ = parent_frame_task_runners; 115 parent_frame_task_runners_ = parent_frame_task_runners;
118
119 // Synchronously initialize the per-global-scope scheduler to prevent someone
120 // from posting a task to the thread before the scheduler is ready.
121 WaitableEvent waitable_event;
122 GetWorkerBackingThread().BackingThread().PostTask(
123 BLINK_FROM_HERE,
124 CrossThreadBind(&WorkerThread::InitializeSchedulerOnWorkerThread,
125 CrossThreadUnretained(this),
126 CrossThreadUnretained(&waitable_event)));
127 waitable_event.Wait();
128
129 GetWorkerBackingThread().BackingThread().PostTask( 116 GetWorkerBackingThread().BackingThread().PostTask(
130 BLINK_FROM_HERE, CrossThreadBind(&WorkerThread::InitializeOnWorkerThread, 117 BLINK_FROM_HERE, CrossThreadBind(&WorkerThread::InitializeOnWorkerThread,
131 CrossThreadUnretained(this), 118 CrossThreadUnretained(this),
132 WTF::Passed(std::move(startup_data)))); 119 WTF::Passed(std::move(startup_data))));
133 } 120 }
134 121
135 void WorkerThread::Terminate() { 122 void WorkerThread::Terminate() {
136 DCHECK(IsMainThread()); 123 DCHECK(IsMainThread());
137 TerminateInternal(TerminationMode::kGraceful); 124 TerminateInternal(TerminationMode::kGraceful);
138 } 125 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 } 183 }
197 184
198 v8::Isolate* WorkerThread::GetIsolate() { 185 v8::Isolate* WorkerThread::GetIsolate() {
199 return GetWorkerBackingThread().GetIsolate(); 186 return GetWorkerBackingThread().GetIsolate();
200 } 187 }
201 188
202 bool WorkerThread::IsCurrentThread() { 189 bool WorkerThread::IsCurrentThread() {
203 return GetWorkerBackingThread().BackingThread().IsCurrentThread(); 190 return GetWorkerBackingThread().BackingThread().IsCurrentThread();
204 } 191 }
205 192
193 void WorkerThread::PostTask(const WebTraceLocation& location,
194 std::unique_ptr<WTF::Closure> task) {
195 DCHECK(IsCurrentThread());
196 if (IsInShutdown())
197 return;
198 GetWorkerBackingThread().BackingThread().PostTask(
199 location,
200 WTF::Bind(
201 &WorkerThread::PerformTaskOnWorkerThread<WTF::kSameThreadAffinity>,
202 WTF::Unretained(this), WTF::Passed(std::move(task))));
203 }
204
205 void WorkerThread::PostTask(const WebTraceLocation& location,
206 std::unique_ptr<WTF::CrossThreadClosure> task) {
207 if (IsInShutdown())
208 return;
209 GetWorkerBackingThread().BackingThread().PostTask(
210 location,
211 CrossThreadBind(
212 &WorkerThread::PerformTaskOnWorkerThread<WTF::kCrossThreadAffinity>,
213 CrossThreadUnretained(this), WTF::Passed(std::move(task))));
214 }
215
206 void WorkerThread::AppendDebuggerTask( 216 void WorkerThread::AppendDebuggerTask(
207 std::unique_ptr<CrossThreadClosure> task) { 217 std::unique_ptr<CrossThreadClosure> task) {
208 DCHECK(IsMainThread()); 218 DCHECK(IsMainThread());
209 if (requested_to_terminate_) 219 if (IsInShutdown())
210 return; 220 return;
211 inspector_task_runner_->AppendTask(CrossThreadBind( 221 inspector_task_runner_->AppendTask(CrossThreadBind(
212 &WorkerThread::PerformDebuggerTaskOnWorkerThread, 222 &WorkerThread::PerformDebuggerTaskOnWorkerThread,
213 CrossThreadUnretained(this), WTF::Passed(std::move(task)))); 223 CrossThreadUnretained(this), WTF::Passed(std::move(task))));
214 { 224 {
215 MutexLocker lock(thread_state_mutex_); 225 MutexLocker lock(thread_state_mutex_);
216 if (GetIsolate() && thread_state_ != ThreadState::kReadyToShutdown) 226 if (GetIsolate() && thread_state_ != ThreadState::kReadyToShutdown)
217 inspector_task_runner_->InterruptAndRunAllTasksDontWait(GetIsolate()); 227 inspector_task_runner_->InterruptAndRunAllTasksDontWait(GetIsolate());
218 } 228 }
219 TaskRunnerHelper::Get(TaskType::kUnthrottled, this) 229 GetWorkerBackingThread().BackingThread().PostTask(
220 ->PostTask(BLINK_FROM_HERE, 230 BLINK_FROM_HERE,
221 CrossThreadBind( 231 CrossThreadBind(&WorkerThread::PerformDebuggerTaskDontWaitOnWorkerThread,
222 &WorkerThread::PerformDebuggerTaskDontWaitOnWorkerThread, 232 CrossThreadUnretained(this)));
223 CrossThreadUnretained(this)));
224 } 233 }
225 234
226 void WorkerThread::StartRunningDebuggerTasksOnPauseOnWorkerThread() { 235 void WorkerThread::StartRunningDebuggerTasksOnPauseOnWorkerThread() {
227 DCHECK(IsCurrentThread()); 236 DCHECK(IsCurrentThread());
228 if (worker_inspector_controller_) 237 if (worker_inspector_controller_)
229 worker_inspector_controller_->FlushProtocolNotifications(); 238 worker_inspector_controller_->FlushProtocolNotifications();
230 paused_in_debugger_ = true; 239 paused_in_debugger_ = true;
231 ThreadDebugger::IdleStarted(GetIsolate()); 240 ThreadDebugger::IdleStarted(GetIsolate());
232 std::unique_ptr<CrossThreadClosure> task; 241 std::unique_ptr<CrossThreadClosure> task;
233 do { 242 do {
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 DCHECK(IsThreadStateMutexLocked(lock)); 423 DCHECK(IsThreadStateMutexLocked(lock));
415 424
416 DCHECK(exit_code == ExitCode::kSyncForciblyTerminated || 425 DCHECK(exit_code == ExitCode::kSyncForciblyTerminated ||
417 exit_code == ExitCode::kAsyncForciblyTerminated); 426 exit_code == ExitCode::kAsyncForciblyTerminated);
418 SetExitCode(lock, exit_code); 427 SetExitCode(lock, exit_code);
419 428
420 GetIsolate()->TerminateExecution(); 429 GetIsolate()->TerminateExecution();
421 forcible_termination_task_handle_.Cancel(); 430 forcible_termination_task_handle_.Cancel();
422 } 431 }
423 432
424 void WorkerThread::InitializeSchedulerOnWorkerThread( 433 bool WorkerThread::IsInShutdown() {
425 WaitableEvent* waitable_event) { 434 // Check if we've started termination or shutdown sequence. Avoid acquiring
426 DCHECK(IsCurrentThread()); 435 // a lock here to avoid introducing a risk of deadlock. Note that accessing
427 DCHECK(!global_scope_scheduler_); 436 // |m_requestedToTerminate| on the main thread or |m_threadState| on the
428 scheduler::WebThreadImplForWorkerScheduler& web_thread_for_worker = 437 // worker thread is safe as the flag is set only on the thread.
429 static_cast<scheduler::WebThreadImplForWorkerScheduler&>( 438 if (IsMainThread() && requested_to_terminate_)
430 GetWorkerBackingThread().BackingThread().PlatformThread()); 439 return true;
431 global_scope_scheduler_ = 440 if (IsCurrentThread() && thread_state_ == ThreadState::kReadyToShutdown)
432 WTF::MakeUnique<scheduler::WorkerGlobalScopeScheduler>( 441 return true;
433 web_thread_for_worker.GetWorkerScheduler()); 442 return false;
434 waitable_event->Signal();
435 } 443 }
436 444
437 void WorkerThread::InitializeOnWorkerThread( 445 void WorkerThread::InitializeOnWorkerThread(
438 std::unique_ptr<WorkerThreadStartupData> startup_data) { 446 std::unique_ptr<WorkerThreadStartupData> startup_data) {
439 DCHECK(IsCurrentThread()); 447 DCHECK(IsCurrentThread());
440 DCHECK_EQ(ThreadState::kNotStarted, thread_state_); 448 DCHECK_EQ(ThreadState::kNotStarted, thread_state_);
441 449
442 KURL script_url = startup_data->script_url_; 450 KURL script_url = startup_data->script_url_;
443 String source_code = startup_data->source_code_; 451 String source_code = startup_data->source_code_;
444 WorkerThreadStartMode start_mode = startup_data->start_mode_; 452 WorkerThreadStartMode start_mode = startup_data->start_mode_;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 inspector_task_runner_->Kill(); 529 inspector_task_runner_->Kill();
522 GetWorkerReportingProxy().WillDestroyWorkerGlobalScope(); 530 GetWorkerReportingProxy().WillDestroyWorkerGlobalScope();
523 probe::AllAsyncTasksCanceled(GlobalScope()); 531 probe::AllAsyncTasksCanceled(GlobalScope());
524 532
525 GlobalScope()->NotifyContextDestroyed(); 533 GlobalScope()->NotifyContextDestroyed();
526 if (worker_inspector_controller_) { 534 if (worker_inspector_controller_) {
527 worker_inspector_controller_->Dispose(); 535 worker_inspector_controller_->Dispose();
528 worker_inspector_controller_.Clear(); 536 worker_inspector_controller_.Clear();
529 } 537 }
530 GlobalScope()->Dispose(); 538 GlobalScope()->Dispose();
531 global_scope_scheduler_->Dispose();
532 console_message_storage_.Clear(); 539 console_message_storage_.Clear();
533 GetWorkerBackingThread().BackingThread().RemoveTaskObserver(this); 540 GetWorkerBackingThread().BackingThread().RemoveTaskObserver(this);
534 } 541 }
535 542
536 void WorkerThread::PerformShutdownOnWorkerThread() { 543 void WorkerThread::PerformShutdownOnWorkerThread() {
537 DCHECK(IsCurrentThread()); 544 DCHECK(IsCurrentThread());
538 DCHECK(CheckRequestedToTerminateOnWorkerThread()); 545 DCHECK(CheckRequestedToTerminateOnWorkerThread());
539 DCHECK_EQ(ThreadState::kReadyToShutdown, thread_state_); 546 DCHECK_EQ(ThreadState::kReadyToShutdown, thread_state_);
540 547
541 // The below assignment will destroy the context, which will in turn notify 548 // The below assignment will destroy the context, which will in turn notify
542 // messaging proxy. We cannot let any objects survive past thread exit, 549 // messaging proxy. We cannot let any objects survive past thread exit,
543 // because no other thread will run GC or otherwise destroy them. If Oilpan 550 // because no other thread will run GC or otherwise destroy them. If Oilpan
544 // is enabled, we detach of the context/global scope, with the final heap 551 // is enabled, we detach of the context/global scope, with the final heap
545 // cleanup below sweeping it out. 552 // cleanup below sweeping it out.
546 global_scope_ = nullptr; 553 global_scope_ = nullptr;
547 554
548 if (IsOwningBackingThread()) 555 if (IsOwningBackingThread())
549 GetWorkerBackingThread().Shutdown(); 556 GetWorkerBackingThread().Shutdown();
550 // We must not touch workerBackingThread() from now on. 557 // We must not touch workerBackingThread() from now on.
551 558
552 // Notify the proxy that the WorkerOrWorkletGlobalScope has been disposed 559 // Notify the proxy that the WorkerOrWorkletGlobalScope has been disposed
553 // of. This can free this thread object, hence it must not be touched 560 // of. This can free this thread object, hence it must not be touched
554 // afterwards. 561 // afterwards.
555 GetWorkerReportingProxy().DidTerminateWorkerThread(); 562 GetWorkerReportingProxy().DidTerminateWorkerThread();
556 563
557 shutdown_event_->Signal(); 564 shutdown_event_->Signal();
558 } 565 }
559 566
567 template <WTF::FunctionThreadAffinity threadAffinity>
568 void WorkerThread::PerformTaskOnWorkerThread(
569 std::unique_ptr<Function<void(), threadAffinity>> task) {
570 DCHECK(IsCurrentThread());
571 if (thread_state_ != ThreadState::kRunning)
572 return;
573
574 {
575 DEFINE_THREAD_SAFE_STATIC_LOCAL(
576 CustomCountHistogram, scoped_us_counter,
577 new CustomCountHistogram("WorkerThread.Task.Time", 0, 10000000, 50));
578 ScopedUsHistogramTimer timer(scoped_us_counter);
579 (*task)();
580 }
581 }
582
560 void WorkerThread::PerformDebuggerTaskOnWorkerThread( 583 void WorkerThread::PerformDebuggerTaskOnWorkerThread(
561 std::unique_ptr<CrossThreadClosure> task) { 584 std::unique_ptr<CrossThreadClosure> task) {
562 DCHECK(IsCurrentThread()); 585 DCHECK(IsCurrentThread());
563 InspectorTaskRunner::IgnoreInterruptsScope scope( 586 InspectorTaskRunner::IgnoreInterruptsScope scope(
564 inspector_task_runner_.get()); 587 inspector_task_runner_.get());
565 { 588 {
566 MutexLocker lock(thread_state_mutex_); 589 MutexLocker lock(thread_state_mutex_);
567 DCHECK_EQ(ThreadState::kRunning, thread_state_); 590 DCHECK_EQ(ThreadState::kRunning, thread_state_);
568 running_debugger_task_ = true; 591 running_debugger_task_ = true;
569 } 592 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 MutexLocker lock(thread_state_mutex_); 659 MutexLocker lock(thread_state_mutex_);
637 return requested_to_terminate_; 660 return requested_to_terminate_;
638 } 661 }
639 662
640 ExitCode WorkerThread::GetExitCodeForTesting() { 663 ExitCode WorkerThread::GetExitCodeForTesting() {
641 MutexLocker lock(thread_state_mutex_); 664 MutexLocker lock(thread_state_mutex_);
642 return exit_code_; 665 return exit_code_;
643 } 666 }
644 667
645 } // namespace blink 668 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698