1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/child/worker_task_runner.h"
7 #include "base/callback.h"
8 #include "base/lazy_instance.h"
9 #include "base/location.h"
10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/observer_list.h"
13 #include "base/single_thread_task_runner.h"
14 #include "base/stl_util.h"
15 #include "base/thread_task_runner_handle.h"
16 #include "content/child/worker_thread_impl.h"
22 // A task-runner that refuses to run any tasks.
23 class DoNothingTaskRunner
: public base::TaskRunner
{
25 DoNothingTaskRunner() {}
28 ~DoNothingTaskRunner() override
{}
30 bool PostDelayedTask(const tracked_objects::Location
& from_here
,
31 const base::Closure
& task
,
32 base::TimeDelta delay
) override
{
36 bool RunsTasksOnCurrentThread() const override
{ return false; }
41 WorkerTaskRunner::WorkerTaskRunner()
42 : task_runner_for_dead_worker_(new DoNothingTaskRunner()) {
45 bool WorkerTaskRunner::PostTask(
46 int id
, const base::Closure
& closure
) {
48 base::AutoLock
locker(task_runner_map_lock_
);
49 IDToTaskRunnerMap::iterator found
= task_runner_map_
.find(id
);
50 if (found
== task_runner_map_
.end())
52 return found
->second
->PostTask(FROM_HERE
, closure
);
55 int WorkerTaskRunner::PostTaskToAllThreads(const base::Closure
& closure
) {
56 base::AutoLock
locker(task_runner_map_lock_
);
57 for (const auto& it
: task_runner_map_
)
58 it
.second
->PostTask(FROM_HERE
, closure
);
59 return static_cast<int>(task_runner_map_
.size());
62 WorkerTaskRunner
* WorkerTaskRunner::Instance() {
63 static base::LazyInstance
<WorkerTaskRunner
>::Leaky
64 worker_task_runner
= LAZY_INSTANCE_INITIALIZER
;
65 return worker_task_runner
.Pointer();
68 WorkerTaskRunner::~WorkerTaskRunner() {
71 void WorkerTaskRunner::DidStartWorkerRunLoop() {
72 DCHECK(!base::PlatformThread::CurrentRef().is_null());
73 // Note: call into WorkerThreadImpl rather than this class observing
74 // WorkerThreadImpl, to ensure that the task runner exists before anybody is
75 // notified that the worker thread has started.
76 WorkerThreadImpl::DidStartCurrentWorkerThread();
77 int id
= base::PlatformThread::CurrentId();
78 base::AutoLock
locker_(task_runner_map_lock_
);
79 task_runner_map_
[id
] = base::ThreadTaskRunnerHandle::Get().get();
80 CHECK(task_runner_map_
[id
]);
83 void WorkerTaskRunner::WillStopWorkerRunLoop() {
84 WorkerThreadImpl::WillStopCurrentWorkerThread();
86 base::AutoLock
locker(task_runner_map_lock_
);
87 task_runner_map_
.erase(WorkerThread::GetCurrentId());
91 base::TaskRunner
* WorkerTaskRunner::GetTaskRunnerFor(int worker_id
) {
92 base::AutoLock
locker(task_runner_map_lock_
);
93 return ContainsKey(task_runner_map_
, worker_id
) ? task_runner_map_
[worker_id
]
94 : task_runner_for_dead_worker_
.get();
97 } // namespace content