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 |