Index: mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc |
diff --git a/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc b/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc |
index bce17b4273d27ad9b391ac742b7756f9bb408eb5..aac1cb463a38441bc551b82194af20cd0b387a61 100644 |
--- a/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc |
+++ b/mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc |
@@ -5,7 +5,9 @@ |
#include <stdint.h> |
#include <utility> |
+#include "base/bind.h" |
#include "base/message_loop/message_loop.h" |
+#include "base/run_loop.h" |
#include "mojo/message_pump/message_pump_mojo.h" |
#include "mojo/public/cpp/bindings/binding.h" |
#include "mojo/public/cpp/bindings/strong_binding.h" |
@@ -75,31 +77,41 @@ class MathCalculatorUI { |
public: |
explicit MathCalculatorUI(math::CalculatorPtr calculator) |
: calculator_(std::move(calculator)), |
- output_(0.0), |
- callback_(MakeRunnable(&MathCalculatorUI::Output, this)) {} |
+ output_(0.0) {} |
bool WaitForIncomingResponse() { |
return calculator_.WaitForIncomingResponse(); |
} |
bool encountered_error() const { return calculator_.encountered_error(); } |
+ void set_connection_error_handler(const base::Closure& closure) { |
+ calculator_.set_connection_error_handler(closure); |
+ } |
- void Add(double value) { calculator_->Add(value, callback_); } |
- |
- void Subtract(double value) { calculator_->Add(-value, callback_); } |
- |
- void Multiply(double value) { calculator_->Multiply(value, callback_); } |
+ void Add(double value, const base::Closure& closure) { |
+ calculator_->Add( |
+ value, |
+ base::Bind(&MathCalculatorUI::Output, base::Unretained(this), closure)); |
+ } |
- void Divide(double value) { calculator_->Multiply(1.0 / value, callback_); } |
+ void Multiply(double value, const base::Closure& closure) { |
+ calculator_->Multiply( |
+ value, |
+ base::Bind(&MathCalculatorUI::Output, base::Unretained(this), closure)); |
+ } |
double GetOutput() const { return output_; } |
private: |
- void Output(double output) { output_ = output; } |
+ void Output(const base::Closure& closure, double output) { |
+ output_ = output; |
+ if (!closure.is_null()) |
+ closure.Run(); |
+ } |
math::CalculatorPtr calculator_; |
double output_; |
- Callback<void(double)> callback_; |
+ base::Closure closure_; |
}; |
class SelfDestructingMathCalculatorUI { |
@@ -109,21 +121,25 @@ class SelfDestructingMathCalculatorUI { |
++num_instances_; |
} |
- void BeginTest(bool nested) { |
+ void BeginTest(bool nested, const base::Closure& closure) { |
nesting_level_ = nested ? 2 : 1; |
calculator_->Add( |
- 1.0, MakeRunnable(&SelfDestructingMathCalculatorUI::Output, this)); |
+ 1.0, |
+ base::Bind(&SelfDestructingMathCalculatorUI::Output, |
+ base::Unretained(this), closure)); |
} |
static int num_instances() { return num_instances_; } |
- void Output(double value) { |
+ void Output(const base::Closure& closure, double value) { |
if (--nesting_level_ > 0) { |
// Add some more and wait for re-entrant call to Output! |
calculator_->Add( |
- 1.0, MakeRunnable(&SelfDestructingMathCalculatorUI::Output, this)); |
- base::MessageLoop::current()->RunUntilIdle(); |
+ 1.0, |
+ base::Bind(&SelfDestructingMathCalculatorUI::Output, |
+ base::Unretained(this), closure)); |
} else { |
+ closure.Run(); |
delete this; |
} |
} |
@@ -177,14 +193,23 @@ class IntegerAccessorImpl : public sample::IntegerAccessor { |
int64_t integer() const { return integer_; } |
+ void set_closure(const base::Closure& closure) { closure_ = closure; } |
+ |
private: |
// sample::IntegerAccessor implementation. |
void GetInteger(const GetIntegerCallback& callback) override { |
callback.Run(integer_, sample::ENUM_VALUE); |
} |
- void SetInteger(int64_t data, sample::Enum type) override { integer_ = data; } |
+ void SetInteger(int64_t data, sample::Enum type) override { |
+ integer_ = data; |
+ if (!closure_.is_null()) { |
+ closure_.Run(); |
+ closure_.Reset(); |
+ } |
+ } |
int64_t integer_; |
+ base::Closure closure_; |
}; |
class InterfacePtrTest : public testing::Test { |
@@ -212,10 +237,11 @@ TEST_F(InterfacePtrTest, EndToEnd) { |
// Suppose this is instantiated in a process that has pipe1_. |
MathCalculatorUI calculator_ui(std::move(calc)); |
- calculator_ui.Add(2.0); |
- calculator_ui.Multiply(5.0); |
- |
- PumpMessages(); |
+ base::RunLoop run_loop, run_loop2; |
+ calculator_ui.Add(2.0, run_loop.QuitClosure()); |
+ calculator_ui.Multiply(5.0, run_loop2.QuitClosure()); |
+ run_loop.Run(); |
+ run_loop2.Run(); |
EXPECT_EQ(10.0, calculator_ui.GetOutput()); |
} |
@@ -229,13 +255,13 @@ TEST_F(InterfacePtrTest, EndToEnd_Synchronous) { |
EXPECT_EQ(0.0, calculator_ui.GetOutput()); |
- calculator_ui.Add(2.0); |
+ calculator_ui.Add(2.0, base::Closure()); |
EXPECT_EQ(0.0, calculator_ui.GetOutput()); |
calc_impl.WaitForIncomingMethodCall(); |
calculator_ui.WaitForIncomingResponse(); |
EXPECT_EQ(2.0, calculator_ui.GetOutput()); |
- calculator_ui.Multiply(5.0); |
+ calculator_ui.Multiply(5.0, base::Closure()); |
EXPECT_EQ(2.0, calculator_ui.GetOutput()); |
calc_impl.WaitForIncomingMethodCall(); |
calculator_ui.WaitForIncomingResponse(); |
@@ -296,21 +322,24 @@ TEST_F(InterfacePtrTest, EncounteredError) { |
MathCalculatorUI calculator_ui(std::move(proxy)); |
- calculator_ui.Add(2.0); |
- PumpMessages(); |
+ base::RunLoop run_loop; |
+ calculator_ui.Add(2.0, run_loop.QuitClosure()); |
+ run_loop.Run(); |
EXPECT_EQ(2.0, calculator_ui.GetOutput()); |
EXPECT_FALSE(calculator_ui.encountered_error()); |
- calculator_ui.Multiply(5.0); |
+ calculator_ui.Multiply(5.0, base::Closure()); |
EXPECT_FALSE(calculator_ui.encountered_error()); |
// Close the server. |
calc_impl.CloseMessagePipe(); |
// The state change isn't picked up locally yet. |
+ base::RunLoop run_loop2; |
+ calculator_ui.set_connection_error_handler(run_loop2.QuitClosure()); |
EXPECT_FALSE(calculator_ui.encountered_error()); |
- PumpMessages(); |
+ run_loop2.Run(); |
// OK, now we see the error. |
EXPECT_TRUE(calculator_ui.encountered_error()); |
@@ -321,17 +350,22 @@ TEST_F(InterfacePtrTest, EncounteredErrorCallback) { |
MathCalculatorImpl calc_impl(GetProxy(&proxy)); |
bool encountered_error = false; |
+ base::RunLoop run_loop; |
proxy.set_connection_error_handler( |
- [&encountered_error]() { encountered_error = true; }); |
+ [&encountered_error, &run_loop]() { |
+ encountered_error = true; |
+ run_loop.Quit(); |
+ }); |
MathCalculatorUI calculator_ui(std::move(proxy)); |
- calculator_ui.Add(2.0); |
- PumpMessages(); |
+ base::RunLoop run_loop2; |
+ calculator_ui.Add(2.0, run_loop2.QuitClosure()); |
+ run_loop2.Run(); |
EXPECT_EQ(2.0, calculator_ui.GetOutput()); |
EXPECT_FALSE(calculator_ui.encountered_error()); |
- calculator_ui.Multiply(5.0); |
+ calculator_ui.Multiply(5.0, base::Closure()); |
EXPECT_FALSE(calculator_ui.encountered_error()); |
// Close the server. |
@@ -340,7 +374,7 @@ TEST_F(InterfacePtrTest, EncounteredErrorCallback) { |
// The state change isn't picked up locally yet. |
EXPECT_FALSE(calculator_ui.encountered_error()); |
- PumpMessages(); |
+ run_loop.Run(); |
// OK, now we see the error. |
EXPECT_TRUE(calculator_ui.encountered_error()); |
@@ -358,9 +392,9 @@ TEST_F(InterfacePtrTest, DestroyInterfacePtrOnMethodResponse) { |
SelfDestructingMathCalculatorUI* impl = |
new SelfDestructingMathCalculatorUI(std::move(proxy)); |
- impl->BeginTest(false); |
- |
- PumpMessages(); |
+ base::RunLoop run_loop; |
+ impl->BeginTest(false, run_loop.QuitClosure()); |
+ run_loop.Run(); |
EXPECT_EQ(0, SelfDestructingMathCalculatorUI::num_instances()); |
} |
@@ -373,9 +407,9 @@ TEST_F(InterfacePtrTest, NestedDestroyInterfacePtrOnMethodResponse) { |
SelfDestructingMathCalculatorUI* impl = |
new SelfDestructingMathCalculatorUI(std::move(proxy)); |
- impl->BeginTest(true); |
- |
- PumpMessages(); |
+ base::RunLoop run_loop; |
+ impl->BeginTest(true, run_loop.QuitClosure()); |
+ run_loop.Run(); |
EXPECT_EQ(0, SelfDestructingMathCalculatorUI::num_instances()); |
} |
@@ -384,12 +418,16 @@ TEST_F(InterfacePtrTest, ReentrantWaitForIncomingMethodCall) { |
sample::ServicePtr proxy; |
ReentrantServiceImpl impl(GetProxy(&proxy)); |
+ base::RunLoop run_loop, run_loop2; |
+ auto called_cb = [&run_loop](int32_t result) { run_loop.Quit(); }; |
+ auto called_cb2 = [&run_loop2](int32_t result) { run_loop2.Quit(); }; |
proxy->Frobinate(nullptr, sample::Service::BAZ_OPTIONS_REGULAR, nullptr, |
- sample::Service::FrobinateCallback()); |
+ called_cb); |
proxy->Frobinate(nullptr, sample::Service::BAZ_OPTIONS_REGULAR, nullptr, |
- sample::Service::FrobinateCallback()); |
+ called_cb2); |
- PumpMessages(); |
+ run_loop.Run(); |
+ run_loop2.Run(); |
EXPECT_EQ(2, impl.max_call_depth()); |
} |
@@ -401,10 +439,14 @@ TEST_F(InterfacePtrTest, QueryVersion) { |
EXPECT_EQ(0u, ptr.version()); |
- auto callback = [](uint32_t version) { EXPECT_EQ(3u, version); }; |
+ base::RunLoop run_loop; |
+ auto callback = [&run_loop](uint32_t version) { |
+ EXPECT_EQ(3u, version); |
+ run_loop.Quit(); |
+ }; |
ptr.QueryVersion(callback); |
- PumpMessages(); |
+ run_loop.Run(); |
EXPECT_EQ(3u, ptr.version()); |
} |
@@ -418,15 +460,19 @@ TEST_F(InterfacePtrTest, RequireVersion) { |
ptr.RequireVersion(1u); |
EXPECT_EQ(1u, ptr.version()); |
+ base::RunLoop run_loop; |
+ impl.set_closure(run_loop.QuitClosure()); |
ptr->SetInteger(123, sample::ENUM_VALUE); |
- PumpMessages(); |
+ run_loop.Run(); |
EXPECT_FALSE(ptr.encountered_error()); |
EXPECT_EQ(123, impl.integer()); |
ptr.RequireVersion(3u); |
EXPECT_EQ(3u, ptr.version()); |
+ base::RunLoop run_loop2; |
+ impl.set_closure(run_loop2.QuitClosure()); |
ptr->SetInteger(456, sample::ENUM_VALUE); |
- PumpMessages(); |
+ run_loop2.Run(); |
EXPECT_FALSE(ptr.encountered_error()); |
EXPECT_EQ(456, impl.integer()); |
@@ -434,8 +480,10 @@ TEST_F(InterfacePtrTest, RequireVersion) { |
ptr.RequireVersion(4u); |
// This value is set to the input of RequireVersion() synchronously. |
EXPECT_EQ(4u, ptr.version()); |
+ base::RunLoop run_loop3; |
+ ptr.set_connection_error_handler(run_loop3.QuitClosure()); |
ptr->SetInteger(789, sample::ENUM_VALUE); |
- PumpMessages(); |
+ run_loop3.Run(); |
EXPECT_TRUE(ptr.encountered_error()); |
// The call to SetInteger() after RequireVersion(4u) is ignored. |
EXPECT_EQ(456, impl.integer()); |
@@ -445,12 +493,14 @@ class StrongMathCalculatorImpl : public math::Calculator { |
public: |
StrongMathCalculatorImpl(ScopedMessagePipeHandle handle, |
bool* error_received, |
- bool* destroyed) |
+ bool* destroyed, |
+ const base::Closure& closure) |
: error_received_(error_received), |
destroyed_(destroyed), |
+ closure_(closure), |
binding_(this, std::move(handle)) { |
binding_.set_connection_error_handler( |
- [this]() { *error_received_ = true; }); |
+ [this]() { *error_received_ = true; closure_.Run(); }); |
} |
~StrongMathCalculatorImpl() override { *destroyed_ = true; } |
@@ -471,6 +521,7 @@ class StrongMathCalculatorImpl : public math::Calculator { |
double total_ = 0.0; |
bool* error_received_; |
bool* destroyed_; |
+ base::Closure closure_; |
StrongBinding<math::Calculator> binding_; |
}; |
@@ -481,8 +532,9 @@ TEST(StrongConnectorTest, Math) { |
bool error_received = false; |
bool destroyed = false; |
MessagePipe pipe; |
+ base::RunLoop run_loop; |
new StrongMathCalculatorImpl(std::move(pipe.handle0), &error_received, |
- &destroyed); |
+ &destroyed, run_loop.QuitClosure()); |
math::CalculatorPtr calc; |
calc.Bind(InterfacePtrInfo<math::Calculator>(std::move(pipe.handle1), 0u)); |
@@ -492,10 +544,11 @@ TEST(StrongConnectorTest, Math) { |
// message pipe. |
MathCalculatorUI calculator_ui(std::move(calc)); |
- calculator_ui.Add(2.0); |
- calculator_ui.Multiply(5.0); |
- |
- loop.RunUntilIdle(); |
+ base::RunLoop run_loop, run_loop2; |
+ calculator_ui.Add(2.0, run_loop.QuitClosure()); |
+ calculator_ui.Multiply(5.0, run_loop2.QuitClosure()); |
+ run_loop.Run(); |
+ run_loop2.Run(); |
EXPECT_EQ(10.0, calculator_ui.GetOutput()); |
EXPECT_FALSE(error_received); |
@@ -505,7 +558,7 @@ TEST(StrongConnectorTest, Math) { |
// other |
// end which will destroy the instance since it is strongly bound. |
- loop.RunUntilIdle(); |
+ run_loop.Run(); |
EXPECT_TRUE(error_received); |
EXPECT_TRUE(destroyed); |
} |
@@ -514,12 +567,14 @@ class WeakMathCalculatorImpl : public math::Calculator { |
public: |
WeakMathCalculatorImpl(ScopedMessagePipeHandle handle, |
bool* error_received, |
- bool* destroyed) |
+ bool* destroyed, |
+ const base::Closure& closure) |
: error_received_(error_received), |
destroyed_(destroyed), |
+ closure_(closure), |
binding_(this, std::move(handle)) { |
binding_.set_connection_error_handler( |
- [this]() { *error_received_ = true; }); |
+ [this]() { *error_received_ = true; closure_.Run(); }); |
} |
~WeakMathCalculatorImpl() override { *destroyed_ = true; } |
@@ -539,6 +594,7 @@ class WeakMathCalculatorImpl : public math::Calculator { |
double total_ = 0.0; |
bool* error_received_; |
bool* destroyed_; |
+ base::Closure closure_; |
Binding<math::Calculator> binding_; |
}; |
@@ -549,8 +605,9 @@ TEST(WeakConnectorTest, Math) { |
bool error_received = false; |
bool destroyed = false; |
MessagePipe pipe; |
+ base::RunLoop run_loop; |
WeakMathCalculatorImpl impl(std::move(pipe.handle0), &error_received, |
- &destroyed); |
+ &destroyed, run_loop.QuitClosure()); |
math::CalculatorPtr calc; |
calc.Bind(InterfacePtrInfo<math::Calculator>(std::move(pipe.handle1), 0u)); |
@@ -560,10 +617,11 @@ TEST(WeakConnectorTest, Math) { |
// message pipe. |
MathCalculatorUI calculator_ui(std::move(calc)); |
- calculator_ui.Add(2.0); |
- calculator_ui.Multiply(5.0); |
- |
- loop.RunUntilIdle(); |
+ base::RunLoop run_loop, run_loop2; |
+ calculator_ui.Add(2.0, run_loop.QuitClosure()); |
+ calculator_ui.Multiply(5.0, run_loop2.QuitClosure()); |
+ run_loop.Run(); |
+ run_loop2.Run(); |
EXPECT_EQ(10.0, calculator_ui.GetOutput()); |
EXPECT_FALSE(error_received); |
@@ -573,61 +631,71 @@ TEST(WeakConnectorTest, Math) { |
// end which will destroy the instance since it is strongly bound. |
} |
- loop.RunUntilIdle(); |
+ run_loop.Run(); |
EXPECT_TRUE(error_received); |
EXPECT_FALSE(destroyed); |
} |
class CImpl : public C { |
public: |
- CImpl(bool* d_called, InterfaceRequest<C> request) |
- : d_called_(d_called), binding_(this, std::move(request)) {} |
+ CImpl(bool* d_called, InterfaceRequest<C> request, |
+ const base::Closure& closure) |
+ : d_called_(d_called), binding_(this, std::move(request)), |
+ closure_(closure) {} |
~CImpl() override {} |
private: |
void D() override { |
*d_called_ = true; |
+ closure_.Run(); |
} |
bool* d_called_; |
StrongBinding<C> binding_; |
+ base::Closure closure_; |
}; |
class BImpl : public B { |
public: |
- BImpl(bool* d_called, InterfaceRequest<B> request) |
- : d_called_(d_called), binding_(this, std::move(request)) {} |
+ BImpl(bool* d_called, InterfaceRequest<B> request, |
+ const base::Closure& closure) |
+ : d_called_(d_called), binding_(this, std::move(request)), |
+ closure_(closure) {} |
~BImpl() override {} |
private: |
void GetC(InterfaceRequest<C> c) override { |
- new CImpl(d_called_, std::move(c)); |
+ new CImpl(d_called_, std::move(c), closure_); |
} |
bool* d_called_; |
StrongBinding<B> binding_; |
+ base::Closure closure_; |
}; |
class AImpl : public A { |
public: |
- explicit AImpl(InterfaceRequest<A> request) |
- : d_called_(false), binding_(this, std::move(request)) {} |
+ AImpl(InterfaceRequest<A> request, const base::Closure& closure) |
+ : d_called_(false), binding_(this, std::move(request)), |
+ closure_(closure) {} |
~AImpl() override {} |
bool d_called() const { return d_called_; } |
private: |
void GetB(InterfaceRequest<B> b) override { |
- new BImpl(&d_called_, std::move(b)); |
+ new BImpl(&d_called_, std::move(b), closure_); |
} |
bool d_called_; |
Binding<A> binding_; |
+ base::Closure closure_; |
}; |
TEST_F(InterfacePtrTest, Scoping) { |
APtr a; |
- AImpl a_impl(GetProxy(&a)); |
+ base::RunLoop run_loop; |
+ AImpl a_impl(GetProxy(&a), run_loop.QuitClosure()); |
EXPECT_FALSE(a_impl.d_called()); |
@@ -642,7 +710,7 @@ TEST_F(InterfacePtrTest, Scoping) { |
// While B & C have fallen out of scope, the pipes will remain until they are |
// flushed. |
EXPECT_FALSE(a_impl.d_called()); |
- PumpMessages(); |
+ run_loop.Run(); |
EXPECT_TRUE(a_impl.d_called()); |
} |