| 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/lazy_instance.h" | 8 #include "base/lazy_instance.h" |
| 9 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | 9 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" |
| 10 #include "base/threading/thread_local.h" | 10 #include "base/threading/thread_local.h" |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 return initializer.Pass(); | 33 return initializer.Pass(); |
| 34 } | 34 } |
| 35 #endif | 35 #endif |
| 36 | 36 |
| 37 } | 37 } |
| 38 | 38 |
| 39 // Used to pass data to ThreadMain. This structure is allocated on the stack | 39 // Used to pass data to ThreadMain. This structure is allocated on the stack |
| 40 // from within StartWithType. | 40 // from within StartWithType. |
| 41 struct AutoThread::StartupData { | 41 struct AutoThread::StartupData { |
| 42 // Fields describing the desired thread behaviour. | 42 // Fields describing the desired thread behaviour. |
| 43 MessageLoop::Type loop_type; | 43 base::MessageLoop::Type loop_type; |
| 44 | 44 |
| 45 // Used to receive the AutoThreadTaskRunner for the thread. | 45 // Used to receive the AutoThreadTaskRunner for the thread. |
| 46 scoped_refptr<AutoThreadTaskRunner> task_runner; | 46 scoped_refptr<AutoThreadTaskRunner> task_runner; |
| 47 | 47 |
| 48 // Used to synchronize thread startup. | 48 // Used to synchronize thread startup. |
| 49 base::WaitableEvent event; | 49 base::WaitableEvent event; |
| 50 | 50 |
| 51 explicit StartupData(MessageLoop::Type type) | 51 explicit StartupData(base::MessageLoop::Type type) |
| 52 : loop_type(type), | 52 : loop_type(type), event(false, false) {} |
| 53 event(false, false) {} | |
| 54 }; | 53 }; |
| 55 | 54 |
| 56 // static | 55 // static |
| 57 scoped_refptr<AutoThreadTaskRunner> AutoThread::CreateWithType( | 56 scoped_refptr<AutoThreadTaskRunner> AutoThread::CreateWithType( |
| 58 const char* name, | 57 const char* name, |
| 59 scoped_refptr<AutoThreadTaskRunner> joiner, | 58 scoped_refptr<AutoThreadTaskRunner> joiner, |
| 60 MessageLoop::Type type) { | 59 base::MessageLoop::Type type) { |
| 61 AutoThread* thread = new AutoThread(name, joiner); | 60 AutoThread* thread = new AutoThread(name, joiner); |
| 62 scoped_refptr<AutoThreadTaskRunner> task_runner = thread->StartWithType(type); | 61 scoped_refptr<AutoThreadTaskRunner> task_runner = thread->StartWithType(type); |
| 63 if (!task_runner) | 62 if (!task_runner) |
| 64 delete thread; | 63 delete thread; |
| 65 return task_runner; | 64 return task_runner; |
| 66 } | 65 } |
| 67 | 66 |
| 68 // static | 67 // static |
| 69 scoped_refptr<AutoThreadTaskRunner> AutoThread::Create( | 68 scoped_refptr<AutoThreadTaskRunner> AutoThread::Create( |
| 70 const char* name, scoped_refptr<AutoThreadTaskRunner> joiner) { | 69 const char* name, scoped_refptr<AutoThreadTaskRunner> joiner) { |
| 71 return CreateWithType(name, joiner, MessageLoop::TYPE_DEFAULT); | 70 return CreateWithType(name, joiner, base::MessageLoop::TYPE_DEFAULT); |
| 72 } | 71 } |
| 73 | 72 |
| 74 #if defined(OS_WIN) | 73 #if defined(OS_WIN) |
| 75 // static | 74 // static |
| 76 scoped_refptr<AutoThreadTaskRunner> AutoThread::CreateWithLoopAndComInitTypes( | 75 scoped_refptr<AutoThreadTaskRunner> AutoThread::CreateWithLoopAndComInitTypes( |
| 77 const char* name, | 76 const char* name, |
| 78 scoped_refptr<AutoThreadTaskRunner> joiner, | 77 scoped_refptr<AutoThreadTaskRunner> joiner, |
| 79 MessageLoop::Type loop_type, | 78 base::MessageLoop::Type loop_type, |
| 80 ComInitType com_init_type) { | 79 ComInitType com_init_type) { |
| 81 AutoThread* thread = new AutoThread(name, joiner); | 80 AutoThread* thread = new AutoThread(name, joiner); |
| 82 thread->SetComInitType(com_init_type); | 81 thread->SetComInitType(com_init_type); |
| 83 scoped_refptr<AutoThreadTaskRunner> task_runner = | 82 scoped_refptr<AutoThreadTaskRunner> task_runner = |
| 84 thread->StartWithType(loop_type); | 83 thread->StartWithType(loop_type); |
| 85 if (!task_runner) | 84 if (!task_runner) |
| 86 delete thread; | 85 delete thread; |
| 87 return task_runner; | 86 return task_runner; |
| 88 } | 87 } |
| 89 #endif | 88 #endif |
| (...skipping 21 matching lines...) Expand all Loading... |
| 111 | 110 |
| 112 AutoThread::~AutoThread() { | 111 AutoThread::~AutoThread() { |
| 113 DCHECK(!startup_data_); | 112 DCHECK(!startup_data_); |
| 114 | 113 |
| 115 // Wait for the thread to exit. | 114 // Wait for the thread to exit. |
| 116 if (thread_) { | 115 if (thread_) { |
| 117 base::PlatformThread::Join(thread_); | 116 base::PlatformThread::Join(thread_); |
| 118 } | 117 } |
| 119 } | 118 } |
| 120 | 119 |
| 121 scoped_refptr<AutoThreadTaskRunner> | 120 scoped_refptr<AutoThreadTaskRunner> AutoThread::StartWithType( |
| 122 AutoThread::StartWithType(MessageLoop::Type type) { | 121 base::MessageLoop::Type type) { |
| 123 DCHECK(!thread_); | 122 DCHECK(!thread_); |
| 124 #if defined(OS_WIN) | 123 #if defined(OS_WIN) |
| 125 DCHECK(com_init_type_ != COM_INIT_STA || type == MessageLoop::TYPE_UI); | 124 DCHECK(com_init_type_ != COM_INIT_STA || type == base::MessageLoop::TYPE_UI); |
| 126 #endif | 125 #endif |
| 127 | 126 |
| 128 StartupData startup_data(type); | 127 StartupData startup_data(type); |
| 129 startup_data_ = &startup_data; | 128 startup_data_ = &startup_data; |
| 130 | 129 |
| 131 if (!base::PlatformThread::Create(0, this, &thread_)) { | 130 if (!base::PlatformThread::Create(0, this, &thread_)) { |
| 132 DLOG(ERROR) << "failed to create thread"; | 131 DLOG(ERROR) << "failed to create thread"; |
| 133 startup_data_ = NULL; | 132 startup_data_ = NULL; |
| 134 return NULL; | 133 return NULL; |
| 135 } | 134 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 158 | 157 |
| 159 void AutoThread::QuitThread( | 158 void AutoThread::QuitThread( |
| 160 scoped_refptr<base::SingleThreadTaskRunner> task_runner) { | 159 scoped_refptr<base::SingleThreadTaskRunner> task_runner) { |
| 161 if (!task_runner->BelongsToCurrentThread()) { | 160 if (!task_runner->BelongsToCurrentThread()) { |
| 162 task_runner->PostTask(FROM_HERE, base::Bind(&AutoThread::QuitThread, | 161 task_runner->PostTask(FROM_HERE, base::Bind(&AutoThread::QuitThread, |
| 163 base::Unretained(this), | 162 base::Unretained(this), |
| 164 task_runner)); | 163 task_runner)); |
| 165 return; | 164 return; |
| 166 } | 165 } |
| 167 | 166 |
| 168 MessageLoop::current()->Quit(); | 167 base::MessageLoop::current()->Quit(); |
| 169 was_quit_properly_ = true; | 168 was_quit_properly_ = true; |
| 170 | 169 |
| 171 if (joiner_) { | 170 if (joiner_) { |
| 172 joiner_->PostTask(FROM_HERE, base::Bind(&AutoThread::JoinAndDeleteThread, | 171 joiner_->PostTask(FROM_HERE, base::Bind(&AutoThread::JoinAndDeleteThread, |
| 173 base::Unretained(this))); | 172 base::Unretained(this))); |
| 174 } | 173 } |
| 175 } | 174 } |
| 176 | 175 |
| 177 void AutoThread::JoinAndDeleteThread() { | 176 void AutoThread::JoinAndDeleteThread() { |
| 178 delete this; | 177 delete this; |
| 179 } | 178 } |
| 180 | 179 |
| 181 void AutoThread::ThreadMain() { | 180 void AutoThread::ThreadMain() { |
| 182 // The message loop for this thread. | 181 // The message loop for this thread. |
| 183 MessageLoop message_loop(startup_data_->loop_type); | 182 base::MessageLoop message_loop(startup_data_->loop_type); |
| 184 | 183 |
| 185 // Complete the initialization of our AutoThread object. | 184 // Complete the initialization of our AutoThread object. |
| 186 base::PlatformThread::SetName(name_.c_str()); | 185 base::PlatformThread::SetName(name_.c_str()); |
| 187 ANNOTATE_THREAD_NAME(name_.c_str()); // Tell the name to race detector. | 186 ANNOTATE_THREAD_NAME(name_.c_str()); // Tell the name to race detector. |
| 188 message_loop.set_thread_name(name_); | 187 message_loop.set_thread_name(name_); |
| 189 | 188 |
| 190 // Return an AutoThreadTaskRunner that will cleanly quit this thread when | 189 // Return an AutoThreadTaskRunner that will cleanly quit this thread when |
| 191 // no more references to it remain. | 190 // no more references to it remain. |
| 192 startup_data_->task_runner = | 191 startup_data_->task_runner = |
| 193 new AutoThreadTaskRunner(message_loop.message_loop_proxy(), | 192 new AutoThreadTaskRunner(message_loop.message_loop_proxy(), |
| (...skipping 11 matching lines...) Expand all Loading... |
| 205 CreateComInitializer(com_init_type_)); | 204 CreateComInitializer(com_init_type_)); |
| 206 #endif | 205 #endif |
| 207 | 206 |
| 208 message_loop.Run(); | 207 message_loop.Run(); |
| 209 | 208 |
| 210 // Assert that MessageLoop::Quit was called by AutoThread::QuitThread. | 209 // Assert that MessageLoop::Quit was called by AutoThread::QuitThread. |
| 211 DCHECK(was_quit_properly_); | 210 DCHECK(was_quit_properly_); |
| 212 } | 211 } |
| 213 | 212 |
| 214 } // namespace base | 213 } // namespace base |
| OLD | NEW |