Home | History | Annotate | Download | only in html_viewer
      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 
     19 WebThreadBase::WebThreadBase() {}
     20 WebThreadBase::~WebThreadBase() {}
     21 
     22 class WebThreadBase::TaskObserverAdapter
     23     : public base::MessageLoop::TaskObserver {
     24  public:
     25   TaskObserverAdapter(WebThread::TaskObserver* observer)
     26       : observer_(observer) {}
     27 
     28   virtual void WillProcessTask(const base::PendingTask& pending_task) OVERRIDE {
     29     observer_->willProcessTask();
     30   }
     31 
     32   virtual void DidProcessTask(const base::PendingTask& pending_task) OVERRIDE {
     33     observer_->didProcessTask();
     34   }
     35 
     36 private:
     37   WebThread::TaskObserver* observer_;
     38 };
     39 
     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 
     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 
     59 WebThreadImpl::WebThreadImpl(const char* name)
     60     : thread_(new base::Thread(name)) {
     61   thread_->Start();
     62 }
     63 
     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 
     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 
     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 
     82 void WebThreadImpl::exitRunLoop() {
     83   CHECK(isCurrentThread());
     84   CHECK(thread_->message_loop()->is_running());
     85   thread_->message_loop()->Quit();
     86 }
     87 
     88 bool WebThreadImpl::isCurrentThread() const {
     89   return thread_->thread_id() == base::PlatformThread::CurrentId();
     90 }
     91 
     92 WebThreadImpl::~WebThreadImpl() {
     93   thread_->Stop();
     94 }
     95 
     96 WebThreadImplForMessageLoop::WebThreadImplForMessageLoop(
     97     base::MessageLoopProxy* message_loop)
     98     : message_loop_(message_loop) {}
     99 
    100 void WebThreadImplForMessageLoop::postTask(Task* task) {
    101   message_loop_->PostTask(
    102       FROM_HERE, base::Bind(&blink::WebThread::Task::run, base::Owned(task)));
    103 }
    104 
    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 
    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 
    120 void WebThreadImplForMessageLoop::exitRunLoop() {
    121   CHECK(isCurrentThread());
    122   CHECK(base::MessageLoop::current()->is_running());
    123   base::MessageLoop::current()->Quit();
    124 }
    125 
    126 bool WebThreadImplForMessageLoop::isCurrentThread() const {
    127   return message_loop_->BelongsToCurrentThread();
    128 }
    129 
    130 WebThreadImplForMessageLoop::~WebThreadImplForMessageLoop() {}
    131 
    132 }  // namespace examples
    133 }  // namespace mojo
    134