Update libjingle to 61168196
R=mallinath@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/8139004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@5502 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/talk/base/thread_unittest.cc b/talk/base/thread_unittest.cc
index 896fbab..ddf6326 100644
--- a/talk/base/thread_unittest.cc
+++ b/talk/base/thread_unittest.cc
@@ -25,6 +25,7 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "talk/base/asyncinvoker.h"
#include "talk/base/asyncudpsocket.h"
#include "talk/base/event.h"
#include "talk/base/gunit.h"
@@ -150,16 +151,22 @@
};
// Function objects to test Thread::Invoke.
-struct Functor1 {
+struct FunctorA {
int operator()() { return 42; }
};
-class Functor2 {
+class FunctorB {
public:
- explicit Functor2(bool* flag) : flag_(flag) {}
+ explicit FunctorB(bool* flag) : flag_(flag) {}
void operator()() { if (flag_) *flag_ = true; }
private:
bool* flag_;
};
+struct FunctorC {
+ int operator()() {
+ Thread::Current()->ProcessMessages(50);
+ return 24;
+ }
+};
// See: https://code.google.com/p/webrtc/issues/detail?id=2409
TEST(ThreadTest, DISABLED_Main) {
@@ -289,9 +296,9 @@
Thread thread;
thread.Start();
// Try calling functors.
- EXPECT_EQ(42, thread.Invoke<int>(Functor1()));
+ EXPECT_EQ(42, thread.Invoke<int>(FunctorA()));
bool called = false;
- Functor2 f2(&called);
+ FunctorB f2(&called);
thread.Invoke<void>(f2);
EXPECT_TRUE(called);
// Try calling bare functions.
@@ -303,6 +310,152 @@
thread.Invoke<void>(&LocalFuncs::Func2);
}
+class AsyncInvokeTest : public testing::Test {
+ public:
+ void IntCallback(int value) {
+ EXPECT_EQ(expected_thread_, Thread::Current());
+ int_value_ = value;
+ }
+ void AsyncInvokeIntCallback(AsyncInvoker* invoker, Thread* thread) {
+ expected_thread_ = thread;
+ invoker->AsyncInvoke(thread, FunctorC(),
+ &AsyncInvokeTest::IntCallback,
+ static_cast<AsyncInvokeTest*>(this));
+ invoke_started_.Set();
+ }
+ void SetExpectedThreadForIntCallback(Thread* thread) {
+ expected_thread_ = thread;
+ }
+
+ protected:
+ enum { kWaitTimeout = 1000 };
+ AsyncInvokeTest()
+ : int_value_(0),
+ invoke_started_(true, false),
+ expected_thread_(NULL) {}
+
+ int int_value_;
+ Event invoke_started_;
+ Thread* expected_thread_;
+};
+
+TEST_F(AsyncInvokeTest, FireAndForget) {
+ AsyncInvoker invoker;
+ // Create and start the thread.
+ Thread thread;
+ thread.Start();
+ // Try calling functor.
+ bool called = false;
+ invoker.AsyncInvoke<void>(&thread, FunctorB(&called));
+ EXPECT_TRUE_WAIT(called, kWaitTimeout);
+}
+
+TEST_F(AsyncInvokeTest, WithCallback) {
+ AsyncInvoker invoker;
+ // Create and start the thread.
+ Thread thread;
+ thread.Start();
+ // Try calling functor.
+ SetExpectedThreadForIntCallback(Thread::Current());
+ invoker.AsyncInvoke(&thread, FunctorA(),
+ &AsyncInvokeTest::IntCallback,
+ static_cast<AsyncInvokeTest*>(this));
+ EXPECT_EQ_WAIT(42, int_value_, kWaitTimeout);
+}
+
+TEST_F(AsyncInvokeTest, CancelInvoker) {
+ // Create and start the thread.
+ Thread thread;
+ thread.Start();
+ // Try destroying invoker during call.
+ {
+ AsyncInvoker invoker;
+ invoker.AsyncInvoke(&thread, FunctorC(),
+ &AsyncInvokeTest::IntCallback,
+ static_cast<AsyncInvokeTest*>(this));
+ }
+ // With invoker gone, callback should be cancelled.
+ Thread::Current()->ProcessMessages(kWaitTimeout);
+ EXPECT_EQ(0, int_value_);
+}
+
+TEST_F(AsyncInvokeTest, CancelCallingThread) {
+ AsyncInvoker invoker;
+ { // Create and start the thread.
+ Thread thread;
+ thread.Start();
+ // Try calling functor.
+ thread.Invoke<void>(Bind(&AsyncInvokeTest::AsyncInvokeIntCallback,
+ static_cast<AsyncInvokeTest*>(this),
+ &invoker, Thread::Current()));
+ // Wait for the call to begin.
+ ASSERT_TRUE(invoke_started_.Wait(kWaitTimeout));
+ }
+ // Calling thread is gone. Return message shouldn't happen.
+ Thread::Current()->ProcessMessages(kWaitTimeout);
+ EXPECT_EQ(0, int_value_);
+}
+
+TEST_F(AsyncInvokeTest, KillInvokerBeforeExecute) {
+ Thread thread;
+ thread.Start();
+ {
+ AsyncInvoker invoker;
+ // Try calling functor.
+ thread.Invoke<void>(Bind(&AsyncInvokeTest::AsyncInvokeIntCallback,
+ static_cast<AsyncInvokeTest*>(this),
+ &invoker, Thread::Current()));
+ // Wait for the call to begin.
+ ASSERT_TRUE(invoke_started_.Wait(kWaitTimeout));
+ }
+ // Invoker is destroyed. Function should not execute.
+ Thread::Current()->ProcessMessages(kWaitTimeout);
+ EXPECT_EQ(0, int_value_);
+}
+
+TEST_F(AsyncInvokeTest, Flush) {
+ AsyncInvoker invoker;
+ bool flag1 = false;
+ bool flag2 = false;
+ // Queue two async calls to the current thread.
+ invoker.AsyncInvoke<void>(Thread::Current(),
+ FunctorB(&flag1));
+ invoker.AsyncInvoke<void>(Thread::Current(),
+ FunctorB(&flag2));
+ // Because we haven't pumped messages, these should not have run yet.
+ EXPECT_FALSE(flag1);
+ EXPECT_FALSE(flag2);
+ // Force them to run now.
+ invoker.Flush(Thread::Current());
+ EXPECT_TRUE(flag1);
+ EXPECT_TRUE(flag2);
+}
+
+TEST_F(AsyncInvokeTest, FlushWithIds) {
+ AsyncInvoker invoker;
+ bool flag1 = false;
+ bool flag2 = false;
+ // Queue two async calls to the current thread, one with a message id.
+ invoker.AsyncInvoke<void>(Thread::Current(),
+ FunctorB(&flag1),
+ 5);
+ invoker.AsyncInvoke<void>(Thread::Current(),
+ FunctorB(&flag2));
+ // Because we haven't pumped messages, these should not have run yet.
+ EXPECT_FALSE(flag1);
+ EXPECT_FALSE(flag2);
+ // Execute pending calls with id == 5.
+ invoker.Flush(Thread::Current(), 5);
+ EXPECT_TRUE(flag1);
+ EXPECT_FALSE(flag2);
+ flag1 = false;
+ // Execute all pending calls. The id == 5 call should not execute again.
+ invoker.Flush(Thread::Current());
+ EXPECT_FALSE(flag1);
+ EXPECT_TRUE(flag2);
+}
+
+
#ifdef WIN32
class ComThreadTest : public testing::Test, public MessageHandler {
public: