| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "mojo/public/cpp/bindings/lib/connector.h" | 5 #include "mojo/public/cpp/bindings/connector.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdlib.h> | 8 #include <stdlib.h> |
| 9 #include <string.h> | 9 #include <string.h> |
| 10 #include <utility> | 10 #include <utility> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/callback.h" | 13 #include "base/callback.h" |
| 14 #include "base/callback_helpers.h" | 14 #include "base/callback_helpers.h" |
| 15 #include "base/message_loop/message_loop.h" | 15 #include "base/message_loop/message_loop.h" |
| (...skipping 28 matching lines...) Expand all Loading... |
| 44 | 44 |
| 45 size_t size() const { return queue_.size(); } | 45 size_t size() const { return queue_.size(); } |
| 46 | 46 |
| 47 private: | 47 private: |
| 48 MessageQueue queue_; | 48 MessageQueue queue_; |
| 49 base::Closure closure_; | 49 base::Closure closure_; |
| 50 }; | 50 }; |
| 51 | 51 |
| 52 class ConnectorDeletingMessageAccumulator : public MessageAccumulator { | 52 class ConnectorDeletingMessageAccumulator : public MessageAccumulator { |
| 53 public: | 53 public: |
| 54 ConnectorDeletingMessageAccumulator(internal::Connector** connector) | 54 ConnectorDeletingMessageAccumulator(Connector** connector) |
| 55 : connector_(connector) {} | 55 : connector_(connector) {} |
| 56 | 56 |
| 57 bool Accept(Message* message) override { | 57 bool Accept(Message* message) override { |
| 58 delete *connector_; | 58 delete *connector_; |
| 59 *connector_ = nullptr; | 59 *connector_ = nullptr; |
| 60 return MessageAccumulator::Accept(message); | 60 return MessageAccumulator::Accept(message); |
| 61 } | 61 } |
| 62 | 62 |
| 63 private: | 63 private: |
| 64 internal::Connector** connector_; | 64 Connector** connector_; |
| 65 }; | 65 }; |
| 66 | 66 |
| 67 class ReentrantMessageAccumulator : public MessageAccumulator { | 67 class ReentrantMessageAccumulator : public MessageAccumulator { |
| 68 public: | 68 public: |
| 69 ReentrantMessageAccumulator(internal::Connector* connector) | 69 ReentrantMessageAccumulator(Connector* connector) |
| 70 : connector_(connector), number_of_calls_(0) {} | 70 : connector_(connector), number_of_calls_(0) {} |
| 71 | 71 |
| 72 bool Accept(Message* message) override { | 72 bool Accept(Message* message) override { |
| 73 if (!MessageAccumulator::Accept(message)) | 73 if (!MessageAccumulator::Accept(message)) |
| 74 return false; | 74 return false; |
| 75 number_of_calls_++; | 75 number_of_calls_++; |
| 76 if (number_of_calls_ == 1) { | 76 if (number_of_calls_ == 1) { |
| 77 return connector_->WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE); | 77 return connector_->WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE); |
| 78 } | 78 } |
| 79 return true; | 79 return true; |
| 80 } | 80 } |
| 81 | 81 |
| 82 int number_of_calls() { return number_of_calls_; } | 82 int number_of_calls() { return number_of_calls_; } |
| 83 | 83 |
| 84 private: | 84 private: |
| 85 internal::Connector* connector_; | 85 Connector* connector_; |
| 86 int number_of_calls_; | 86 int number_of_calls_; |
| 87 }; | 87 }; |
| 88 | 88 |
| 89 class ConnectorTest : public testing::Test { | 89 class ConnectorTest : public testing::Test { |
| 90 public: | 90 public: |
| 91 ConnectorTest() {} | 91 ConnectorTest() {} |
| 92 | 92 |
| 93 void SetUp() override { | 93 void SetUp() override { |
| 94 CreateMessagePipe(nullptr, &handle0_, &handle1_); | 94 CreateMessagePipe(nullptr, &handle0_, &handle1_); |
| 95 } | 95 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 106 | 106 |
| 107 protected: | 107 protected: |
| 108 ScopedMessagePipeHandle handle0_; | 108 ScopedMessagePipeHandle handle0_; |
| 109 ScopedMessagePipeHandle handle1_; | 109 ScopedMessagePipeHandle handle1_; |
| 110 | 110 |
| 111 private: | 111 private: |
| 112 base::MessageLoop loop_; | 112 base::MessageLoop loop_; |
| 113 }; | 113 }; |
| 114 | 114 |
| 115 TEST_F(ConnectorTest, Basic) { | 115 TEST_F(ConnectorTest, Basic) { |
| 116 internal::Connector connector0(std::move(handle0_), | 116 Connector connector0(std::move(handle0_), Connector::SINGLE_THREADED_SEND, |
| 117 internal::Connector::SINGLE_THREADED_SEND, | 117 base::ThreadTaskRunnerHandle::Get()); |
| 118 base::ThreadTaskRunnerHandle::Get()); | 118 Connector connector1(std::move(handle1_), Connector::SINGLE_THREADED_SEND, |
| 119 internal::Connector connector1(std::move(handle1_), | 119 base::ThreadTaskRunnerHandle::Get()); |
| 120 internal::Connector::SINGLE_THREADED_SEND, | |
| 121 base::ThreadTaskRunnerHandle::Get()); | |
| 122 | 120 |
| 123 const char kText[] = "hello world"; | 121 const char kText[] = "hello world"; |
| 124 | 122 |
| 125 Message message; | 123 Message message; |
| 126 AllocMessage(kText, &message); | 124 AllocMessage(kText, &message); |
| 127 | 125 |
| 128 connector0.Accept(&message); | 126 connector0.Accept(&message); |
| 129 | 127 |
| 130 base::RunLoop run_loop; | 128 base::RunLoop run_loop; |
| 131 MessageAccumulator accumulator(run_loop.QuitClosure()); | 129 MessageAccumulator accumulator(run_loop.QuitClosure()); |
| 132 connector1.set_incoming_receiver(&accumulator); | 130 connector1.set_incoming_receiver(&accumulator); |
| 133 | 131 |
| 134 run_loop.Run(); | 132 run_loop.Run(); |
| 135 | 133 |
| 136 ASSERT_FALSE(accumulator.IsEmpty()); | 134 ASSERT_FALSE(accumulator.IsEmpty()); |
| 137 | 135 |
| 138 Message message_received; | 136 Message message_received; |
| 139 accumulator.Pop(&message_received); | 137 accumulator.Pop(&message_received); |
| 140 | 138 |
| 141 EXPECT_EQ( | 139 EXPECT_EQ( |
| 142 std::string(kText), | 140 std::string(kText), |
| 143 std::string(reinterpret_cast<const char*>(message_received.payload()))); | 141 std::string(reinterpret_cast<const char*>(message_received.payload()))); |
| 144 } | 142 } |
| 145 | 143 |
| 146 TEST_F(ConnectorTest, Basic_Synchronous) { | 144 TEST_F(ConnectorTest, Basic_Synchronous) { |
| 147 internal::Connector connector0(std::move(handle0_), | 145 Connector connector0(std::move(handle0_), Connector::SINGLE_THREADED_SEND, |
| 148 internal::Connector::SINGLE_THREADED_SEND, | 146 base::ThreadTaskRunnerHandle::Get()); |
| 149 base::ThreadTaskRunnerHandle::Get()); | 147 Connector connector1(std::move(handle1_), Connector::SINGLE_THREADED_SEND, |
| 150 internal::Connector connector1(std::move(handle1_), | 148 base::ThreadTaskRunnerHandle::Get()); |
| 151 internal::Connector::SINGLE_THREADED_SEND, | |
| 152 base::ThreadTaskRunnerHandle::Get()); | |
| 153 | 149 |
| 154 const char kText[] = "hello world"; | 150 const char kText[] = "hello world"; |
| 155 | 151 |
| 156 Message message; | 152 Message message; |
| 157 AllocMessage(kText, &message); | 153 AllocMessage(kText, &message); |
| 158 | 154 |
| 159 connector0.Accept(&message); | 155 connector0.Accept(&message); |
| 160 | 156 |
| 161 MessageAccumulator accumulator; | 157 MessageAccumulator accumulator; |
| 162 connector1.set_incoming_receiver(&accumulator); | 158 connector1.set_incoming_receiver(&accumulator); |
| 163 | 159 |
| 164 connector1.WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE); | 160 connector1.WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE); |
| 165 | 161 |
| 166 ASSERT_FALSE(accumulator.IsEmpty()); | 162 ASSERT_FALSE(accumulator.IsEmpty()); |
| 167 | 163 |
| 168 Message message_received; | 164 Message message_received; |
| 169 accumulator.Pop(&message_received); | 165 accumulator.Pop(&message_received); |
| 170 | 166 |
| 171 EXPECT_EQ( | 167 EXPECT_EQ( |
| 172 std::string(kText), | 168 std::string(kText), |
| 173 std::string(reinterpret_cast<const char*>(message_received.payload()))); | 169 std::string(reinterpret_cast<const char*>(message_received.payload()))); |
| 174 } | 170 } |
| 175 | 171 |
| 176 TEST_F(ConnectorTest, Basic_EarlyIncomingReceiver) { | 172 TEST_F(ConnectorTest, Basic_EarlyIncomingReceiver) { |
| 177 internal::Connector connector0(std::move(handle0_), | 173 Connector connector0(std::move(handle0_), Connector::SINGLE_THREADED_SEND, |
| 178 internal::Connector::SINGLE_THREADED_SEND, | 174 base::ThreadTaskRunnerHandle::Get()); |
| 179 base::ThreadTaskRunnerHandle::Get()); | 175 Connector connector1(std::move(handle1_), Connector::SINGLE_THREADED_SEND, |
| 180 internal::Connector connector1(std::move(handle1_), | 176 base::ThreadTaskRunnerHandle::Get()); |
| 181 internal::Connector::SINGLE_THREADED_SEND, | |
| 182 base::ThreadTaskRunnerHandle::Get()); | |
| 183 | 177 |
| 184 base::RunLoop run_loop; | 178 base::RunLoop run_loop; |
| 185 MessageAccumulator accumulator(run_loop.QuitClosure()); | 179 MessageAccumulator accumulator(run_loop.QuitClosure()); |
| 186 connector1.set_incoming_receiver(&accumulator); | 180 connector1.set_incoming_receiver(&accumulator); |
| 187 | 181 |
| 188 const char kText[] = "hello world"; | 182 const char kText[] = "hello world"; |
| 189 | 183 |
| 190 Message message; | 184 Message message; |
| 191 AllocMessage(kText, &message); | 185 AllocMessage(kText, &message); |
| 192 | 186 |
| 193 connector0.Accept(&message); | 187 connector0.Accept(&message); |
| 194 | 188 |
| 195 run_loop.Run(); | 189 run_loop.Run(); |
| 196 | 190 |
| 197 ASSERT_FALSE(accumulator.IsEmpty()); | 191 ASSERT_FALSE(accumulator.IsEmpty()); |
| 198 | 192 |
| 199 Message message_received; | 193 Message message_received; |
| 200 accumulator.Pop(&message_received); | 194 accumulator.Pop(&message_received); |
| 201 | 195 |
| 202 EXPECT_EQ( | 196 EXPECT_EQ( |
| 203 std::string(kText), | 197 std::string(kText), |
| 204 std::string(reinterpret_cast<const char*>(message_received.payload()))); | 198 std::string(reinterpret_cast<const char*>(message_received.payload()))); |
| 205 } | 199 } |
| 206 | 200 |
| 207 TEST_F(ConnectorTest, Basic_TwoMessages) { | 201 TEST_F(ConnectorTest, Basic_TwoMessages) { |
| 208 internal::Connector connector0(std::move(handle0_), | 202 Connector connector0(std::move(handle0_), Connector::SINGLE_THREADED_SEND, |
| 209 internal::Connector::SINGLE_THREADED_SEND, | 203 base::ThreadTaskRunnerHandle::Get()); |
| 210 base::ThreadTaskRunnerHandle::Get()); | 204 Connector connector1(std::move(handle1_), Connector::SINGLE_THREADED_SEND, |
| 211 internal::Connector connector1(std::move(handle1_), | 205 base::ThreadTaskRunnerHandle::Get()); |
| 212 internal::Connector::SINGLE_THREADED_SEND, | |
| 213 base::ThreadTaskRunnerHandle::Get()); | |
| 214 | 206 |
| 215 const char* kText[] = {"hello", "world"}; | 207 const char* kText[] = {"hello", "world"}; |
| 216 | 208 |
| 217 for (size_t i = 0; i < arraysize(kText); ++i) { | 209 for (size_t i = 0; i < arraysize(kText); ++i) { |
| 218 Message message; | 210 Message message; |
| 219 AllocMessage(kText[i], &message); | 211 AllocMessage(kText[i], &message); |
| 220 | 212 |
| 221 connector0.Accept(&message); | 213 connector0.Accept(&message); |
| 222 } | 214 } |
| 223 | 215 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 235 Message message_received; | 227 Message message_received; |
| 236 accumulator.Pop(&message_received); | 228 accumulator.Pop(&message_received); |
| 237 | 229 |
| 238 EXPECT_EQ( | 230 EXPECT_EQ( |
| 239 std::string(kText[i]), | 231 std::string(kText[i]), |
| 240 std::string(reinterpret_cast<const char*>(message_received.payload()))); | 232 std::string(reinterpret_cast<const char*>(message_received.payload()))); |
| 241 } | 233 } |
| 242 } | 234 } |
| 243 | 235 |
| 244 TEST_F(ConnectorTest, Basic_TwoMessages_Synchronous) { | 236 TEST_F(ConnectorTest, Basic_TwoMessages_Synchronous) { |
| 245 internal::Connector connector0(std::move(handle0_), | 237 Connector connector0(std::move(handle0_), Connector::SINGLE_THREADED_SEND, |
| 246 internal::Connector::SINGLE_THREADED_SEND, | 238 base::ThreadTaskRunnerHandle::Get()); |
| 247 base::ThreadTaskRunnerHandle::Get()); | 239 Connector connector1(std::move(handle1_), Connector::SINGLE_THREADED_SEND, |
| 248 internal::Connector connector1(std::move(handle1_), | 240 base::ThreadTaskRunnerHandle::Get()); |
| 249 internal::Connector::SINGLE_THREADED_SEND, | |
| 250 base::ThreadTaskRunnerHandle::Get()); | |
| 251 | 241 |
| 252 const char* kText[] = {"hello", "world"}; | 242 const char* kText[] = {"hello", "world"}; |
| 253 | 243 |
| 254 for (size_t i = 0; i < arraysize(kText); ++i) { | 244 for (size_t i = 0; i < arraysize(kText); ++i) { |
| 255 Message message; | 245 Message message; |
| 256 AllocMessage(kText[i], &message); | 246 AllocMessage(kText[i], &message); |
| 257 | 247 |
| 258 connector0.Accept(&message); | 248 connector0.Accept(&message); |
| 259 } | 249 } |
| 260 | 250 |
| 261 MessageAccumulator accumulator; | 251 MessageAccumulator accumulator; |
| 262 connector1.set_incoming_receiver(&accumulator); | 252 connector1.set_incoming_receiver(&accumulator); |
| 263 | 253 |
| 264 connector1.WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE); | 254 connector1.WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE); |
| 265 | 255 |
| 266 ASSERT_FALSE(accumulator.IsEmpty()); | 256 ASSERT_FALSE(accumulator.IsEmpty()); |
| 267 | 257 |
| 268 Message message_received; | 258 Message message_received; |
| 269 accumulator.Pop(&message_received); | 259 accumulator.Pop(&message_received); |
| 270 | 260 |
| 271 EXPECT_EQ( | 261 EXPECT_EQ( |
| 272 std::string(kText[0]), | 262 std::string(kText[0]), |
| 273 std::string(reinterpret_cast<const char*>(message_received.payload()))); | 263 std::string(reinterpret_cast<const char*>(message_received.payload()))); |
| 274 | 264 |
| 275 ASSERT_TRUE(accumulator.IsEmpty()); | 265 ASSERT_TRUE(accumulator.IsEmpty()); |
| 276 } | 266 } |
| 277 | 267 |
| 278 TEST_F(ConnectorTest, WriteToClosedPipe) { | 268 TEST_F(ConnectorTest, WriteToClosedPipe) { |
| 279 internal::Connector connector0(std::move(handle0_), | 269 Connector connector0(std::move(handle0_), Connector::SINGLE_THREADED_SEND, |
| 280 internal::Connector::SINGLE_THREADED_SEND, | 270 base::ThreadTaskRunnerHandle::Get()); |
| 281 base::ThreadTaskRunnerHandle::Get()); | |
| 282 | 271 |
| 283 const char kText[] = "hello world"; | 272 const char kText[] = "hello world"; |
| 284 | 273 |
| 285 Message message; | 274 Message message; |
| 286 AllocMessage(kText, &message); | 275 AllocMessage(kText, &message); |
| 287 | 276 |
| 288 // Close the other end of the pipe. | 277 // Close the other end of the pipe. |
| 289 handle1_.reset(); | 278 handle1_.reset(); |
| 290 | 279 |
| 291 // Not observed yet because we haven't spun the message loop yet. | 280 // Not observed yet because we haven't spun the message loop yet. |
| 292 EXPECT_FALSE(connector0.encountered_error()); | 281 EXPECT_FALSE(connector0.encountered_error()); |
| 293 | 282 |
| 294 // Write failures are not reported. | 283 // Write failures are not reported. |
| 295 bool ok = connector0.Accept(&message); | 284 bool ok = connector0.Accept(&message); |
| 296 EXPECT_TRUE(ok); | 285 EXPECT_TRUE(ok); |
| 297 | 286 |
| 298 // Still not observed. | 287 // Still not observed. |
| 299 EXPECT_FALSE(connector0.encountered_error()); | 288 EXPECT_FALSE(connector0.encountered_error()); |
| 300 | 289 |
| 301 // Spin the message loop, and then we should start observing the closed pipe. | 290 // Spin the message loop, and then we should start observing the closed pipe. |
| 302 base::RunLoop run_loop; | 291 base::RunLoop run_loop; |
| 303 connector0.set_connection_error_handler(run_loop.QuitClosure()); | 292 connector0.set_connection_error_handler(run_loop.QuitClosure()); |
| 304 run_loop.Run(); | 293 run_loop.Run(); |
| 305 | 294 |
| 306 EXPECT_TRUE(connector0.encountered_error()); | 295 EXPECT_TRUE(connector0.encountered_error()); |
| 307 } | 296 } |
| 308 | 297 |
| 309 TEST_F(ConnectorTest, MessageWithHandles) { | 298 TEST_F(ConnectorTest, MessageWithHandles) { |
| 310 internal::Connector connector0(std::move(handle0_), | 299 Connector connector0(std::move(handle0_), Connector::SINGLE_THREADED_SEND, |
| 311 internal::Connector::SINGLE_THREADED_SEND, | 300 base::ThreadTaskRunnerHandle::Get()); |
| 312 base::ThreadTaskRunnerHandle::Get()); | 301 Connector connector1(std::move(handle1_), Connector::SINGLE_THREADED_SEND, |
| 313 internal::Connector connector1(std::move(handle1_), | 302 base::ThreadTaskRunnerHandle::Get()); |
| 314 internal::Connector::SINGLE_THREADED_SEND, | |
| 315 base::ThreadTaskRunnerHandle::Get()); | |
| 316 | 303 |
| 317 const char kText[] = "hello world"; | 304 const char kText[] = "hello world"; |
| 318 | 305 |
| 319 Message message1; | 306 Message message1; |
| 320 AllocMessage(kText, &message1); | 307 AllocMessage(kText, &message1); |
| 321 | 308 |
| 322 MessagePipe pipe; | 309 MessagePipe pipe; |
| 323 message1.mutable_handles()->push_back(pipe.handle0.release()); | 310 message1.mutable_handles()->push_back(pipe.handle0.release()); |
| 324 | 311 |
| 325 connector0.Accept(&message1); | 312 connector0.Accept(&message1); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 344 ASSERT_EQ(1U, message_received.handles()->size()); | 331 ASSERT_EQ(1U, message_received.handles()->size()); |
| 345 | 332 |
| 346 // Now send a message to the transferred handle and confirm it's sent through | 333 // Now send a message to the transferred handle and confirm it's sent through |
| 347 // to the orginal pipe. | 334 // to the orginal pipe. |
| 348 // TODO(vtl): Do we need a better way of "downcasting" the handle types? | 335 // TODO(vtl): Do we need a better way of "downcasting" the handle types? |
| 349 ScopedMessagePipeHandle smph; | 336 ScopedMessagePipeHandle smph; |
| 350 smph.reset(MessagePipeHandle(message_received.handles()->front().value())); | 337 smph.reset(MessagePipeHandle(message_received.handles()->front().value())); |
| 351 message_received.mutable_handles()->front() = Handle(); | 338 message_received.mutable_handles()->front() = Handle(); |
| 352 // |smph| now owns this handle. | 339 // |smph| now owns this handle. |
| 353 | 340 |
| 354 internal::Connector connector_received( | 341 Connector connector_received(std::move(smph), Connector::SINGLE_THREADED_SEND, |
| 355 std::move(smph), internal::Connector::SINGLE_THREADED_SEND, | 342 base::ThreadTaskRunnerHandle::Get()); |
| 356 base::ThreadTaskRunnerHandle::Get()); | 343 Connector connector_original(std::move(pipe.handle1), |
| 357 internal::Connector connector_original( | 344 Connector::SINGLE_THREADED_SEND, |
| 358 std::move(pipe.handle1), internal::Connector::SINGLE_THREADED_SEND, | 345 base::ThreadTaskRunnerHandle::Get()); |
| 359 base::ThreadTaskRunnerHandle::Get()); | |
| 360 | 346 |
| 361 Message message2; | 347 Message message2; |
| 362 AllocMessage(kText, &message2); | 348 AllocMessage(kText, &message2); |
| 363 | 349 |
| 364 connector_received.Accept(&message2); | 350 connector_received.Accept(&message2); |
| 365 base::RunLoop run_loop2; | 351 base::RunLoop run_loop2; |
| 366 MessageAccumulator accumulator2(run_loop2.QuitClosure()); | 352 MessageAccumulator accumulator2(run_loop2.QuitClosure()); |
| 367 connector_original.set_incoming_receiver(&accumulator2); | 353 connector_original.set_incoming_receiver(&accumulator2); |
| 368 run_loop2.Run(); | 354 run_loop2.Run(); |
| 369 | 355 |
| 370 ASSERT_FALSE(accumulator2.IsEmpty()); | 356 ASSERT_FALSE(accumulator2.IsEmpty()); |
| 371 | 357 |
| 372 accumulator2.Pop(&message_received); | 358 accumulator2.Pop(&message_received); |
| 373 | 359 |
| 374 EXPECT_EQ( | 360 EXPECT_EQ( |
| 375 std::string(kText), | 361 std::string(kText), |
| 376 std::string(reinterpret_cast<const char*>(message_received.payload()))); | 362 std::string(reinterpret_cast<const char*>(message_received.payload()))); |
| 377 } | 363 } |
| 378 | 364 |
| 379 TEST_F(ConnectorTest, WaitForIncomingMessageWithError) { | 365 TEST_F(ConnectorTest, WaitForIncomingMessageWithError) { |
| 380 internal::Connector connector0(std::move(handle0_), | 366 Connector connector0(std::move(handle0_), Connector::SINGLE_THREADED_SEND, |
| 381 internal::Connector::SINGLE_THREADED_SEND, | 367 base::ThreadTaskRunnerHandle::Get()); |
| 382 base::ThreadTaskRunnerHandle::Get()); | |
| 383 // Close the other end of the pipe. | 368 // Close the other end of the pipe. |
| 384 handle1_.reset(); | 369 handle1_.reset(); |
| 385 ASSERT_FALSE(connector0.WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE)); | 370 ASSERT_FALSE(connector0.WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE)); |
| 386 } | 371 } |
| 387 | 372 |
| 388 TEST_F(ConnectorTest, WaitForIncomingMessageWithDeletion) { | 373 TEST_F(ConnectorTest, WaitForIncomingMessageWithDeletion) { |
| 389 internal::Connector connector0(std::move(handle0_), | 374 Connector connector0(std::move(handle0_), Connector::SINGLE_THREADED_SEND, |
| 390 internal::Connector::SINGLE_THREADED_SEND, | 375 base::ThreadTaskRunnerHandle::Get()); |
| 391 base::ThreadTaskRunnerHandle::Get()); | 376 Connector* connector1 = |
| 392 internal::Connector* connector1 = new internal::Connector( | 377 new Connector(std::move(handle1_), Connector::SINGLE_THREADED_SEND, |
| 393 std::move(handle1_), internal::Connector::SINGLE_THREADED_SEND, | 378 base::ThreadTaskRunnerHandle::Get()); |
| 394 base::ThreadTaskRunnerHandle::Get()); | |
| 395 | 379 |
| 396 const char kText[] = "hello world"; | 380 const char kText[] = "hello world"; |
| 397 | 381 |
| 398 Message message; | 382 Message message; |
| 399 AllocMessage(kText, &message); | 383 AllocMessage(kText, &message); |
| 400 | 384 |
| 401 connector0.Accept(&message); | 385 connector0.Accept(&message); |
| 402 | 386 |
| 403 ConnectorDeletingMessageAccumulator accumulator(&connector1); | 387 ConnectorDeletingMessageAccumulator accumulator(&connector1); |
| 404 connector1->set_incoming_receiver(&accumulator); | 388 connector1->set_incoming_receiver(&accumulator); |
| 405 | 389 |
| 406 connector1->WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE); | 390 connector1->WaitForIncomingMessage(MOJO_DEADLINE_INDEFINITE); |
| 407 | 391 |
| 408 ASSERT_FALSE(connector1); | 392 ASSERT_FALSE(connector1); |
| 409 ASSERT_FALSE(accumulator.IsEmpty()); | 393 ASSERT_FALSE(accumulator.IsEmpty()); |
| 410 | 394 |
| 411 Message message_received; | 395 Message message_received; |
| 412 accumulator.Pop(&message_received); | 396 accumulator.Pop(&message_received); |
| 413 | 397 |
| 414 EXPECT_EQ( | 398 EXPECT_EQ( |
| 415 std::string(kText), | 399 std::string(kText), |
| 416 std::string(reinterpret_cast<const char*>(message_received.payload()))); | 400 std::string(reinterpret_cast<const char*>(message_received.payload()))); |
| 417 } | 401 } |
| 418 | 402 |
| 419 TEST_F(ConnectorTest, WaitForIncomingMessageWithReentrancy) { | 403 TEST_F(ConnectorTest, WaitForIncomingMessageWithReentrancy) { |
| 420 internal::Connector connector0(std::move(handle0_), | 404 Connector connector0(std::move(handle0_), Connector::SINGLE_THREADED_SEND, |
| 421 internal::Connector::SINGLE_THREADED_SEND, | 405 base::ThreadTaskRunnerHandle::Get()); |
| 422 base::ThreadTaskRunnerHandle::Get()); | 406 Connector connector1(std::move(handle1_), Connector::SINGLE_THREADED_SEND, |
| 423 internal::Connector connector1(std::move(handle1_), | 407 base::ThreadTaskRunnerHandle::Get()); |
| 424 internal::Connector::SINGLE_THREADED_SEND, | |
| 425 base::ThreadTaskRunnerHandle::Get()); | |
| 426 | 408 |
| 427 const char* kText[] = {"hello", "world"}; | 409 const char* kText[] = {"hello", "world"}; |
| 428 | 410 |
| 429 for (size_t i = 0; i < arraysize(kText); ++i) { | 411 for (size_t i = 0; i < arraysize(kText); ++i) { |
| 430 Message message; | 412 Message message; |
| 431 AllocMessage(kText[i], &message); | 413 AllocMessage(kText[i], &message); |
| 432 | 414 |
| 433 connector0.Accept(&message); | 415 connector0.Accept(&message); |
| 434 } | 416 } |
| 435 | 417 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 455 ASSERT_EQ(2, accumulator.number_of_calls()); | 437 ASSERT_EQ(2, accumulator.number_of_calls()); |
| 456 } | 438 } |
| 457 | 439 |
| 458 void ForwardErrorHandler(bool* called, const base::Closure& callback) { | 440 void ForwardErrorHandler(bool* called, const base::Closure& callback) { |
| 459 *called = true; | 441 *called = true; |
| 460 callback.Run(); | 442 callback.Run(); |
| 461 } | 443 } |
| 462 | 444 |
| 463 TEST_F(ConnectorTest, RaiseError) { | 445 TEST_F(ConnectorTest, RaiseError) { |
| 464 base::RunLoop run_loop, run_loop2; | 446 base::RunLoop run_loop, run_loop2; |
| 465 internal::Connector connector0(std::move(handle0_), | 447 Connector connector0(std::move(handle0_), Connector::SINGLE_THREADED_SEND, |
| 466 internal::Connector::SINGLE_THREADED_SEND, | 448 base::ThreadTaskRunnerHandle::Get()); |
| 467 base::ThreadTaskRunnerHandle::Get()); | |
| 468 bool error_handler_called0 = false; | 449 bool error_handler_called0 = false; |
| 469 connector0.set_connection_error_handler( | 450 connector0.set_connection_error_handler( |
| 470 base::Bind(&ForwardErrorHandler, &error_handler_called0, | 451 base::Bind(&ForwardErrorHandler, &error_handler_called0, |
| 471 run_loop.QuitClosure())); | 452 run_loop.QuitClosure())); |
| 472 | 453 |
| 473 internal::Connector connector1(std::move(handle1_), | 454 Connector connector1(std::move(handle1_), Connector::SINGLE_THREADED_SEND, |
| 474 internal::Connector::SINGLE_THREADED_SEND, | 455 base::ThreadTaskRunnerHandle::Get()); |
| 475 base::ThreadTaskRunnerHandle::Get()); | |
| 476 bool error_handler_called1 = false; | 456 bool error_handler_called1 = false; |
| 477 connector1.set_connection_error_handler( | 457 connector1.set_connection_error_handler( |
| 478 base::Bind(&ForwardErrorHandler, &error_handler_called1, | 458 base::Bind(&ForwardErrorHandler, &error_handler_called1, |
| 479 run_loop2.QuitClosure())); | 459 run_loop2.QuitClosure())); |
| 480 | 460 |
| 481 const char kText[] = "hello world"; | 461 const char kText[] = "hello world"; |
| 482 | 462 |
| 483 Message message; | 463 Message message; |
| 484 AllocMessage(kText, &message); | 464 AllocMessage(kText, &message); |
| 485 | 465 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 511 | 491 |
| 512 // The error flag is set at both sides. | 492 // The error flag is set at both sides. |
| 513 EXPECT_TRUE(connector0.encountered_error()); | 493 EXPECT_TRUE(connector0.encountered_error()); |
| 514 EXPECT_TRUE(connector1.encountered_error()); | 494 EXPECT_TRUE(connector1.encountered_error()); |
| 515 | 495 |
| 516 // The message pipe handle is valid at both sides. | 496 // The message pipe handle is valid at both sides. |
| 517 EXPECT_TRUE(connector0.is_valid()); | 497 EXPECT_TRUE(connector0.is_valid()); |
| 518 EXPECT_TRUE(connector1.is_valid()); | 498 EXPECT_TRUE(connector1.is_valid()); |
| 519 } | 499 } |
| 520 | 500 |
| 521 void PauseConnectorAndRunClosure(internal::Connector* connector, | 501 void PauseConnectorAndRunClosure(Connector* connector, |
| 522 const base::Closure& closure) { | 502 const base::Closure& closure) { |
| 523 connector->PauseIncomingMethodCallProcessing(); | 503 connector->PauseIncomingMethodCallProcessing(); |
| 524 closure.Run(); | 504 closure.Run(); |
| 525 } | 505 } |
| 526 | 506 |
| 527 TEST_F(ConnectorTest, PauseWithQueuedMessages) { | 507 TEST_F(ConnectorTest, PauseWithQueuedMessages) { |
| 528 internal::Connector connector0(std::move(handle0_), | 508 Connector connector0(std::move(handle0_), Connector::SINGLE_THREADED_SEND, |
| 529 internal::Connector::SINGLE_THREADED_SEND, | 509 base::ThreadTaskRunnerHandle::Get()); |
| 530 base::ThreadTaskRunnerHandle::Get()); | 510 Connector connector1(std::move(handle1_), Connector::SINGLE_THREADED_SEND, |
| 531 internal::Connector connector1(std::move(handle1_), | 511 base::ThreadTaskRunnerHandle::Get()); |
| 532 internal::Connector::SINGLE_THREADED_SEND, | |
| 533 base::ThreadTaskRunnerHandle::Get()); | |
| 534 | 512 |
| 535 const char kText[] = "hello world"; | 513 const char kText[] = "hello world"; |
| 536 | 514 |
| 537 // Queue up two messages. | 515 // Queue up two messages. |
| 538 Message message; | 516 Message message; |
| 539 AllocMessage(kText, &message); | 517 AllocMessage(kText, &message); |
| 540 connector0.Accept(&message); | 518 connector0.Accept(&message); |
| 541 AllocMessage(kText, &message); | 519 AllocMessage(kText, &message); |
| 542 connector0.Accept(&message); | 520 connector0.Accept(&message); |
| 543 | 521 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 560 const base::Closure& closure) { | 538 const base::Closure& closure) { |
| 561 base::RunLoop nested_run_loop; | 539 base::RunLoop nested_run_loop; |
| 562 base::MessageLoop::ScopedNestableTaskAllower allow( | 540 base::MessageLoop::ScopedNestableTaskAllower allow( |
| 563 base::MessageLoop::current()); | 541 base::MessageLoop::current()); |
| 564 accumulator->set_closure(nested_run_loop.QuitClosure()); | 542 accumulator->set_closure(nested_run_loop.QuitClosure()); |
| 565 nested_run_loop.Run(); | 543 nested_run_loop.Run(); |
| 566 closure.Run(); | 544 closure.Run(); |
| 567 } | 545 } |
| 568 | 546 |
| 569 TEST_F(ConnectorTest, ProcessWhenNested) { | 547 TEST_F(ConnectorTest, ProcessWhenNested) { |
| 570 internal::Connector connector0(std::move(handle0_), | 548 Connector connector0(std::move(handle0_), Connector::SINGLE_THREADED_SEND, |
| 571 internal::Connector::SINGLE_THREADED_SEND, | 549 base::ThreadTaskRunnerHandle::Get()); |
| 572 base::ThreadTaskRunnerHandle::Get()); | 550 Connector connector1(std::move(handle1_), Connector::SINGLE_THREADED_SEND, |
| 573 internal::Connector connector1(std::move(handle1_), | 551 base::ThreadTaskRunnerHandle::Get()); |
| 574 internal::Connector::SINGLE_THREADED_SEND, | |
| 575 base::ThreadTaskRunnerHandle::Get()); | |
| 576 | 552 |
| 577 const char kText[] = "hello world"; | 553 const char kText[] = "hello world"; |
| 578 | 554 |
| 579 // Queue up two messages. | 555 // Queue up two messages. |
| 580 Message message; | 556 Message message; |
| 581 AllocMessage(kText, &message); | 557 AllocMessage(kText, &message); |
| 582 connector0.Accept(&message); | 558 connector0.Accept(&message); |
| 583 AllocMessage(kText, &message); | 559 AllocMessage(kText, &message); |
| 584 connector0.Accept(&message); | 560 connector0.Accept(&message); |
| 585 | 561 |
| 586 base::RunLoop run_loop; | 562 base::RunLoop run_loop; |
| 587 MessageAccumulator accumulator; | 563 MessageAccumulator accumulator; |
| 588 // When the accumulator gets the first message it spins a nested message | 564 // When the accumulator gets the first message it spins a nested message |
| 589 // loop. The loop is quit when another message is received. | 565 // loop. The loop is quit when another message is received. |
| 590 accumulator.set_closure(base::Bind(&AccumulateWithNestedLoop, &accumulator, | 566 accumulator.set_closure(base::Bind(&AccumulateWithNestedLoop, &accumulator, |
| 591 run_loop.QuitClosure())); | 567 run_loop.QuitClosure())); |
| 592 connector1.set_incoming_receiver(&accumulator); | 568 connector1.set_incoming_receiver(&accumulator); |
| 593 | 569 |
| 594 run_loop.Run(); | 570 run_loop.Run(); |
| 595 | 571 |
| 596 ASSERT_EQ(2u, accumulator.size()); | 572 ASSERT_EQ(2u, accumulator.size()); |
| 597 } | 573 } |
| 598 | 574 |
| 599 } // namespace | 575 } // namespace |
| 600 } // namespace test | 576 } // namespace test |
| 601 } // namespace mojo | 577 } // namespace mojo |
| OLD | NEW |