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