| Index: mojo/public/cpp/bindings/tests/binding_unittest.cc
|
| diff --git a/mojo/public/cpp/bindings/tests/binding_unittest.cc b/mojo/public/cpp/bindings/tests/binding_unittest.cc
|
| index a2a26c64226220f81a266cc3b4101ddb206a0a20..e9a334c28c672a80ece7a1e576d10e1d5e8e4031 100644
|
| --- a/mojo/public/cpp/bindings/tests/binding_unittest.cc
|
| +++ b/mojo/public/cpp/bindings/tests/binding_unittest.cc
|
| @@ -36,13 +36,18 @@ class BindingTestBase : public testing::Test {
|
| DISALLOW_COPY_AND_ASSIGN(BindingTestBase);
|
| };
|
|
|
| -class ServiceImpl : public sample::Service {
|
| +class ServiceImpl : public SupportsStrongBinding<sample::Service> {
|
| public:
|
| - explicit ServiceImpl(bool* was_deleted = nullptr)
|
| - : was_deleted_(was_deleted) {}
|
| + explicit ServiceImpl(
|
| + bool* was_deleted = nullptr,
|
| + const base::Closure& destruction_callback = base::Closure())
|
| + : was_deleted_(was_deleted),
|
| + destruction_callback_(destruction_callback) {}
|
| ~ServiceImpl() override {
|
| if (was_deleted_)
|
| *was_deleted_ = true;
|
| + if (!destruction_callback_.is_null())
|
| + destruction_callback_.Run();
|
| }
|
|
|
| private:
|
| @@ -56,6 +61,7 @@ class ServiceImpl : public sample::Service {
|
| void GetPort(InterfaceRequest<sample::Port> port) override {}
|
|
|
| bool* const was_deleted_;
|
| + const base::Closure destruction_callback_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(ServiceImpl);
|
| };
|
| @@ -173,25 +179,19 @@ TEST_F(BindingTest, CloseDoesntCallConnectionErrorHandler) {
|
| class ServiceImplWithBinding : public ServiceImpl {
|
| public:
|
| ServiceImplWithBinding(bool* was_deleted,
|
| - const base::Closure& closure,
|
| + const base::Closure& destruction_callback,
|
| InterfaceRequest<sample::Service> request)
|
| - : ServiceImpl(was_deleted),
|
| - binding_(this, std::move(request)),
|
| - closure_(closure) {
|
| + : ServiceImpl(was_deleted, destruction_callback),
|
| + binding_(this, std::move(request)) {
|
| binding_.set_connection_error_handler(
|
| base::Bind(&ServiceImplWithBinding::OnConnectionError,
|
| base::Unretained(this)));
|
| }
|
|
|
| private:
|
| - ~ServiceImplWithBinding() override{
|
| - closure_.Run();
|
| - }
|
| -
|
| void OnConnectionError() { delete this; }
|
|
|
| Binding<sample::Service> binding_;
|
| - base::Closure closure_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(ServiceImplWithBinding);
|
| };
|
| @@ -488,55 +488,46 @@ TEST_F(BindingTest, CustomImplPointerType) {
|
|
|
| using StrongBindingTest = BindingTestBase;
|
|
|
| -// Tests that destroying a mojo::StrongBinding closes the bound message pipe
|
| -// handle but does *not* destroy the implementation object.
|
| -TEST_F(StrongBindingTest, DestroyClosesMessagePipe) {
|
| - base::RunLoop run_loop;
|
| - bool encountered_error = false;
|
| - bool was_deleted = false;
|
| +TEST_F(StrongBindingTest, ConnectionErrorDestroysImpl) {
|
| sample::ServicePtr ptr;
|
| - auto request = GetProxy(&ptr);
|
| - ptr.set_connection_error_handler(
|
| - SetFlagAndRunClosure(&encountered_error, run_loop.QuitClosure()));
|
| - bool called = false;
|
| - base::RunLoop run_loop2;
|
| -
|
| - auto binding = MakeStrongBinding(base::MakeUnique<ServiceImpl>(&was_deleted),
|
| - std::move(request));
|
| - ptr->Frobinate(
|
| - nullptr, sample::Service::BazOptions::REGULAR, nullptr,
|
| - SetFlagAndRunClosure<int32_t>(&called, run_loop2.QuitClosure()));
|
| - run_loop2.Run();
|
| - EXPECT_TRUE(called);
|
| - EXPECT_FALSE(encountered_error);
|
| - binding->Close();
|
| + bool was_deleted = false;
|
|
|
| - // Now that the StrongBinding is closed we should detect an error on the other
|
| - // end of the pipe.
|
| + base::RunLoop run_loop;
|
| + StrongBindingPtr<sample::Service> weak_binding = mojo::MakeStrongBinding(
|
| + base::MakeUnique<ServiceImpl>(&was_deleted, run_loop.QuitClosure()),
|
| + GetProxy(&ptr));
|
| + ptr.reset();
|
| + EXPECT_FALSE(was_deleted);
|
| run_loop.Run();
|
| - EXPECT_TRUE(encountered_error);
|
| -
|
| - // Destroying the StrongBinding also destroys the impl.
|
| - ASSERT_TRUE(was_deleted);
|
| + EXPECT_TRUE(was_deleted);
|
| + EXPECT_FALSE(weak_binding);
|
| }
|
|
|
| -// Tests the typical case, where the implementation object owns the
|
| -// StrongBinding (and should be destroyed on connection error).
|
| -TEST_F(StrongBindingTest, ConnectionErrorDestroysImpl) {
|
| +TEST_F(StrongBindingTest, ExplicitImplDeletionIsSafe) {
|
| sample::ServicePtr ptr;
|
| bool was_deleted = false;
|
| - // Will delete itself.
|
| - base::RunLoop run_loop;
|
| - new ServiceImplWithBinding(&was_deleted, run_loop.QuitClosure(),
|
| - GetProxy(&ptr));
|
|
|
| - base::RunLoop().RunUntilIdle();
|
| - EXPECT_FALSE(was_deleted);
|
| + base::Closure close_callback;
|
| +
|
| + std::unique_ptr<ServiceImpl> impl =
|
| + base::MakeUnique<ServiceImpl>(&was_deleted);
|
| + ServiceImpl* raw_impl = impl.get();
|
| + StrongBindingPtr<sample::Service> weak_binding =
|
| + mojo::MakeStrongBinding(std::move(impl), GetProxy(&ptr));
|
|
|
| - ptr.reset();
|
| EXPECT_FALSE(was_deleted);
|
| - run_loop.Run();
|
| +
|
| + base::RunLoop run_loop;
|
| + ptr.set_connection_error_handler(run_loop.QuitClosure());
|
| +
|
| + EXPECT_TRUE(weak_binding);
|
| +
|
| + delete raw_impl;
|
| +
|
| EXPECT_TRUE(was_deleted);
|
| + EXPECT_FALSE(weak_binding);
|
| +
|
| + run_loop.Run();
|
| }
|
|
|
| TEST_F(StrongBindingTest, FlushForTesting) {
|
|
|