• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 // An implementation of WebThread in terms of base::MessageLoop and
6 // base::Thread
7 
8 #include "mojo/examples/html_viewer/webthread_impl.h"
9 
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/pending_task.h"
14 #include "base/threading/platform_thread.h"
15 
16 namespace mojo {
17 namespace examples {
18 
WebThreadBase()19 WebThreadBase::WebThreadBase() {}
~WebThreadBase()20 WebThreadBase::~WebThreadBase() {}
21 
22 class WebThreadBase::TaskObserverAdapter
23     : public base::MessageLoop::TaskObserver {
24  public:
TaskObserverAdapter(WebThread::TaskObserver * observer)25   TaskObserverAdapter(WebThread::TaskObserver* observer)
26       : observer_(observer) {}
27 
WillProcessTask(const base::PendingTask & pending_task)28   virtual void WillProcessTask(const base::PendingTask& pending_task) OVERRIDE {
29     observer_->willProcessTask();
30   }
31 
DidProcessTask(const base::PendingTask & pending_task)32   virtual void DidProcessTask(const base::PendingTask& pending_task) OVERRIDE {
33     observer_->didProcessTask();
34   }
35 
36 private:
37   WebThread::TaskObserver* observer_;
38 };
39 
addTaskObserver(TaskObserver * observer)40 void WebThreadBase::addTaskObserver(TaskObserver* observer) {
41   CHECK(isCurrentThread());
42   std::pair<TaskObserverMap::iterator, bool> result = task_observer_map_.insert(
43       std::make_pair(observer, static_cast<TaskObserverAdapter*>(NULL)));
44   if (result.second)
45     result.first->second = new TaskObserverAdapter(observer);
46   base::MessageLoop::current()->AddTaskObserver(result.first->second);
47 }
48 
removeTaskObserver(TaskObserver * observer)49 void WebThreadBase::removeTaskObserver(TaskObserver* observer) {
50   CHECK(isCurrentThread());
51   TaskObserverMap::iterator iter = task_observer_map_.find(observer);
52   if (iter == task_observer_map_.end())
53     return;
54   base::MessageLoop::current()->RemoveTaskObserver(iter->second);
55   delete iter->second;
56   task_observer_map_.erase(iter);
57 }
58 
WebThreadImpl(const char * name)59 WebThreadImpl::WebThreadImpl(const char* name)
60     : thread_(new base::Thread(name)) {
61   thread_->Start();
62 }
63 
postTask(Task * task)64 void WebThreadImpl::postTask(Task* task) {
65   thread_->message_loop()->PostTask(
66       FROM_HERE, base::Bind(&blink::WebThread::Task::run, base::Owned(task)));
67 }
68 
postDelayedTask(Task * task,long long delay_ms)69 void WebThreadImpl::postDelayedTask(Task* task, long long delay_ms) {
70   thread_->message_loop()->PostDelayedTask(
71       FROM_HERE,
72       base::Bind(&blink::WebThread::Task::run, base::Owned(task)),
73       base::TimeDelta::FromMilliseconds(delay_ms));
74 }
75 
enterRunLoop()76 void WebThreadImpl::enterRunLoop() {
77   CHECK(isCurrentThread());
78   CHECK(!thread_->message_loop()->is_running());  // We don't support nesting.
79   thread_->message_loop()->Run();
80 }
81 
exitRunLoop()82 void WebThreadImpl::exitRunLoop() {
83   CHECK(isCurrentThread());
84   CHECK(thread_->message_loop()->is_running());
85   thread_->message_loop()->Quit();
86 }
87 
isCurrentThread() const88 bool WebThreadImpl::isCurrentThread() const {
89   return thread_->thread_id() == base::PlatformThread::CurrentId();
90 }
91 
~WebThreadImpl()92 WebThreadImpl::~WebThreadImpl() {
93   thread_->Stop();
94 }
95 
WebThreadImplForMessageLoop(base::MessageLoopProxy * message_loop)96 WebThreadImplForMessageLoop::WebThreadImplForMessageLoop(
97     base::MessageLoopProxy* message_loop)
98     : message_loop_(message_loop) {}
99 
postTask(Task * task)100 void WebThreadImplForMessageLoop::postTask(Task* task) {
101   message_loop_->PostTask(
102       FROM_HERE, base::Bind(&blink::WebThread::Task::run, base::Owned(task)));
103 }
104 
postDelayedTask(Task * task,long long delay_ms)105 void WebThreadImplForMessageLoop::postDelayedTask(Task* task,
106                                                   long long delay_ms) {
107   message_loop_->PostDelayedTask(
108       FROM_HERE,
109       base::Bind(&blink::WebThread::Task::run, base::Owned(task)),
110       base::TimeDelta::FromMilliseconds(delay_ms));
111 }
112 
enterRunLoop()113 void WebThreadImplForMessageLoop::enterRunLoop() {
114   CHECK(isCurrentThread());
115   // We don't support nesting.
116   CHECK(!base::MessageLoop::current()->is_running());
117   base::MessageLoop::current()->Run();
118 }
119 
exitRunLoop()120 void WebThreadImplForMessageLoop::exitRunLoop() {
121   CHECK(isCurrentThread());
122   CHECK(base::MessageLoop::current()->is_running());
123   base::MessageLoop::current()->Quit();
124 }
125 
isCurrentThread() const126 bool WebThreadImplForMessageLoop::isCurrentThread() const {
127   return message_loop_->BelongsToCurrentThread();
128 }
129 
~WebThreadImplForMessageLoop()130 WebThreadImplForMessageLoop::~WebThreadImplForMessageLoop() {}
131 
132 }  // namespace examples
133 }  // namespace mojo
134