Chromium Code Reviews| Index: mojo/public/cpp/bindings/tests/sync_method_unittest.cc |
| diff --git a/mojo/public/cpp/bindings/tests/sync_method_unittest.cc b/mojo/public/cpp/bindings/tests/sync_method_unittest.cc |
| index d0e5f108880aa2bfe3a7e8018a59a496e8be3022..264e3484ffec871cec9de17c220e695de9aad61c 100644 |
| --- a/mojo/public/cpp/bindings/tests/sync_method_unittest.cc |
| +++ b/mojo/public/cpp/bindings/tests/sync_method_unittest.cc |
| @@ -349,17 +349,21 @@ TYPED_TEST(SyncMethodCommonTest, CallSyncMethodAsynchronously) { |
| TYPED_TEST(SyncMethodCommonTest, BasicSyncCalls) { |
| InterfacePtr<TypeParam> ptr; |
| - |
| + InterfaceRequest<TypeParam> request(&ptr); |
| TestSyncServiceThread<TypeParam> service_thread; |
| + scoped_refptr<ThreadSafeInterfacePtr<TypeParam>> tsip = |
| + ThreadSafeInterfacePtr<TypeParam>::Create( |
| + ptr.PassInterface(), service_thread.thread()->task_runner()); |
| + |
| service_thread.thread()->task_runner()->PostTask( |
| - FROM_HERE, base::Bind(&TestSyncServiceThread<TypeParam>::SetUp, |
| - base::Unretained(&service_thread), |
| - base::Passed(MakeRequest(&ptr)))); |
| - ASSERT_TRUE(ptr->Ping()); |
| + FROM_HERE, |
| + base::Bind(&TestSyncServiceThread<TypeParam>::SetUp, |
| + base::Unretained(&service_thread), base::Passed(&request))); |
| + ASSERT_TRUE((*tsip)->Ping()); |
| ASSERT_TRUE(service_thread.ping_called()); |
| int32_t output_value = -1; |
| - ASSERT_TRUE(ptr->Echo(42, &output_value)); |
| + ASSERT_TRUE((*tsip)->Echo(42, &output_value)); |
| ASSERT_EQ(42, output_value); |
| base::RunLoop run_loop; |
| @@ -395,6 +399,23 @@ TYPED_TEST(SyncMethodCommonTest, InterfacePtrDestroyedDuringSyncCall) { |
| ASSERT_FALSE(ptr->Ping()); |
| } |
| +TYPED_TEST(SyncMethodCommonTest, TSIPInterfacePtrDestroyedDuringSyncCall) { |
|
watk
2017/03/24 02:40:52
I just added these for local testing.
I'm thinki
|
| + // Test that it won't result in crash or hang if an interface pointer is |
| + // destroyed while it is waiting for a sync call response. |
| + |
| + InterfacePtr<TypeParam> ptr; |
| + typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); |
| + scoped_refptr<ThreadSafeInterfacePtr<TypeParam>> thread_safe_ptr = |
| + ThreadSafeInterfacePtr<TypeParam>::Create(std::move(ptr)); |
| + // The binding lives on the same thread as the interface pointer. |
| + impl.set_ping_handler( |
| + [&thread_safe_ptr](const TestSync::PingCallback& callback) { |
| + thread_safe_ptr = nullptr; |
| + callback.Run(); |
| + }); |
| + ASSERT_FALSE((*thread_safe_ptr)->Ping()); |
| +} |
| + |
| TYPED_TEST(SyncMethodCommonTest, BindingDestroyedDuringSyncCall) { |
| // Test that it won't result in crash or hang if a binding is |
| // closed (and therefore the message pipe handle is closed) while the |
| @@ -435,6 +456,35 @@ TYPED_TEST(SyncMethodCommonTest, NestedSyncCallsWithInOrderResponses) { |
| EXPECT_EQ(123, result_value); |
| } |
| +TYPED_TEST(SyncMethodCommonTest, TSIPNestedSyncCallsWithInOrderResponses) { |
| + // Test that we can call a sync method on an interface ptr, while there is |
| + // already a sync call ongoing. The responses arrive in order. |
| + |
| + InterfacePtr<TypeParam> ptr; |
| + typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); |
| + scoped_refptr<ThreadSafeInterfacePtr<TypeParam>> tsip = |
| + ThreadSafeInterfacePtr<TypeParam>::Create(std::move(ptr)); |
| + |
| + // The same variable is used to store the output of the two sync calls, in |
| + // order to test that responses are handled in the correct order. |
| + int32_t result_value = -1; |
| + |
| + bool first_call = true; |
| + impl.set_echo_handler( |
| + [&first_call, &tsip, &result_value]( |
| + int32_t value, const TestSync::EchoCallback& callback) { |
| + if (first_call) { |
| + first_call = false; |
| + ASSERT_TRUE((*tsip)->Echo(456, &result_value)); |
| + EXPECT_EQ(456, result_value); |
| + } |
| + callback.Run(value); |
| + }); |
| + |
| + ASSERT_TRUE((*tsip)->Echo(123, &result_value)); |
| + EXPECT_EQ(123, result_value); |
| +} |
| + |
| TYPED_TEST(SyncMethodCommonTest, NestedSyncCallsWithOutOfOrderResponses) { |
| // Test that we can call a sync method on an interface ptr, while there is |
| // already a sync call ongoing. The responses arrive out of order. |
| @@ -461,6 +511,35 @@ TYPED_TEST(SyncMethodCommonTest, NestedSyncCallsWithOutOfOrderResponses) { |
| EXPECT_EQ(123, result_value); |
| } |
| +TYPED_TEST(SyncMethodCommonTest, TSIPNestedSyncCallsWithOutOfOrderResponses) { |
| + // Test that we can call a sync method on an interface ptr, while there is |
| + // already a sync call ongoing. The responses arrive out of order. |
| + |
| + InterfacePtr<TypeParam> ptr; |
| + typename ImplTraits<TypeParam>::Type impl(MakeRequest(&ptr)); |
| + scoped_refptr<ThreadSafeInterfacePtr<TypeParam>> tsip = |
| + ThreadSafeInterfacePtr<TypeParam>::Create(std::move(ptr)); |
| + |
| + // The same variable is used to store the output of the two sync calls, in |
| + // order to test that responses are handled in the correct order. |
| + int32_t result_value = -1; |
| + |
| + bool first_call = true; |
| + impl.set_echo_handler( |
| + [&first_call, &tsip, &result_value]( |
| + int32_t value, const TestSync::EchoCallback& callback) { |
| + callback.Run(value); |
| + if (first_call) { |
| + first_call = false; |
| + ASSERT_TRUE((*tsip)->Echo(456, &result_value)); |
| + EXPECT_EQ(456, result_value); |
| + } |
| + }); |
| + |
| + ASSERT_TRUE((*tsip)->Echo(123, &result_value)); |
| + EXPECT_EQ(123, result_value); |
| +} |
| + |
| TYPED_TEST(SyncMethodCommonTest, AsyncResponseQueuedDuringSyncCall) { |
| // Test that while an interface pointer is waiting for the response to a sync |
| // call, async responses are queued until the sync call completes. |