OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ipc/mojo/async_handle_waiter.h" | 5 #include "ipc/mojo/async_handle_waiter.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
9 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
10 #include "base/threading/thread.h" | 10 #include "base/threading/thread.h" |
11 #include "testing/gtest/include/gtest/gtest.h" | 11 #include "testing/gtest/include/gtest/gtest.h" |
12 #include "third_party/mojo/src/mojo/public/cpp/system/message_pipe.h" | 12 #include "third_party/mojo/src/mojo/public/cpp/system/message_pipe.h" |
13 | 13 |
14 namespace IPC { | 14 namespace IPC { |
15 namespace internal { | 15 namespace internal { |
16 namespace { | 16 namespace { |
17 | 17 |
18 void ReadOneByteOfX(MojoHandle pipe) { | 18 void ReadOneByteOfX(MojoHandle pipe) { |
19 uint32_t size = 1; | 19 uint32_t size = 1; |
20 char buffer = ' '; | 20 char buffer = ' '; |
21 MojoResult rv = MojoReadMessage(pipe, &buffer, &size, nullptr, nullptr, | 21 MojoResult rv = MojoReadMessage(pipe, &buffer, &size, nullptr, nullptr, |
22 MOJO_READ_MESSAGE_FLAG_NONE); | 22 MOJO_READ_MESSAGE_FLAG_NONE); |
23 CHECK_EQ(rv, MOJO_RESULT_OK); | 23 CHECK_EQ(rv, MOJO_RESULT_OK); |
24 CHECK_EQ(size, 1U); | 24 CHECK_EQ(size, 1U); |
25 CHECK_EQ(buffer, 'X'); | 25 CHECK_EQ(buffer, 'X'); |
26 } | 26 } |
27 | 27 |
28 class AsyncHandleWaiterTest : public testing::Test { | 28 class AsyncHandleWaiterTest : public testing::Test, |
| 29 public AsyncHandleWaiter::Delegate { |
29 public: | 30 public: |
30 AsyncHandleWaiterTest() : worker_("test_worker") { | 31 AsyncHandleWaiterTest() : worker_("test_worker") { |
31 worker_.StartWithOptions( | 32 worker_.StartWithOptions( |
32 base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); | 33 base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); |
33 } | 34 } |
34 | 35 |
35 void SetUp() override { | 36 void SetUp() override { |
36 message_loop_.reset(new base::MessageLoopForIO()); | 37 message_loop_.reset(new base::MessageLoopForIO()); |
37 ResetSignaledStates(); | 38 ResetSignaledStates(); |
38 mojo::CreateMessagePipe(nullptr, &pipe_to_write_, &pipe_to_read_); | 39 mojo::CreateMessagePipe(nullptr, &pipe_to_write_, &pipe_to_read_); |
39 target_.reset(new AsyncHandleWaiter(base::Bind( | 40 target_.reset(new AsyncHandleWaiter(this)); |
40 &AsyncHandleWaiterTest::HandleIsReady, base::Unretained(this)))); | |
41 } | 41 } |
42 | 42 |
43 protected: | 43 protected: |
44 MojoResult Start() { | 44 MojoResult Start() { |
45 return target_->Wait(pipe_to_read_.get().value(), | 45 return target_->Wait(pipe_to_read_.get().value(), |
46 MOJO_HANDLE_SIGNAL_READABLE); | 46 MOJO_HANDLE_SIGNAL_READABLE); |
47 } | 47 } |
48 | 48 |
49 void ResetSignaledStates() { | 49 void ResetSignaledStates() { |
50 signaled_result_ = MOJO_RESULT_UNKNOWN; | 50 signaled_result_ = MOJO_RESULT_UNKNOWN; |
(...skipping 20 matching lines...) Expand all Loading... |
71 } | 71 } |
72 | 72 |
73 void WaitAndAssertNotSignaled() { | 73 void WaitAndAssertNotSignaled() { |
74 run_loop_->RunUntilIdle(); | 74 run_loop_->RunUntilIdle(); |
75 EXPECT_EQ(MOJO_RESULT_OK, MojoWait(pipe_to_read_.get().value(), | 75 EXPECT_EQ(MOJO_RESULT_OK, MojoWait(pipe_to_read_.get().value(), |
76 MOJO_HANDLE_SIGNAL_READABLE, 0, | 76 MOJO_HANDLE_SIGNAL_READABLE, 0, |
77 nullptr)); | 77 nullptr)); |
78 EXPECT_EQ(MOJO_RESULT_UNKNOWN, signaled_result_); | 78 EXPECT_EQ(MOJO_RESULT_UNKNOWN, signaled_result_); |
79 } | 79 } |
80 | 80 |
81 void HandleIsReady(MojoResult result) { | 81 void MessageWasArrived(const void* bytes, uint32_t num_bytes) override { |
| 82 EXPECT_TRUE(false); |
| 83 } |
| 84 |
| 85 void PipeIsReady(MojoResult result) override { |
82 CHECK_EQ(base::MessageLoop::current(), message_loop_.get()); | 86 CHECK_EQ(base::MessageLoop::current(), message_loop_.get()); |
83 CHECK_EQ(signaled_result_, MOJO_RESULT_UNKNOWN); | 87 CHECK_EQ(signaled_result_, MOJO_RESULT_UNKNOWN); |
84 signaled_result_ = result; | 88 signaled_result_ = result; |
85 run_loop_->Quit(); | 89 run_loop_->Quit(); |
86 } | 90 } |
87 | 91 |
88 base::Thread worker_; | 92 base::Thread worker_; |
89 scoped_ptr<base::MessageLoop> message_loop_; | 93 scoped_ptr<base::MessageLoop> message_loop_; |
90 scoped_ptr<base::RunLoop> run_loop_; | 94 scoped_ptr<base::RunLoop> run_loop_; |
91 mojo::ScopedMessagePipeHandle pipe_to_write_; | 95 mojo::ScopedMessagePipeHandle pipe_to_write_; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 | 136 |
133 TEST_F(AsyncHandleWaiterTest, DeleteWaiterBeforeSignal) { | 137 TEST_F(AsyncHandleWaiterTest, DeleteWaiterBeforeSignal) { |
134 EXPECT_EQ(MOJO_RESULT_OK, Start()); | 138 EXPECT_EQ(MOJO_RESULT_OK, Start()); |
135 WriteToPipe(); | 139 WriteToPipe(); |
136 | 140 |
137 target_.reset(); | 141 target_.reset(); |
138 | 142 |
139 WaitAndAssertNotSignaled(); | 143 WaitAndAssertNotSignaled(); |
140 } | 144 } |
141 | 145 |
142 class HandlerThatReenters { | 146 class HandlerThatReenters : public AsyncHandleWaiter::Delegate { |
143 public: | 147 public: |
144 HandlerThatReenters(base::RunLoop* loop, MojoHandle handle) | 148 HandlerThatReenters(base::RunLoop* loop, MojoHandle handle) |
145 : target_(nullptr), handle_(handle), loop_(loop), step_(0) {} | 149 : target_(nullptr), handle_(handle), loop_(loop), step_(0) {} |
146 | 150 |
147 void set_target(AsyncHandleWaiter* target) { target_ = target; } | 151 void set_target(AsyncHandleWaiter* target) { target_ = target; } |
148 | 152 |
149 void HandleIsReady(MojoResult result) { | 153 void MessageWasArrived(const void* bytes, uint32_t num_bytes) override { |
| 154 CHECK(false); |
| 155 } |
| 156 |
| 157 void PipeIsReady(MojoResult result) override { |
150 switch (step_) { | 158 switch (step_) { |
151 case 0: | 159 case 0: |
152 RestartAndClose(result); | 160 RestartAndClose(result); |
153 break; | 161 break; |
154 case 1: | 162 case 1: |
155 HandleClosingSignal(result); | 163 HandleClosingSignal(result); |
156 break; | 164 break; |
157 default: | 165 default: |
158 NOTREACHED(); | 166 NOTREACHED(); |
159 break; | 167 break; |
(...skipping 23 matching lines...) Expand all Loading... |
183 bool IsClosingHandled() const { return step_ == 2; } | 191 bool IsClosingHandled() const { return step_ == 2; } |
184 | 192 |
185 AsyncHandleWaiter* target_; | 193 AsyncHandleWaiter* target_; |
186 MojoHandle handle_; | 194 MojoHandle handle_; |
187 base::RunLoop* loop_; | 195 base::RunLoop* loop_; |
188 int step_; | 196 int step_; |
189 }; | 197 }; |
190 | 198 |
191 TEST_F(AsyncHandleWaiterTest, RestartWaitingWhileSignaled) { | 199 TEST_F(AsyncHandleWaiterTest, RestartWaitingWhileSignaled) { |
192 HandlerThatReenters handler(run_loop_.get(), pipe_to_read_.get().value()); | 200 HandlerThatReenters handler(run_loop_.get(), pipe_to_read_.get().value()); |
193 target_.reset(new AsyncHandleWaiter(base::Bind( | 201 target_.reset(new AsyncHandleWaiter(&handler)); |
194 &HandlerThatReenters::HandleIsReady, base::Unretained(&handler)))); | |
195 handler.set_target(target_.get()); | 202 handler.set_target(target_.get()); |
196 | 203 |
197 EXPECT_EQ(MOJO_RESULT_OK, Start()); | 204 EXPECT_EQ(MOJO_RESULT_OK, Start()); |
198 WriteToPipe(); | 205 WriteToPipe(); |
199 run_loop_->Run(); | 206 run_loop_->Run(); |
200 | 207 |
201 EXPECT_TRUE(handler.IsClosingHandled()); | 208 EXPECT_TRUE(handler.IsClosingHandled()); |
202 | 209 |
203 // |HandlerThatReenters::RestartAndClose| already closed it. | 210 // |HandlerThatReenters::RestartAndClose| already closed it. |
204 ignore_result(pipe_to_read_.release()); | 211 ignore_result(pipe_to_read_.release()); |
205 } | 212 } |
206 | 213 |
207 } // namespace | 214 } // namespace |
208 } // namespace internal | 215 } // namespace internal |
209 } // namespace IPC | 216 } // namespace IPC |
OLD | NEW |