(Auto)update libjingle 61549749-> 61608469

git-svn-id: http://webrtc.googlecode.com/svn/trunk@5555 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/talk/base/asyncinvoker-inl.h b/talk/base/asyncinvoker-inl.h
index c4afd3a..b6be175 100644
--- a/talk/base/asyncinvoker-inl.h
+++ b/talk/base/asyncinvoker-inl.h
@@ -28,74 +28,119 @@
 #ifndef TALK_BASE_ASYNCINVOKER_INL_H_
 #define TALK_BASE_ASYNCINVOKER_INL_H_
 
+#include "talk/base/bind.h"
+#include "talk/base/callback.h"
 #include "talk/base/criticalsection.h"
 #include "talk/base/messagehandler.h"
+#include "talk/base/refcount.h"
+#include "talk/base/scoped_ref_ptr.h"
 #include "talk/base/sigslot.h"
 #include "talk/base/thread.h"
 
 namespace talk_base {
 
-// Helper class for AsyncInvoker. Runs a functor on a message queue or thread
-// and doesn't execute the callback when finished if the calling thread ends.
-template <class ReturnT, class FunctorT>
-class AsyncFunctorMessageHandler
-    : public FunctorMessageHandler<ReturnT, FunctorT>,
-      public sigslot::has_slots<> {
-  typedef AsyncFunctorMessageHandler<ReturnT, FunctorT> ThisT;
+class AsyncInvoker;
+
+// Helper class for AsyncInvoker. Runs a task and triggers a callback
+// on the calling thread if necessary. Instances are ref-counted so their
+// lifetime can be independent of AsyncInvoker.
+class AsyncClosure : public RefCountInterface {
  public:
-  explicit AsyncFunctorMessageHandler(const FunctorT& functor)
-      : FunctorMessageHandler<ReturnT, FunctorT>(functor),
-        thread_(Thread::Current()),
-        shutting_down_(false) {
-    thread_->SignalQueueDestroyed.connect(this, &ThisT::OnThreadDestroyed);
-  }
+  virtual ~AsyncClosure() {}
+  // Runs the asynchronous task, and triggers a callback to the calling
+  // thread if needed. Should be called from the target thread.
+  virtual void Execute() = 0;
+};
 
-  virtual ~AsyncFunctorMessageHandler() {
-    CritScope cs(&running_crit_);
-    shutting_down_ = true;
+// Simple closure that doesn't trigger a callback for the calling thread.
+template <class FunctorT>
+class FireAndForgetAsyncClosure : public AsyncClosure {
+ public:
+  explicit FireAndForgetAsyncClosure(const FunctorT& functor)
+      : functor_(functor) {}
+  virtual void Execute() {
+    functor_();
   }
+ private:
+  FunctorT functor_;
+};
 
-  virtual void OnMessage(Message* msg) {
-    CritScope cs(&running_crit_);
-    if (!shutting_down_) {
-      FunctorMessageHandler<ReturnT, FunctorT>::OnMessage(msg);
+// Base class for closures that may trigger a callback for the calling thread.
+// Listens for the "destroyed" signals from the calling thread and the invoker,
+// and cancels the callback to the calling thread if either is destroyed.
+class NotifyingAsyncClosureBase : public AsyncClosure,
+                                  public sigslot::has_slots<> {
+ public:
+  virtual ~NotifyingAsyncClosureBase() { disconnect_all(); }
+
+ protected:
+  NotifyingAsyncClosureBase(AsyncInvoker* invoker, Thread* calling_thread);
+  void TriggerCallback();
+  void SetCallback(const Callback0<void>& callback) {
+    CritScope cs(&crit_);
+    callback_ = callback;
+  }
+  bool CallbackCanceled() const { return calling_thread_ == NULL; }
+
+ private:
+  Callback0<void> callback_;
+  CriticalSection crit_;
+  AsyncInvoker* invoker_;
+  Thread* calling_thread_;
+
+  void CancelCallback();
+};
+
+// Closures that have a non-void return value and require a callback.
+template <class ReturnT, class FunctorT, class HostT>
+class NotifyingAsyncClosure : public NotifyingAsyncClosureBase {
+ public:
+  NotifyingAsyncClosure(AsyncInvoker* invoker,
+                        Thread* calling_thread,
+                        const FunctorT& functor,
+                        void (HostT::*callback)(ReturnT),
+                        HostT* callback_host)
+      :  NotifyingAsyncClosureBase(invoker, calling_thread),
+         functor_(functor),
+         callback_(callback),
+         callback_host_(callback_host) {}
+  virtual void Execute() {
+    ReturnT result = functor_();
+    if (!CallbackCanceled()) {
+      SetCallback(Callback0<void>(Bind(callback_, callback_host_, result)));
+      TriggerCallback();
     }
   }
 
-  // Returns the thread that initiated the async call.
-  Thread* thread() const { return thread_; }
-
-  // Wraps a callback so that it won't execute if |thread_| goes away.
-  void WrapCallback(Callback0<void> cb) {
-    this->SetCallback(
-        Callback0<void>(Bind(&ThisT::MaybeRunCallback, this, cb)));
-  }
-
  private:
-  void OnThreadDestroyed() {
-    CritScope cs(&thread_crit_);
-    thread_ = NULL;
-    this->SetCallback(Callback0<void>());  // Clear out the callback.
-  }
-
-  void MaybeRunCallback(Callback0<void> cb) {
-#ifdef _DEBUG
-    ASSERT(running_crit_.CurrentThreadIsOwner());
-#endif
-    CritScope cs(&thread_crit_);
-    if (thread_ && !shutting_down_) {
-      cb();
-    }
-  }
-
   FunctorT functor_;
-  Thread* thread_;
-  CriticalSection thread_crit_;
-  CriticalSection running_crit_;
-  bool shutting_down_;
+  void (HostT::*callback_)(ReturnT);
+  HostT* callback_host_;
+};
+
+// Closures that have a void return value and require a callback.
+template <class FunctorT, class HostT>
+class NotifyingAsyncClosure<void, FunctorT, HostT>
+    : public NotifyingAsyncClosureBase {
+ public:
+  NotifyingAsyncClosure(AsyncInvoker* invoker,
+                        Thread* calling_thread,
+                        const FunctorT& functor,
+                        void (HostT::*callback)(),
+                        HostT* callback_host)
+      : NotifyingAsyncClosureBase(invoker, calling_thread),
+        functor_(functor) {
+    SetCallback(Callback0<void>(Bind(callback, callback_host)));
+  }
+  virtual void Execute() {
+    functor_();
+    TriggerCallback();
+  }
+
+ private:
+  FunctorT functor_;
 };
 
 }  // namespace talk_base
 
-
 #endif  // TALK_BASE_ASYNCINVOKER_INL_H_
diff --git a/talk/base/asyncinvoker.cc b/talk/base/asyncinvoker.cc
index 63171be..a57eb7b 100644
--- a/talk/base/asyncinvoker.cc
+++ b/talk/base/asyncinvoker.cc
@@ -29,50 +29,80 @@
 
 namespace talk_base {
 
-// Synchronously execute all outstanding calls we own pending
-// on |thread|. Optionally filter by message id.
+AsyncInvoker::AsyncInvoker() : destroying_(false) {}
+
+AsyncInvoker::~AsyncInvoker() {
+  destroying_ = true;
+  SignalInvokerDestroyed();
+  // Messages for this need to be cleared *before* our destructor is complete.
+  MessageQueueManager::Clear(this);
+}
+
+void AsyncInvoker::OnMessage(Message* msg) {
+  // Get the AsyncClosure shared ptr from this message's data.
+  ScopedRefMessageData<AsyncClosure>* data =
+      static_cast<ScopedRefMessageData<AsyncClosure>*>(msg->pdata);
+  scoped_refptr<AsyncClosure> closure = data->data();
+  delete msg->pdata;
+  msg->pdata = NULL;
+
+  // Execute the closure and trigger the return message if needed.
+  closure->Execute();
+}
+
 void AsyncInvoker::Flush(Thread* thread, uint32 id /*= MQID_ANY*/) {
+  if (destroying_) return;
+
   // Run this on |thread| to reduce the number of context switches.
   if (Thread::Current() != thread) {
     thread->Invoke<void>(Bind(&AsyncInvoker::Flush, this, thread, id));
     return;
   }
 
-  // Make a copy of handlers_, since it'll be modified by
-  // callbacks to RemoveHandler when each is done executing.
-  crit_.Enter();
-  std::vector<MessageHandler*> handlers(handlers_.collection());
-  crit_.Leave();
   MessageList removed;
-  for (size_t i = 0; i < handlers.size(); ++i) {
-    removed.clear();
-    thread->Clear(handlers[i], id, &removed);
-    if (!removed.empty()) {
-      // Since each message gets its own handler with AsyncInvoker,
-      // we expect a maximum of one removed.
-      ASSERT(removed.size() == 1);
-      // This handler was pending on this thread, so run it now.
-      const Message& msg = removed.front();
-      thread->Send(msg.phandler,
-                   msg.message_id,
-                   msg.pdata);
-    }
+  thread->Clear(this, id, &removed);
+  for (MessageList::iterator it = removed.begin(); it != removed.end(); ++it) {
+    // This message was pending on this thread, so run it now.
+    thread->Send(it->phandler,
+                 it->message_id,
+                 it->pdata);
   }
 }
 
-void AsyncInvoker::InvokeHandler(Thread* thread, MessageHandler* handler,
-                                 uint32 id) {
-  {
-    CritScope cs(&crit_);
-    handlers_.PushBack(handler);
+void AsyncInvoker::DoInvoke(Thread* thread, AsyncClosure* closure,
+                            uint32 id) {
+  if (destroying_) {
+    LOG(LS_WARNING) << "Tried to invoke while destroying the invoker.";
+    // Since this call transwers ownership of |closure|, we clean it up here.
+    delete closure;
+    return;
   }
-  thread->Post(handler, id);
+  thread->Post(this, id, new ScopedRefMessageData<AsyncClosure>(closure));
 }
 
-void AsyncInvoker::RemoveHandler(MessageHandler* handler) {
+NotifyingAsyncClosureBase::NotifyingAsyncClosureBase(AsyncInvoker* invoker,
+                                                     Thread* calling_thread)
+    : invoker_(invoker), calling_thread_(calling_thread) {
+  calling_thread->SignalQueueDestroyed.connect(
+      this, &NotifyingAsyncClosureBase::CancelCallback);
+  invoker->SignalInvokerDestroyed.connect(
+      this, &NotifyingAsyncClosureBase::CancelCallback);
+}
+
+void NotifyingAsyncClosureBase::TriggerCallback() {
   CritScope cs(&crit_);
-  handlers_.Remove(handler);
-  delete handler;
+  if (!CallbackCanceled() && !callback_.empty()) {
+    invoker_->AsyncInvoke<void>(calling_thread_, callback_);
+  }
+}
+
+void NotifyingAsyncClosureBase::CancelCallback() {
+  // If the callback is triggering when this is called, block the
+  // destructor of the dying object here by waiting until the callback
+  // is done triggering.
+  CritScope cs(&crit_);
+  // calling_thread_ == NULL means do not trigger the callback.
+  calling_thread_ = NULL;
 }
 
 }  // namespace talk_base
diff --git a/talk/base/asyncinvoker.h b/talk/base/asyncinvoker.h
index fabdbdc..b7dfac9 100644
--- a/talk/base/asyncinvoker.h
+++ b/talk/base/asyncinvoker.h
@@ -30,6 +30,7 @@
 
 #include "talk/base/asyncinvoker-inl.h"
 #include "talk/base/bind.h"
+#include "talk/base/sigslot.h"
 #include "talk/base/scopedptrcollection.h"
 #include "talk/base/thread.h"
 
@@ -82,18 +83,20 @@
 //     AsyncInvoker invoker_;
 //     int result_;
 //   };
-class AsyncInvoker {
+class AsyncInvoker : public MessageHandler {
  public:
+  AsyncInvoker();
+  virtual ~AsyncInvoker();
+
   // Call |functor| asynchronously on |thread|, with no callback upon
   // completion. Returns immediately.
   template <class ReturnT, class FunctorT>
   void AsyncInvoke(Thread* thread,
                    const FunctorT& functor,
                    uint32 id = 0) {
-    FunctorMessageHandler<ReturnT, FunctorT>* handler =
-        new FunctorMessageHandler<ReturnT, FunctorT>(functor);
-    handler->SetCallback(Bind(&AsyncInvoker::RemoveHandler, this, handler));
-    InvokeHandler(thread, handler, id);
+    AsyncClosure* closure =
+        new RefCountedObject<FireAndForgetAsyncClosure<FunctorT> >(functor);
+    DoInvoke(thread, closure, id);
   }
 
   // Call |functor| asynchronously on |thread|, calling |callback| when done.
@@ -103,12 +106,10 @@
                    void (HostT::*callback)(ReturnT),
                    HostT* callback_host,
                    uint32 id = 0) {
-    AsyncFunctorMessageHandler<ReturnT, FunctorT>* handler =
-        new AsyncFunctorMessageHandler<ReturnT, FunctorT>(functor);
-    handler->WrapCallback(
-        Bind(&AsyncInvoker::OnAsyncCallCompleted<ReturnT, FunctorT, HostT>,
-             this, handler, callback, callback_host));
-    InvokeHandler(thread, handler, id);
+    AsyncClosure* closure =
+        new RefCountedObject<NotifyingAsyncClosure<ReturnT, FunctorT, HostT> >(
+            this, Thread::Current(), functor, callback, callback_host);
+    DoInvoke(thread, closure, id);
   }
 
   // Call |functor| asynchronously on |thread|, calling |callback| when done.
@@ -119,12 +120,10 @@
                    void (HostT::*callback)(),
                    HostT* callback_host,
                    uint32 id = 0) {
-    AsyncFunctorMessageHandler<void, FunctorT>* handler =
-        new AsyncFunctorMessageHandler<ReturnT, FunctorT>(functor);
-    handler->WrapCallback(
-        Bind(&AsyncInvoker::OnAsyncVoidCallCompleted<FunctorT, HostT>,
-             this, handler, callback, callback_host));
-    InvokeHandler(thread, handler, id);
+    AsyncClosure* closure =
+        new RefCountedObject<NotifyingAsyncClosure<void, FunctorT, HostT> >(
+            this, Thread::Current(), functor, callback, callback_host);
+    DoInvoke(thread, closure, id);
   }
 
   // Synchronously execute on |thread| all outstanding calls we own
@@ -134,31 +133,16 @@
   // behavior is desired, call Flush() before destroying this object.
   void Flush(Thread* thread, uint32 id = MQID_ANY);
 
+  // Signaled when this object is destructed.
+  sigslot::signal0<> SignalInvokerDestroyed;
+
  private:
-  void InvokeHandler(Thread* thread, MessageHandler* handler, uint32 id);
-  void RemoveHandler(MessageHandler* handler);
+  virtual void OnMessage(Message* msg);
+  void DoInvoke(Thread* thread, AsyncClosure* closure, uint32 id);
 
-  template <class ReturnT, class FunctorT, class HostT>
-  void OnAsyncCallCompleted(
-      AsyncFunctorMessageHandler<ReturnT, FunctorT>* handler,
-      void (HostT::*callback)(ReturnT),
-      HostT* callback_host) {
-    AsyncInvoke<void>(handler->thread(),
-                Bind(callback, callback_host, handler->result()));
-    RemoveHandler(handler);
-  }
+  bool destroying_;
 
-  template <class FunctorT, class HostT>
-  void OnAsyncVoidCallCompleted(
-      AsyncFunctorMessageHandler<void, FunctorT>* handler,
-      void (HostT::*callback)(),
-      HostT* callback_host) {
-    AsyncInvoke<void>(handler->thread(), Bind(callback, callback_host));
-    RemoveHandler(handler);
-  }
-
-  CriticalSection crit_;
-  ScopedPtrCollection<MessageHandler> handlers_;
+  DISALLOW_COPY_AND_ASSIGN(AsyncInvoker);
 };
 
 }  // namespace talk_base
diff --git a/talk/base/messagehandler.h b/talk/base/messagehandler.h
index 8b9e5f6..6494f2b 100644
--- a/talk/base/messagehandler.h
+++ b/talk/base/messagehandler.h
@@ -28,7 +28,6 @@
 #ifndef TALK_BASE_MESSAGEHANDLER_H_
 #define TALK_BASE_MESSAGEHANDLER_H_
 
-#include "talk/base/callback.h"
 #include "talk/base/constructormagic.h"
 
 namespace talk_base {
@@ -57,14 +56,12 @@
       : functor_(functor) {}
   virtual void OnMessage(Message* msg) {
     result_ = functor_();
-    if (!callback_.empty()) callback_();
   }
   const ReturnT& result() const { return result_; }
-  void SetCallback(const Callback0<void>& callback) { callback_ = callback; }
+
  private:
   FunctorT functor_;
   ReturnT result_;
-  Callback0<void> callback_;
 };
 
 // Specialization for ReturnT of void.
@@ -75,13 +72,11 @@
       : functor_(functor) {}
   virtual void OnMessage(Message* msg) {
     functor_();
-    if (!callback_.empty()) callback_();
   }
   void result() const {}
-  void SetCallback(const Callback0<void>& callback) { callback_ = callback; }
+
  private:
   FunctorT functor_;
-  Callback0<void> callback_;
 };
 
 
diff --git a/talk/base/thread_unittest.cc b/talk/base/thread_unittest.cc
index 728e321..ddf6326 100644
--- a/talk/base/thread_unittest.cc
+++ b/talk/base/thread_unittest.cc
@@ -339,7 +339,7 @@
   Thread* expected_thread_;
 };
 
-TEST_F(AsyncInvokeTest, DISABLED_FireAndForget) {
+TEST_F(AsyncInvokeTest, FireAndForget) {
   AsyncInvoker invoker;
   // Create and start the thread.
   Thread thread;
@@ -350,7 +350,7 @@
   EXPECT_TRUE_WAIT(called, kWaitTimeout);
 }
 
-TEST_F(AsyncInvokeTest, DISABLED_WithCallback) {
+TEST_F(AsyncInvokeTest, WithCallback) {
   AsyncInvoker invoker;
   // Create and start the thread.
   Thread thread;
@@ -363,7 +363,7 @@
   EXPECT_EQ_WAIT(42, int_value_, kWaitTimeout);
 }
 
-TEST_F(AsyncInvokeTest, DISABLED_CancelInvoker) {
+TEST_F(AsyncInvokeTest, CancelInvoker) {
   // Create and start the thread.
   Thread thread;
   thread.Start();
@@ -379,7 +379,7 @@
   EXPECT_EQ(0, int_value_);
 }
 
-TEST_F(AsyncInvokeTest, DISABLED_CancelCallingThread) {
+TEST_F(AsyncInvokeTest, CancelCallingThread) {
   AsyncInvoker invoker;
   { // Create and start the thread.
     Thread thread;
@@ -396,7 +396,7 @@
   EXPECT_EQ(0, int_value_);
 }
 
-TEST_F(AsyncInvokeTest, DISABLED_KillInvokerBeforeExecute) {
+TEST_F(AsyncInvokeTest, KillInvokerBeforeExecute) {
   Thread thread;
   thread.Start();
   {
@@ -413,7 +413,7 @@
   EXPECT_EQ(0, int_value_);
 }
 
-TEST_F(AsyncInvokeTest, DISABLED_Flush) {
+TEST_F(AsyncInvokeTest, Flush) {
   AsyncInvoker invoker;
   bool flag1 = false;
   bool flag2 = false;
@@ -431,7 +431,7 @@
   EXPECT_TRUE(flag2);
 }
 
-TEST_F(AsyncInvokeTest, DISABLED_FlushWithIds) {
+TEST_F(AsyncInvokeTest, FlushWithIds) {
   AsyncInvoker invoker;
   bool flag1 = false;
   bool flag2 = false;
diff --git a/talk/media/base/mediachannel.h b/talk/media/base/mediachannel.h
index 239798c..1a84704 100644
--- a/talk/media/base/mediachannel.h
+++ b/talk/media/base/mediachannel.h
@@ -749,7 +749,13 @@
         jitter_buffer_preferred_ms(0),
         delay_estimate_ms(0),
         audio_level(0),
-        expand_rate(0) {
+        expand_rate(0),
+        decoding_calls_to_silence_generator(0),
+        decoding_calls_to_neteq(0),
+        decoding_normal(0),
+        decoding_plc(0),
+        decoding_cng(0),
+        decoding_plc_cng(0) {
   }
 
   int ext_seqnum;
@@ -760,6 +766,12 @@
   int audio_level;
   // fraction of synthesized speech inserted through pre-emptive expansion
   float expand_rate;
+  int decoding_calls_to_silence_generator;
+  int decoding_calls_to_neteq;
+  int decoding_normal;
+  int decoding_plc;
+  int decoding_cng;
+  int decoding_plc_cng;
 };
 
 struct VideoSenderInfo : public MediaSenderInfo {
diff --git a/talk/media/webrtc/webrtcvoiceengine.cc b/talk/media/webrtc/webrtcvoiceengine.cc
index f1030bd..e2415cf 100644
--- a/talk/media/webrtc/webrtcvoiceengine.cc
+++ b/talk/media/webrtc/webrtcvoiceengine.cc
@@ -3200,6 +3200,20 @@
         rinfo.expand_rate =
             static_cast<float>(ns.currentExpandRate) / (1 << 14);
       }
+
+      webrtc::AudioDecodingCallStats ds;
+      if (engine()->voe()->neteq() &&
+          engine()->voe()->neteq()->GetDecodingCallStatistics(
+              *it, &ds) != -1) {
+        rinfo.decoding_calls_to_silence_generator =
+            ds.calls_to_silence_generator;
+        rinfo.decoding_calls_to_neteq = ds.calls_to_neteq;
+        rinfo.decoding_normal = ds.decoded_normal;
+        rinfo.decoding_plc = ds.decoded_plc;
+        rinfo.decoding_cng = ds.decoded_cng;
+        rinfo.decoding_plc_cng = ds.decoded_plc_cng;
+      }
+
       if (engine()->voe()->sync()) {
         int jitter_buffer_delay_ms = 0;
         int playout_buffer_delay_ms = 0;