diff options
author | sky <sky@chromium.org> | 2016-01-06 12:56:53 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-01-06 20:57:50 +0000 |
commit | bed273db7a0dbd855ecd7b897f7e56e0557f742f (patch) | |
tree | e752b40bf41d018e7d50ab1f60faf5303bec7b5c /mojo | |
parent | c7c88b0bc5fa6020c4d5befa1f09ba6e98c02479 (diff) | |
download | chromium_src-bed273db7a0dbd855ecd7b897f7e56e0557f742f.zip chromium_src-bed273db7a0dbd855ecd7b897f7e56e0557f742f.tar.gz chromium_src-bed273db7a0dbd855ecd7b897f7e56e0557f742f.tar.bz2 |
Fixes bug in pausing connector with multiple messages queued up
Prior to this patch if there were multiple messages queued up and in
processing one of the queued messages the connector was paused, we
would continue processing the messages. After this patch we stop
processing if paused after dispatch.
BUG=none
TEST=covered by test
R=yzshen@chromium.org
Review URL: https://codereview.chromium.org/1565763003
Cr-Commit-Position: refs/heads/master@{#367902}
Diffstat (limited to 'mojo')
-rw-r--r-- | mojo/public/cpp/bindings/lib/connector.cc | 6 | ||||
-rw-r--r-- | mojo/public/cpp/bindings/tests/connector_unittest.cc | 40 | ||||
-rw-r--r-- | mojo/public/cpp/bindings/tests/message_queue.h | 2 |
3 files changed, 44 insertions, 4 deletions
diff --git a/mojo/public/cpp/bindings/lib/connector.cc b/mojo/public/cpp/bindings/lib/connector.cc index e6f2d83..854a80c 100644 --- a/mojo/public/cpp/bindings/lib/connector.cc +++ b/mojo/public/cpp/bindings/lib/connector.cc @@ -212,6 +212,7 @@ void Connector::OnHandleReady(MojoResult result) { void Connector::WaitToReadMore() { CHECK(!async_wait_id_); + CHECK(!paused_); async_wait_id_ = waiter_->AsyncWait(message_pipe_.get().value(), MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE, @@ -220,6 +221,8 @@ void Connector::WaitToReadMore() { } bool Connector::ReadSingleMessage(MojoResult* read_result) { + CHECK(!paused_); + bool receiver_result = false; // Detect if |this| was destroyed during message dispatch. Allow for the @@ -263,6 +266,9 @@ void Connector::ReadAllAvailableMessages() { if (!ReadSingleMessage(&rv)) return; + if (paused_) + return; + if (rv == MOJO_RESULT_SHOULD_WAIT) { // ReadSingleMessage could end up calling HandleError which resets // message_pipe_ to a dummy one that is closed. The old EDK will see the diff --git a/mojo/public/cpp/bindings/tests/connector_unittest.cc b/mojo/public/cpp/bindings/tests/connector_unittest.cc index 6669764..879abfa 100644 --- a/mojo/public/cpp/bindings/tests/connector_unittest.cc +++ b/mojo/public/cpp/bindings/tests/connector_unittest.cc @@ -24,14 +24,13 @@ namespace { class MessageAccumulator : public MessageReceiver { public: MessageAccumulator() {} - explicit MessageAccumulator(const base::Closure& closure) - : closure_(closure) {} + explicit MessageAccumulator(const Closure& closure) : closure_(closure) {} bool Accept(Message* message) override { queue_.Push(message); if (!closure_.is_null()) closure_.Run(); - closure_.Reset(); + closure_.reset(); return true; } @@ -43,9 +42,11 @@ class MessageAccumulator : public MessageReceiver { closure_ = closure; } + size_t size() const { return queue_.size(); } + private: MessageQueue queue_; - base::Closure closure_; + Closure closure_; }; class ConnectorDeletingMessageAccumulator : public MessageAccumulator { @@ -494,6 +495,37 @@ TEST_F(ConnectorTest, RaiseError) { EXPECT_TRUE(connector1.is_valid()); } +TEST_F(ConnectorTest, PauseWithQueuedMessages) { + internal::Connector connector0(std::move(handle0_), + internal::Connector::SINGLE_THREADED_SEND); + internal::Connector connector1(std::move(handle1_), + internal::Connector::SINGLE_THREADED_SEND); + + const char kText[] = "hello world"; + + Message message; + AllocMessage(kText, &message); + + // Queue up two messages. + connector0.Accept(&message); + connector0.Accept(&message); + + base::RunLoop run_loop; + // Configure the accumulator such that it pauses after the first message is + // received. + MessageAccumulator accumulator([&connector1, &run_loop]() { + connector1.PauseIncomingMethodCallProcessing(); + run_loop.Quit(); + }); + connector1.set_incoming_receiver(&accumulator); + + run_loop.Run(); + + // As we paused after the first message we should only have gotten one + // message. + ASSERT_EQ(1u, accumulator.size()); +} + } // namespace } // namespace test } // namespace mojo diff --git a/mojo/public/cpp/bindings/tests/message_queue.h b/mojo/public/cpp/bindings/tests/message_queue.h index c3091db..823758d 100644 --- a/mojo/public/cpp/bindings/tests/message_queue.h +++ b/mojo/public/cpp/bindings/tests/message_queue.h @@ -29,6 +29,8 @@ class MessageQueue { // ownership of its handles to the given |message|. void Pop(Message* message); + size_t size() const { return queue_.size(); } + private: void Pop(); |