15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "jingle/glue/thread_wrapper.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_local.h"
115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "third_party/webrtc/base/nullsocketserver.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace jingle_glue {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct JingleThreadWrapper::PendingSend {
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  PendingSend(const rtc::Message& message_value)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : sending_thread(JingleThreadWrapper::current()),
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        message(message_value),
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        done_event(true, false) {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(sending_thread);
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  JingleThreadWrapper* sending_thread;
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rtc::Message message;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WaitableEvent done_event;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::LazyInstance<base::ThreadLocalPointer<JingleThreadWrapper> >
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_jingle_thread_wrapper = LAZY_INSTANCE_INITIALIZER;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleThreadWrapper::EnsureForCurrentMessageLoop() {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (JingleThreadWrapper::current() == NULL) {
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::MessageLoop* message_loop = base::MessageLoop::current();
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    g_jingle_thread_wrapper.Get()
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        .Set(new JingleThreadWrapper(message_loop->message_loop_proxy()));
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_loop->AddDestructionObserver(current());
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK_EQ(rtc::Thread::Current(), current());
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JingleThreadWrapper* JingleThreadWrapper::current() {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_jingle_thread_wrapper.Get().Get();
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JingleThreadWrapper::JingleThreadWrapper(
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<base::SingleThreadTaskRunner> task_runner)
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    : rtc::Thread(new rtc::NullSocketServer()),
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      task_runner_(task_runner),
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      send_allowed_(false),
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_task_id_(0),
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pending_send_event_(true, false),
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      weak_ptr_factory_(this) {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(task_runner->BelongsToCurrentThread());
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(!rtc::Thread::Current());
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  weak_ptr_ = weak_ptr_factory_.GetWeakPtr();
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rtc::MessageQueueManager::Add(this);
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SafeWrapCurrent();
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JingleThreadWrapper::~JingleThreadWrapper() {
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  Clear(NULL, rtc::MQID_ANY, NULL);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleThreadWrapper::WillDestroyCurrentMessageLoop() {
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK_EQ(rtc::Thread::Current(), current());
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UnwrapCurrent();
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_jingle_thread_wrapper.Get().Set(NULL);
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rtc::ThreadManager::Instance()->SetCurrentThread(NULL);
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rtc::MessageQueueManager::Remove(this);
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rtc::SocketServer* ss = socketserver();
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete this;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete ss;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleThreadWrapper::Post(
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    rtc::MessageHandler* handler, uint32 message_id,
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    rtc::MessageData* data, bool time_sensitive) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PostTaskInternal(0, handler, message_id, data);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleThreadWrapper::PostDelayed(
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    int delay_ms, rtc::MessageHandler* handler,
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    uint32 message_id, rtc::MessageData* data) {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PostTaskInternal(delay_ms, handler, message_id, data);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void JingleThreadWrapper::Clear(rtc::MessageHandler* handler, uint32 id,
915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                rtc::MessageList* removed) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock auto_lock(lock_);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (MessagesQueue::iterator it = messages_.begin();
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != messages_.end();) {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MessagesQueue::iterator next = it;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++next;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (it->second.Match(handler, id)) {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (removed) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        removed->push_back(it->second);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delete it->second.pdata;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      messages_.erase(it);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    it = next;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (std::list<PendingSend*>::iterator it = pending_send_messages_.begin();
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != pending_send_messages_.end();) {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::list<PendingSend*>::iterator next = it;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++next;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((*it)->message.Match(handler, id)) {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (removed) {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        removed ->push_back((*it)->message);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delete (*it)->message.pdata;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (*it)->done_event.Signal();
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pending_send_messages_.erase(it);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    it = next;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void JingleThreadWrapper::Send(rtc::MessageHandler *handler, uint32 id,
1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               rtc::MessageData *data) {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (fStop_)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  JingleThreadWrapper* current_thread = JingleThreadWrapper::current();
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(current_thread != NULL) << "Send() can be called only from a "
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "thread that has JingleThreadWrapper.";
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rtc::Message message;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.phandler = handler;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.message_id = id;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.pdata = data;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (current_thread == this) {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler->OnMessage(&message);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Send message from a thread different than |this|.
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allow inter-thread send only from threads that have
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |send_allowed_| flag set.
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(current_thread->send_allowed_) << "Send()'ing synchronous "
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "messages is not allowed from the current thread.";
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingSend pending_send(message);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock auto_lock(lock_);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pending_send_messages_.push_back(&pending_send);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Need to signal |pending_send_event_| here in case the thread is
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // sending message to another thread.
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_send_event_.Signal();
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  task_runner_->PostTask(FROM_HERE,
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         base::Bind(&JingleThreadWrapper::ProcessPendingSends,
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    weak_ptr_));
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (!pending_send.done_event.IsSignaled()) {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::WaitableEvent* events[] = {&pending_send.done_event,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     &current_thread->pending_send_event_};
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t event = base::WaitableEvent::WaitMany(events, arraysize(events));
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(event == 0 || event == 1);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event == 1)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      current_thread->ProcessPendingSends();
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleThreadWrapper::ProcessPendingSends() {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (true) {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PendingSend* pending_send = NULL;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::AutoLock auto_lock(lock_);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!pending_send_messages_.empty()) {
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pending_send = pending_send_messages_.front();
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pending_send_messages_.pop_front();
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Reset the event while |lock_| is still locked.
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pending_send_event_.Reset();
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pending_send) {
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pending_send->message.phandler->OnMessage(&pending_send->message);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pending_send->done_event.Signal();
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleThreadWrapper::PostTaskInternal(
2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    int delay_ms, rtc::MessageHandler* handler,
2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    uint32 message_id, rtc::MessageData* data) {
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int task_id;
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rtc::Message message;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.phandler = handler;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.message_id = message_id;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message.pdata = data;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock auto_lock(lock_);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    task_id = ++last_task_id_;
2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    messages_.insert(std::pair<int, rtc::Message>(task_id, message));
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delay_ms <= 0) {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    task_runner_->PostTask(FROM_HERE,
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           base::Bind(&JingleThreadWrapper::RunTask,
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      weak_ptr_, task_id));
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    task_runner_->PostDelayedTask(FROM_HERE,
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  base::Bind(&JingleThreadWrapper::RunTask,
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             weak_ptr_, task_id),
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  base::TimeDelta::FromMilliseconds(delay_ms));
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleThreadWrapper::RunTask(int task_id) {
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool have_message = false;
2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rtc::Message message;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock auto_lock(lock_);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MessagesQueue::iterator it = messages_.find(task_id);
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (it != messages_.end()) {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      have_message = true;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      message = it->second;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      messages_.erase(it);
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (have_message) {
2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (message.message_id == rtc::MQID_DISPOSE) {
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(message.phandler == NULL);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delete message.pdata;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      message.phandler->OnMessage(&message);
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// All methods below are marked as not reached. See comments in the
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// header for more details.
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleThreadWrapper::Quit() {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool JingleThreadWrapper::IsQuitting() {
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleThreadWrapper::Restart() {
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool JingleThreadWrapper::Get(rtc::Message*, int, bool) {
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool JingleThreadWrapper::Peek(rtc::Message*, int) {
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void JingleThreadWrapper::PostAt(uint32, rtc::MessageHandler*,
2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                 uint32, rtc::MessageData*) {
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void JingleThreadWrapper::Dispatch(rtc::Message* message) {
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleThreadWrapper::ReceiveSends() {
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int JingleThreadWrapper::GetDelay() {
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleThreadWrapper::Stop() {
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JingleThreadWrapper::Run() {
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace jingle_glue
303