| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "remoting/base/auto_thread.h" | 5 #include "remoting/base/auto_thread.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback.h" |
| 8 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
| 10 #include "base/logging.h" |
| 9 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
| 10 #include "base/synchronization/waitable_event.h" | 12 #include "base/synchronization/waitable_event.h" |
| 11 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | 13 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" |
| 12 #include "base/threading/thread_local.h" | 14 #include "base/threading/thread_local.h" |
| 13 #include "base/threading/thread_restrictions.h" | 15 #include "base/threading/thread_restrictions.h" |
| 14 #include "build/build_config.h" | 16 #include "build/build_config.h" |
| 15 #include "remoting/base/auto_thread_task_runner.h" | 17 #include "remoting/base/auto_thread_task_runner.h" |
| 16 | 18 |
| 17 #if defined(OS_WIN) | 19 #if defined(OS_WIN) |
| 18 #include "base/win/scoped_com_initializer.h" | 20 #include "base/win/scoped_com_initializer.h" |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 #endif | 94 #endif |
| 93 | 95 |
| 94 AutoThread::AutoThread(const char* name) | 96 AutoThread::AutoThread(const char* name) |
| 95 : startup_data_(NULL), | 97 : startup_data_(NULL), |
| 96 #if defined(OS_WIN) | 98 #if defined(OS_WIN) |
| 97 com_init_type_(COM_INIT_NONE), | 99 com_init_type_(COM_INIT_NONE), |
| 98 #endif | 100 #endif |
| 99 thread_(), | 101 thread_(), |
| 100 name_(name), | 102 name_(name), |
| 101 was_quit_properly_(false) { | 103 was_quit_properly_(false) { |
| 104 thread_checker_.DetachFromThread(); |
| 102 } | 105 } |
| 103 | 106 |
| 104 AutoThread::AutoThread(const char* name, AutoThreadTaskRunner* joiner) | 107 AutoThread::AutoThread(const char* name, AutoThreadTaskRunner* joiner) |
| 105 : startup_data_(NULL), | 108 : startup_data_(NULL), |
| 106 #if defined(OS_WIN) | 109 #if defined(OS_WIN) |
| 107 com_init_type_(COM_INIT_NONE), | 110 com_init_type_(COM_INIT_NONE), |
| 108 #endif | 111 #endif |
| 109 thread_(), | 112 thread_(), |
| 110 name_(name), | 113 name_(name), |
| 111 was_quit_properly_(false), | 114 was_quit_properly_(false), |
| 112 joiner_(joiner) { | 115 joiner_(joiner) { |
| 116 thread_checker_.DetachFromThread(); |
| 113 } | 117 } |
| 114 | 118 |
| 115 AutoThread::~AutoThread() { | 119 AutoThread::~AutoThread() { |
| 116 DCHECK(!startup_data_); | 120 DCHECK(!startup_data_); |
| 117 | 121 |
| 118 // Wait for the thread to exit. | 122 // Wait for the thread to exit. |
| 119 if (!thread_.is_null()) { | 123 if (!thread_.is_null()) { |
| 120 base::PlatformThread::Join(thread_); | 124 base::PlatformThread::Join(thread_); |
| 121 } | 125 } |
| 122 } | 126 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 152 return startup_data.task_runner; | 156 return startup_data.task_runner; |
| 153 } | 157 } |
| 154 | 158 |
| 155 #if defined(OS_WIN) | 159 #if defined(OS_WIN) |
| 156 void AutoThread::SetComInitType(ComInitType com_init_type) { | 160 void AutoThread::SetComInitType(ComInitType com_init_type) { |
| 157 DCHECK_EQ(com_init_type_, COM_INIT_NONE); | 161 DCHECK_EQ(com_init_type_, COM_INIT_NONE); |
| 158 com_init_type_ = com_init_type; | 162 com_init_type_ = com_init_type; |
| 159 } | 163 } |
| 160 #endif | 164 #endif |
| 161 | 165 |
| 162 void AutoThread::QuitThread( | 166 void AutoThread::QuitThread(const base::Closure& quit_when_idle_closure) { |
| 163 scoped_refptr<base::SingleThreadTaskRunner> task_runner) { | 167 DCHECK(thread_checker_.CalledOnValidThread()); |
| 164 if (!task_runner->BelongsToCurrentThread()) { | |
| 165 task_runner->PostTask(FROM_HERE, base::Bind(&AutoThread::QuitThread, | |
| 166 base::Unretained(this), | |
| 167 task_runner)); | |
| 168 return; | |
| 169 } | |
| 170 | 168 |
| 171 base::MessageLoop::current()->QuitWhenIdle(); | 169 quit_when_idle_closure.Run(); |
| 172 was_quit_properly_ = true; | 170 was_quit_properly_ = true; |
| 173 | 171 |
| 174 if (joiner_.get()) { | 172 if (joiner_.get()) { |
| 175 joiner_->PostTask( | 173 joiner_->PostTask( |
| 176 FROM_HERE, | 174 FROM_HERE, |
| 177 base::Bind(&AutoThread::JoinAndDeleteThread, base::Unretained(this))); | 175 base::Bind(&AutoThread::JoinAndDeleteThread, base::Unretained(this))); |
| 178 } | 176 } |
| 179 } | 177 } |
| 180 | 178 |
| 181 void AutoThread::JoinAndDeleteThread() { | 179 void AutoThread::JoinAndDeleteThread() { |
| 182 delete this; | 180 delete this; |
| 183 } | 181 } |
| 184 | 182 |
| 185 void AutoThread::ThreadMain() { | 183 void AutoThread::ThreadMain() { |
| 186 // The message loop for this thread. | 184 // Bind |thread_checker_| to the current thread. |
| 185 DCHECK(thread_checker_.CalledOnValidThread()); |
| 186 |
| 187 base::MessageLoop message_loop(startup_data_->loop_type); | 187 base::MessageLoop message_loop(startup_data_->loop_type); |
| 188 base::RunLoop run_loop; |
| 188 | 189 |
| 189 // Complete the initialization of our AutoThread object. | 190 // Complete the initialization of our AutoThread object. |
| 190 base::PlatformThread::SetName(name_); | 191 base::PlatformThread::SetName(name_); |
| 191 ANNOTATE_THREAD_NAME(name_.c_str()); // Tell the name to race detector. | 192 ANNOTATE_THREAD_NAME(name_.c_str()); // Tell the name to race detector. |
| 192 | 193 |
| 193 // Return an AutoThreadTaskRunner that will cleanly quit this thread when | 194 // Return an AutoThreadTaskRunner that will cleanly quit this thread when |
| 194 // no more references to it remain. | 195 // no more references to it remain. |
| 195 startup_data_->task_runner = | 196 startup_data_->task_runner = new AutoThreadTaskRunner( |
| 196 new AutoThreadTaskRunner(message_loop.task_runner(), | 197 message_loop.task_runner(), |
| 197 base::Bind(&AutoThread::QuitThread, | 198 base::Bind(&AutoThread::QuitThread, base::Unretained(this), |
| 198 base::Unretained(this), | 199 run_loop.QuitWhenIdleClosure())); |
| 199 message_loop.task_runner())); | |
| 200 | 200 |
| 201 startup_data_->event.Signal(); | 201 startup_data_->event.Signal(); |
| 202 // startup_data_ can't be touched anymore since the starting thread is now | 202 // startup_data_ can't be touched anymore since the starting thread is now |
| 203 // unlocked. | 203 // unlocked. |
| 204 | 204 |
| 205 #if defined(OS_WIN) | 205 #if defined(OS_WIN) |
| 206 // Initialize COM on the thread, if requested. | 206 // Initialize COM on the thread, if requested. |
| 207 std::unique_ptr<base::win::ScopedCOMInitializer> com_initializer( | 207 std::unique_ptr<base::win::ScopedCOMInitializer> com_initializer( |
| 208 CreateComInitializer(com_init_type_)); | 208 CreateComInitializer(com_init_type_)); |
| 209 #endif | 209 #endif |
| 210 | 210 |
| 211 base::RunLoop().Run(); | 211 run_loop.Run(); |
| 212 | 212 |
| 213 // Assert that MessageLoop::QuitWhenIdle was called by AutoThread::QuitThread. | 213 // Assert that MessageLoop::QuitWhenIdle was called by AutoThread::QuitThread. |
| 214 DCHECK(was_quit_properly_); | 214 DCHECK(was_quit_properly_); |
| 215 } | 215 } |
| 216 | 216 |
| 217 } // namespace base | 217 } // namespace base |
| OLD | NEW |