Chromium Code Reviews| Index: jingle/glue/thread_wrapper.cc |
| diff --git a/jingle/glue/thread_wrapper.cc b/jingle/glue/thread_wrapper.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..f61205306b566386fc625dce93d152e00908d430 |
| --- /dev/null |
| +++ b/jingle/glue/thread_wrapper.cc |
| @@ -0,0 +1,198 @@ |
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "jingle/glue/thread_wrapper.h" |
| + |
| +namespace jingle_glue { |
| + |
| +JingleThreadWrapper::JingleThreadWrapper(MessageLoop* message_loop) |
| + : message_loop_(message_loop) { |
| + DCHECK_EQ(message_loop_, MessageLoop::current()); |
| + |
| + talk_base::ThreadManager::SetCurrent(this); |
| + message_loop_->AddDestructionObserver(this); |
| +} |
| + |
| +JingleThreadWrapper::~JingleThreadWrapper() { |
| +} |
| + |
| +void JingleThreadWrapper::WillDestroyCurrentMessageLoop() { |
| + talk_base::ThreadManager::SetCurrent(NULL); |
| + message_loop_->RemoveDestructionObserver(this); |
| + delete this; |
| +} |
| + |
| +void JingleThreadWrapper::Post( |
| + talk_base::MessageHandler* handler, uint32 id, |
| + talk_base::MessageData* data, bool time_sensitive) { |
| + bool queue_was_empty; |
| + talk_base::Message message; |
| + message.phandler = handler; |
| + message.message_id = id; |
| + message.pdata = data; |
| + { |
| + base::AutoLock auto_lock(lock_); |
| + queue_was_empty = messages_.empty(); |
| + messages_.push_back(message); |
| + } |
| + |
| + // Post new task only if there is the queue was empty. |
| + if (!queue_was_empty) { |
| + message_loop_->PostTask(FROM_HERE, NewRunnableMethod( |
| + this, &JingleThreadWrapper::RunPendingTasks)); |
| + } |
| +} |
| + |
| +void JingleThreadWrapper::PostDelayed( |
| + int delay_ms, talk_base::MessageHandler* handler, |
| + uint32 id, talk_base::MessageData* data) { |
| + talk_base::Message message; |
| + message.phandler = handler; |
| + message.message_id = id; |
| + message.pdata = data; |
| + talk_base::DelayedMessage delayed_message( |
| + delay_ms, talk_base::TimeAfter(delay_ms), dmsgq_next_num_++, message); |
| + { |
| + base::AutoLock auto_lock(lock_); |
| + delayed_messages_.push_back(delayed_message); |
| + std::push_heap(delayed_messages_.begin(), delayed_messages_.end()); |
| + } |
| + |
| + message_loop_->PostDelayedTask( |
| + FROM_HERE, NewRunnableMethod(this, &JingleThreadWrapper::RunDelayedTask, |
| + delayed_message.msTrigger_), |
| + delay_ms); |
| +} |
| + |
| +void JingleThreadWrapper::Clear(talk_base::MessageHandler* handler, uint32 id, |
| + talk_base::MessageList* removed) { |
| + base::AutoLock auto_lock(lock_); |
| + |
| + for (std::list<talk_base::Message>::iterator it = messages_.begin(); |
|
Alpha Left Google
2011/03/26 01:06:01
These two loops look really similar, please add co
Sergey Ulanov
2011/03/26 01:44:24
Done.
|
| + it != messages_.end();) { |
| + if (it->Match(handler, id)) { |
| + if (removed) { |
| + removed->push_back(*it); |
| + } else { |
| + delete it->pdata; |
| + } |
| + it = messages_.erase(it); |
| + } else { |
| + ++it; |
| + } |
| + } |
| + |
| + for (DelayedMessagesHeap::iterator it = delayed_messages_.begin(); |
| + it != delayed_messages_.end();) { |
| + if (it->msg_.Match(handler, id)) { |
| + if (removed) { |
| + removed->push_back(it->msg_); |
| + } else { |
| + delete it->msg_.pdata; |
| + } |
| + // Move last element to the current position. |
| + *it = delayed_messages_.back(); |
| + delayed_messages_.erase(delayed_messages_.end() - 1); |
|
Alpha Left Google
2011/03/26 01:06:01
why not just use delayed_messages_.back()?
Sergey Ulanov
2011/03/26 01:44:24
erase() needs iterator. back() returns reference t
|
| + } else { |
| + ++it; |
| + } |
| + } |
| + |
| + // Sort the heap again after we've removed some messages. |
| + std::make_heap(delayed_messages_.begin(), delayed_messages_.end()); |
|
Alpha Left Google
2011/03/26 01:06:01
where is the comparator for messages, add comment
Sergey Ulanov
2011/03/26 01:44:24
It's defined in talk_base::DelayedMessage. Anyway
|
| +} |
| + |
| +void JingleThreadWrapper::RunPendingTasks() { |
| + bool have_message; |
| + |
| + do { |
| + have_message = false; |
| + talk_base::Message message; |
| + { |
| + base::AutoLock auto_lock(lock_); |
| + if (!messages_.empty()) { |
| + have_message = true; |
| + message = messages_.front(); |
| + messages_.pop_front(); |
| + } |
| + } |
| + |
| + if (have_message) { |
| + message.phandler->OnMessage(&message); |
| + delete message.pdata; |
| + } |
| + } while (have_message); |
| +} |
| + |
| +void JingleThreadWrapper::RunDelayedTask(uint32 task_time) { |
| + bool have_message = false; |
| + talk_base::Message message; |
| + |
| + { |
| + base::AutoLock auto_lock(lock_); |
| + if (!delayed_messages_.empty() && |
| + delayed_messages_.front().msTrigger_ == task_time) { |
| + have_message = true; |
| + message = delayed_messages_.front().msg_; |
| + std::pop_heap(delayed_messages_.begin(), delayed_messages_.end()); |
| + delayed_messages_.erase(delayed_messages_.end() - 1); |
|
Alpha Left Google
2011/03/26 01:06:01
why not use delayed_messages_.back()?
Sergey Ulanov
2011/03/26 01:44:24
back() returns reference to last element. erase()
|
| + } |
| + } |
| + |
| + if (have_message) { |
| + message.phandler->OnMessage(&message); |
| + delete message.pdata; |
| + } |
| +} |
| + |
| +void JingleThreadWrapper::Quit() { |
| + NOTREACHED(); |
|
Alpha Left Google
2011/03/26 01:06:01
These methods are NOTREACHED(), why? Explain pleas
Sergey Ulanov
2011/03/26 01:44:24
This is mentioned in the header. Added more commen
|
| +} |
| + |
| +bool JingleThreadWrapper::IsQuitting() { |
| + NOTREACHED(); |
| + return false; |
| +} |
| + |
| +void JingleThreadWrapper::Restart() { |
| + NOTREACHED(); |
| +} |
| + |
| +bool JingleThreadWrapper::Get(talk_base::Message*, int, bool) { |
| + NOTREACHED(); |
| + return false; |
| +} |
| + |
| +bool JingleThreadWrapper::Peek(talk_base::Message*, int) { |
| + NOTREACHED(); |
| + return false; |
| +} |
| + |
| +void JingleThreadWrapper::PostAt(uint32, talk_base::MessageHandler*, |
| + uint32, talk_base::MessageData*) { |
| + NOTREACHED(); |
| +} |
| + |
| +void JingleThreadWrapper::Dispatch(talk_base::Message* msg) { |
| + NOTREACHED(); |
| +} |
| + |
| +void JingleThreadWrapper::ReceiveSends() { |
| + NOTREACHED(); |
| +} |
| + |
| +int JingleThreadWrapper::GetDelay() { |
| + NOTREACHED(); |
| + return 0; |
| +} |
| + |
| +void JingleThreadWrapper::Stop() { |
| + NOTREACHED(); |
| +} |
| + |
| +void JingleThreadWrapper::Run() { |
| + NOTREACHED(); |
| +} |
| + |
| +} // namespace jingle_glue |