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 "jingle/glue/thread_wrapper.h" | 5 #include "jingle/glue/thread_wrapper.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
10 #include "base/threading/thread_local.h" | 10 #include "base/threading/thread_local.h" |
(...skipping 12 matching lines...) Expand all Loading... |
23 JingleThreadWrapper* sending_thread; | 23 JingleThreadWrapper* sending_thread; |
24 rtc::Message message; | 24 rtc::Message message; |
25 base::WaitableEvent done_event; | 25 base::WaitableEvent done_event; |
26 }; | 26 }; |
27 | 27 |
28 base::LazyInstance<base::ThreadLocalPointer<JingleThreadWrapper> > | 28 base::LazyInstance<base::ThreadLocalPointer<JingleThreadWrapper> > |
29 g_jingle_thread_wrapper = LAZY_INSTANCE_INITIALIZER; | 29 g_jingle_thread_wrapper = LAZY_INSTANCE_INITIALIZER; |
30 | 30 |
31 // static | 31 // static |
32 void JingleThreadWrapper::EnsureForCurrentMessageLoop() { | 32 void JingleThreadWrapper::EnsureForCurrentMessageLoop() { |
33 if (JingleThreadWrapper::current() == NULL) { | 33 if (JingleThreadWrapper::current() == nullptr) { |
34 base::MessageLoop* message_loop = base::MessageLoop::current(); | 34 base::MessageLoop* message_loop = base::MessageLoop::current(); |
35 g_jingle_thread_wrapper.Get() | 35 scoped_ptr<JingleThreadWrapper> wrapper = |
36 .Set(new JingleThreadWrapper(message_loop->message_loop_proxy())); | 36 JingleThreadWrapper::WrapTaskRunner(message_loop->task_runner()); |
37 message_loop->AddDestructionObserver(current()); | 37 message_loop->AddDestructionObserver(wrapper.release()); |
38 } | 38 } |
39 | 39 |
40 DCHECK_EQ(rtc::Thread::Current(), current()); | 40 DCHECK_EQ(rtc::Thread::Current(), current()); |
41 } | 41 } |
42 | 42 |
| 43 scoped_ptr<JingleThreadWrapper> JingleThreadWrapper::WrapTaskRunner( |
| 44 scoped_refptr<base::SingleThreadTaskRunner> task_runner) { |
| 45 DCHECK(!JingleThreadWrapper::current()); |
| 46 DCHECK(task_runner->BelongsToCurrentThread()); |
| 47 |
| 48 scoped_ptr<JingleThreadWrapper> result(new JingleThreadWrapper(task_runner)); |
| 49 g_jingle_thread_wrapper.Get().Set(result.get()); |
| 50 return result.Pass(); |
| 51 } |
| 52 |
43 // static | 53 // static |
44 JingleThreadWrapper* JingleThreadWrapper::current() { | 54 JingleThreadWrapper* JingleThreadWrapper::current() { |
45 return g_jingle_thread_wrapper.Get().Get(); | 55 return g_jingle_thread_wrapper.Get().Get(); |
46 } | 56 } |
47 | 57 |
48 JingleThreadWrapper::JingleThreadWrapper( | 58 JingleThreadWrapper::JingleThreadWrapper( |
49 scoped_refptr<base::SingleThreadTaskRunner> task_runner) | 59 scoped_refptr<base::SingleThreadTaskRunner> task_runner) |
50 : rtc::Thread(new rtc::NullSocketServer()), | 60 : task_runner_(task_runner), |
51 task_runner_(task_runner), | |
52 send_allowed_(false), | 61 send_allowed_(false), |
53 last_task_id_(0), | 62 last_task_id_(0), |
54 pending_send_event_(true, false), | 63 pending_send_event_(true, false), |
55 weak_ptr_factory_(this) { | 64 weak_ptr_factory_(this) { |
56 DCHECK(task_runner->BelongsToCurrentThread()); | 65 DCHECK(task_runner->BelongsToCurrentThread()); |
57 DCHECK(!rtc::Thread::Current()); | 66 DCHECK(!rtc::Thread::Current()); |
58 weak_ptr_ = weak_ptr_factory_.GetWeakPtr(); | 67 weak_ptr_ = weak_ptr_factory_.GetWeakPtr(); |
59 rtc::MessageQueueManager::Add(this); | 68 rtc::MessageQueueManager::Add(this); |
60 SafeWrapCurrent(); | 69 SafeWrapCurrent(); |
61 } | 70 } |
62 | 71 |
63 JingleThreadWrapper::~JingleThreadWrapper() { | 72 JingleThreadWrapper::~JingleThreadWrapper() { |
64 Clear(NULL, rtc::MQID_ANY, NULL); | 73 DCHECK_EQ(this, JingleThreadWrapper::current()); |
| 74 DCHECK_EQ(this, rtc::Thread::Current()); |
| 75 |
| 76 UnwrapCurrent(); |
| 77 rtc::ThreadManager::Instance()->SetCurrentThread(nullptr); |
| 78 rtc::MessageQueueManager::Remove(this); |
| 79 g_jingle_thread_wrapper.Get().Set(nullptr); |
| 80 |
| 81 Clear(nullptr, rtc::MQID_ANY, nullptr); |
65 } | 82 } |
66 | 83 |
67 void JingleThreadWrapper::WillDestroyCurrentMessageLoop() { | 84 void JingleThreadWrapper::WillDestroyCurrentMessageLoop() { |
68 DCHECK_EQ(rtc::Thread::Current(), current()); | |
69 UnwrapCurrent(); | |
70 g_jingle_thread_wrapper.Get().Set(NULL); | |
71 rtc::ThreadManager::Instance()->SetCurrentThread(NULL); | |
72 rtc::MessageQueueManager::Remove(this); | |
73 rtc::SocketServer* ss = socketserver(); | |
74 delete this; | 85 delete this; |
75 delete ss; | |
76 } | 86 } |
77 | 87 |
78 void JingleThreadWrapper::Post( | 88 void JingleThreadWrapper::Post( |
79 rtc::MessageHandler* handler, uint32 message_id, | 89 rtc::MessageHandler* handler, uint32 message_id, |
80 rtc::MessageData* data, bool time_sensitive) { | 90 rtc::MessageData* data, bool time_sensitive) { |
81 PostTaskInternal(0, handler, message_id, data); | 91 PostTaskInternal(0, handler, message_id, data); |
82 } | 92 } |
83 | 93 |
84 void JingleThreadWrapper::PostDelayed( | 94 void JingleThreadWrapper::PostDelayed( |
85 int delay_ms, rtc::MessageHandler* handler, | 95 int delay_ms, rtc::MessageHandler* handler, |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 it = next; | 136 it = next; |
127 } | 137 } |
128 } | 138 } |
129 | 139 |
130 void JingleThreadWrapper::Send(rtc::MessageHandler *handler, uint32 id, | 140 void JingleThreadWrapper::Send(rtc::MessageHandler *handler, uint32 id, |
131 rtc::MessageData *data) { | 141 rtc::MessageData *data) { |
132 if (fStop_) | 142 if (fStop_) |
133 return; | 143 return; |
134 | 144 |
135 JingleThreadWrapper* current_thread = JingleThreadWrapper::current(); | 145 JingleThreadWrapper* current_thread = JingleThreadWrapper::current(); |
136 DCHECK(current_thread != NULL) << "Send() can be called only from a " | 146 DCHECK(current_thread != nullptr) << "Send() can be called only from a " |
137 "thread that has JingleThreadWrapper."; | 147 "thread that has JingleThreadWrapper."; |
138 | 148 |
139 rtc::Message message; | 149 rtc::Message message; |
140 message.phandler = handler; | 150 message.phandler = handler; |
141 message.message_id = id; | 151 message.message_id = id; |
142 message.pdata = data; | 152 message.pdata = data; |
143 | 153 |
144 if (current_thread == this) { | 154 if (current_thread == this) { |
145 handler->OnMessage(&message); | 155 handler->OnMessage(&message); |
146 return; | 156 return; |
(...skipping 26 matching lines...) Expand all Loading... |
173 size_t event = base::WaitableEvent::WaitMany(events, arraysize(events)); | 183 size_t event = base::WaitableEvent::WaitMany(events, arraysize(events)); |
174 DCHECK(event == 0 || event == 1); | 184 DCHECK(event == 0 || event == 1); |
175 | 185 |
176 if (event == 1) | 186 if (event == 1) |
177 current_thread->ProcessPendingSends(); | 187 current_thread->ProcessPendingSends(); |
178 } | 188 } |
179 } | 189 } |
180 | 190 |
181 void JingleThreadWrapper::ProcessPendingSends() { | 191 void JingleThreadWrapper::ProcessPendingSends() { |
182 while (true) { | 192 while (true) { |
183 PendingSend* pending_send = NULL; | 193 PendingSend* pending_send = nullptr; |
184 { | 194 { |
185 base::AutoLock auto_lock(lock_); | 195 base::AutoLock auto_lock(lock_); |
186 if (!pending_send_messages_.empty()) { | 196 if (!pending_send_messages_.empty()) { |
187 pending_send = pending_send_messages_.front(); | 197 pending_send = pending_send_messages_.front(); |
188 pending_send_messages_.pop_front(); | 198 pending_send_messages_.pop_front(); |
189 } else { | 199 } else { |
190 // Reset the event while |lock_| is still locked. | 200 // Reset the event while |lock_| is still locked. |
191 pending_send_event_.Reset(); | 201 pending_send_event_.Reset(); |
192 break; | 202 break; |
193 } | 203 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 MessagesQueue::iterator it = messages_.find(task_id); | 243 MessagesQueue::iterator it = messages_.find(task_id); |
234 if (it != messages_.end()) { | 244 if (it != messages_.end()) { |
235 have_message = true; | 245 have_message = true; |
236 message = it->second; | 246 message = it->second; |
237 messages_.erase(it); | 247 messages_.erase(it); |
238 } | 248 } |
239 } | 249 } |
240 | 250 |
241 if (have_message) { | 251 if (have_message) { |
242 if (message.message_id == rtc::MQID_DISPOSE) { | 252 if (message.message_id == rtc::MQID_DISPOSE) { |
243 DCHECK(message.phandler == NULL); | 253 DCHECK(message.phandler == nullptr); |
244 delete message.pdata; | 254 delete message.pdata; |
245 } else { | 255 } else { |
246 message.phandler->OnMessage(&message); | 256 message.phandler->OnMessage(&message); |
247 } | 257 } |
248 } | 258 } |
249 } | 259 } |
250 | 260 |
251 // All methods below are marked as not reached. See comments in the | 261 // All methods below are marked as not reached. See comments in the |
252 // header for more details. | 262 // header for more details. |
253 void JingleThreadWrapper::Quit() { | 263 void JingleThreadWrapper::Quit() { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 | 303 |
294 void JingleThreadWrapper::Stop() { | 304 void JingleThreadWrapper::Stop() { |
295 NOTREACHED(); | 305 NOTREACHED(); |
296 } | 306 } |
297 | 307 |
298 void JingleThreadWrapper::Run() { | 308 void JingleThreadWrapper::Run() { |
299 NOTREACHED(); | 309 NOTREACHED(); |
300 } | 310 } |
301 | 311 |
302 } // namespace jingle_glue | 312 } // namespace jingle_glue |
OLD | NEW |