OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/ipc_sync_channel.h" | 5 #include "ipc/ipc_sync_channel.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 #include <string> | 10 #include <string> |
| 11 #include <utility> |
11 #include <vector> | 12 #include <vector> |
12 | 13 |
13 #include "base/bind.h" | 14 #include "base/bind.h" |
14 #include "base/location.h" | 15 #include "base/location.h" |
15 #include "base/logging.h" | 16 #include "base/logging.h" |
16 #include "base/macros.h" | 17 #include "base/macros.h" |
17 #include "base/process/process_handle.h" | 18 #include "base/process/process_handle.h" |
18 #include "base/run_loop.h" | 19 #include "base/run_loop.h" |
19 #include "base/single_thread_task_runner.h" | 20 #include "base/single_thread_task_runner.h" |
20 #include "base/strings/string_util.h" | 21 #include "base/strings/string_util.h" |
21 #include "base/synchronization/waitable_event.h" | 22 #include "base/synchronization/waitable_event.h" |
22 #include "base/threading/platform_thread.h" | 23 #include "base/threading/platform_thread.h" |
23 #include "base/threading/thread.h" | 24 #include "base/threading/thread.h" |
24 #include "base/threading/thread_task_runner_handle.h" | 25 #include "base/threading/thread_task_runner_handle.h" |
25 #include "build/build_config.h" | 26 #include "build/build_config.h" |
26 #include "ipc/ipc_listener.h" | 27 #include "ipc/ipc_listener.h" |
27 #include "ipc/ipc_message.h" | 28 #include "ipc/ipc_message.h" |
28 #include "ipc/ipc_sender.h" | 29 #include "ipc/ipc_sender.h" |
29 #include "ipc/ipc_sync_message_filter.h" | 30 #include "ipc/ipc_sync_message_filter.h" |
30 #include "ipc/ipc_sync_message_unittest.h" | 31 #include "ipc/ipc_sync_message_unittest.h" |
| 32 #include "mojo/public/cpp/system/message_pipe.h" |
31 #include "testing/gtest/include/gtest/gtest.h" | 33 #include "testing/gtest/include/gtest/gtest.h" |
32 | 34 |
33 using base::WaitableEvent; | 35 using base::WaitableEvent; |
34 | 36 |
35 namespace IPC { | 37 namespace IPC { |
36 namespace { | 38 namespace { |
37 | 39 |
38 // Base class for a "process" with listener and IPC threads. | 40 // Base class for a "process" with listener and IPC threads. |
39 class Worker : public Listener, public Sender { | 41 class Worker : public Listener, public Sender { |
40 public: | 42 public: |
41 // Will create a channel without a name. | 43 // Will create a channel without a name. |
42 Worker(Channel::Mode mode, | 44 Worker(Channel::Mode mode, |
43 const std::string& thread_name, | 45 const std::string& thread_name, |
44 const std::string& channel_name) | 46 mojo::ScopedMessagePipeHandle channel_handle) |
45 : done_( | 47 : done_( |
46 new WaitableEvent(base::WaitableEvent::ResetPolicy::AUTOMATIC, | 48 new WaitableEvent(base::WaitableEvent::ResetPolicy::AUTOMATIC, |
47 base::WaitableEvent::InitialState::NOT_SIGNALED)), | 49 base::WaitableEvent::InitialState::NOT_SIGNALED)), |
48 channel_created_( | 50 channel_created_( |
49 new WaitableEvent(base::WaitableEvent::ResetPolicy::AUTOMATIC, | 51 new WaitableEvent(base::WaitableEvent::ResetPolicy::AUTOMATIC, |
50 base::WaitableEvent::InitialState::NOT_SIGNALED)), | 52 base::WaitableEvent::InitialState::NOT_SIGNALED)), |
51 channel_name_(channel_name), | 53 channel_handle_(std::move(channel_handle)), |
52 mode_(mode), | 54 mode_(mode), |
53 ipc_thread_((thread_name + "_ipc").c_str()), | 55 ipc_thread_((thread_name + "_ipc").c_str()), |
54 listener_thread_((thread_name + "_listener").c_str()), | 56 listener_thread_((thread_name + "_listener").c_str()), |
55 overrided_thread_(NULL), | 57 overrided_thread_(NULL), |
56 shutdown_event_(base::WaitableEvent::ResetPolicy::MANUAL, | 58 shutdown_event_(base::WaitableEvent::ResetPolicy::MANUAL, |
57 base::WaitableEvent::InitialState::NOT_SIGNALED), | 59 base::WaitableEvent::InitialState::NOT_SIGNALED), |
58 is_shutdown_(false) {} | 60 is_shutdown_(false) {} |
59 | 61 |
60 // Will create a named channel and use this name for the threads' name. | 62 // Will create a named channel and use this name for the threads' name. |
61 Worker(const std::string& channel_name, Channel::Mode mode) | 63 Worker(mojo::ScopedMessagePipeHandle channel_handle, Channel::Mode mode) |
62 : done_( | 64 : done_( |
63 new WaitableEvent(base::WaitableEvent::ResetPolicy::AUTOMATIC, | 65 new WaitableEvent(base::WaitableEvent::ResetPolicy::AUTOMATIC, |
64 base::WaitableEvent::InitialState::NOT_SIGNALED)), | 66 base::WaitableEvent::InitialState::NOT_SIGNALED)), |
65 channel_created_( | 67 channel_created_( |
66 new WaitableEvent(base::WaitableEvent::ResetPolicy::AUTOMATIC, | 68 new WaitableEvent(base::WaitableEvent::ResetPolicy::AUTOMATIC, |
67 base::WaitableEvent::InitialState::NOT_SIGNALED)), | 69 base::WaitableEvent::InitialState::NOT_SIGNALED)), |
68 channel_name_(channel_name), | 70 channel_handle_(std::move(channel_handle)), |
69 mode_(mode), | 71 mode_(mode), |
70 ipc_thread_((channel_name + "_ipc").c_str()), | 72 ipc_thread_("ipc thread"), |
71 listener_thread_((channel_name + "_listener").c_str()), | 73 listener_thread_("listener thread"), |
72 overrided_thread_(NULL), | 74 overrided_thread_(NULL), |
73 shutdown_event_(base::WaitableEvent::ResetPolicy::MANUAL, | 75 shutdown_event_(base::WaitableEvent::ResetPolicy::MANUAL, |
74 base::WaitableEvent::InitialState::NOT_SIGNALED), | 76 base::WaitableEvent::InitialState::NOT_SIGNALED), |
75 is_shutdown_(false) {} | 77 is_shutdown_(false) {} |
76 | 78 |
77 ~Worker() override { | 79 ~Worker() override { |
78 // Shutdown() must be called before destruction. | 80 // Shutdown() must be called before destruction. |
79 CHECK(is_shutdown_); | 81 CHECK(is_shutdown_); |
80 } | 82 } |
81 void AddRef() { } | 83 void AddRef() { } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 bool SendDouble(bool pump, bool succeed) { | 128 bool SendDouble(bool pump, bool succeed) { |
127 int answer = 0; | 129 int answer = 0; |
128 SyncMessage* msg = new SyncChannelTestMsg_Double(5, &answer); | 130 SyncMessage* msg = new SyncChannelTestMsg_Double(5, &answer); |
129 if (pump) | 131 if (pump) |
130 msg->EnableMessagePumping(); | 132 msg->EnableMessagePumping(); |
131 bool result = Send(msg); | 133 bool result = Send(msg); |
132 DCHECK_EQ(result, succeed); | 134 DCHECK_EQ(result, succeed); |
133 DCHECK_EQ(answer, (succeed ? 10 : 0)); | 135 DCHECK_EQ(answer, (succeed ? 10 : 0)); |
134 return result; | 136 return result; |
135 } | 137 } |
136 const std::string& channel_name() { return channel_name_; } | 138 mojo::MessagePipeHandle TakeChannelHandle() { |
| 139 DCHECK(channel_handle_.is_valid()); |
| 140 return channel_handle_.release(); |
| 141 } |
137 Channel::Mode mode() { return mode_; } | 142 Channel::Mode mode() { return mode_; } |
138 WaitableEvent* done_event() { return done_.get(); } | 143 WaitableEvent* done_event() { return done_.get(); } |
139 WaitableEvent* shutdown_event() { return &shutdown_event_; } | 144 WaitableEvent* shutdown_event() { return &shutdown_event_; } |
140 void ResetChannel() { channel_.reset(); } | 145 void ResetChannel() { channel_.reset(); } |
141 // Derived classes need to call this when they've completed their part of | 146 // Derived classes need to call this when they've completed their part of |
142 // the test. | 147 // the test. |
143 void Done() { done_->Signal(); } | 148 void Done() { done_->Signal(); } |
144 | 149 |
145 protected: | 150 protected: |
146 SyncChannel* channel() { return channel_.get(); } | 151 SyncChannel* channel() { return channel_.get(); } |
(...skipping 17 matching lines...) Expand all Loading... |
164 OnDouble(in, &result); | 169 OnDouble(in, &result); |
165 SyncChannelTestMsg_Double::WriteReplyParams(reply_msg, result); | 170 SyncChannelTestMsg_Double::WriteReplyParams(reply_msg, result); |
166 Send(reply_msg); | 171 Send(reply_msg); |
167 } | 172 } |
168 | 173 |
169 virtual void OnNestedTestMsg(Message* reply_msg) { | 174 virtual void OnNestedTestMsg(Message* reply_msg) { |
170 NOTREACHED(); | 175 NOTREACHED(); |
171 } | 176 } |
172 | 177 |
173 virtual SyncChannel* CreateChannel() { | 178 virtual SyncChannel* CreateChannel() { |
174 std::unique_ptr<SyncChannel> channel = SyncChannel::Create( | 179 std::unique_ptr<SyncChannel> channel = |
175 channel_name_, mode_, this, ipc_thread_.task_runner().get(), true, | 180 SyncChannel::Create(TakeChannelHandle(), mode_, this, |
176 &shutdown_event_); | 181 ipc_thread_.task_runner(), true, &shutdown_event_); |
177 return channel.release(); | 182 return channel.release(); |
178 } | 183 } |
179 | 184 |
180 base::Thread* ListenerThread() { | 185 base::Thread* ListenerThread() { |
181 return overrided_thread_ ? overrided_thread_ : &listener_thread_; | 186 return overrided_thread_ ? overrided_thread_ : &listener_thread_; |
182 } | 187 } |
183 | 188 |
184 const base::Thread& ipc_thread() const { return ipc_thread_; } | 189 const base::Thread& ipc_thread() const { return ipc_thread_; } |
185 | 190 |
186 private: | 191 private: |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 } | 237 } |
233 | 238 |
234 void StartThread(base::Thread* thread, base::MessageLoop::Type type) { | 239 void StartThread(base::Thread* thread, base::MessageLoop::Type type) { |
235 base::Thread::Options options; | 240 base::Thread::Options options; |
236 options.message_loop_type = type; | 241 options.message_loop_type = type; |
237 thread->StartWithOptions(options); | 242 thread->StartWithOptions(options); |
238 } | 243 } |
239 | 244 |
240 std::unique_ptr<WaitableEvent> done_; | 245 std::unique_ptr<WaitableEvent> done_; |
241 std::unique_ptr<WaitableEvent> channel_created_; | 246 std::unique_ptr<WaitableEvent> channel_created_; |
242 std::string channel_name_; | 247 mojo::ScopedMessagePipeHandle channel_handle_; |
243 Channel::Mode mode_; | 248 Channel::Mode mode_; |
244 std::unique_ptr<SyncChannel> channel_; | 249 std::unique_ptr<SyncChannel> channel_; |
245 base::Thread ipc_thread_; | 250 base::Thread ipc_thread_; |
246 base::Thread listener_thread_; | 251 base::Thread listener_thread_; |
247 base::Thread* overrided_thread_; | 252 base::Thread* overrided_thread_; |
248 | 253 |
249 base::WaitableEvent shutdown_event_; | 254 base::WaitableEvent shutdown_event_; |
250 | 255 |
251 bool is_shutdown_; | 256 bool is_shutdown_; |
252 | 257 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 | 289 |
285 class IPCSyncChannelTest : public testing::Test { | 290 class IPCSyncChannelTest : public testing::Test { |
286 private: | 291 private: |
287 base::MessageLoop message_loop_; | 292 base::MessageLoop message_loop_; |
288 }; | 293 }; |
289 | 294 |
290 //------------------------------------------------------------------------------ | 295 //------------------------------------------------------------------------------ |
291 | 296 |
292 class SimpleServer : public Worker { | 297 class SimpleServer : public Worker { |
293 public: | 298 public: |
294 SimpleServer(bool pump_during_send, const std::string& channel_name) | 299 SimpleServer(bool pump_during_send, |
295 : Worker(Channel::MODE_SERVER, "simpler_server", channel_name), | 300 mojo::ScopedMessagePipeHandle channel_handle) |
| 301 : Worker(Channel::MODE_SERVER, |
| 302 "simpler_server", |
| 303 std::move(channel_handle)), |
296 pump_during_send_(pump_during_send) {} | 304 pump_during_send_(pump_during_send) {} |
297 void Run() override { | 305 void Run() override { |
298 SendAnswerToLife(pump_during_send_, true); | 306 SendAnswerToLife(pump_during_send_, true); |
299 Done(); | 307 Done(); |
300 } | 308 } |
301 | 309 |
302 bool pump_during_send_; | 310 bool pump_during_send_; |
303 }; | 311 }; |
304 | 312 |
305 class SimpleClient : public Worker { | 313 class SimpleClient : public Worker { |
306 public: | 314 public: |
307 explicit SimpleClient(const std::string& channel_name) | 315 explicit SimpleClient(mojo::ScopedMessagePipeHandle channel_handle) |
308 : Worker(Channel::MODE_CLIENT, "simple_client", channel_name) {} | 316 : Worker(Channel::MODE_CLIENT, |
| 317 "simple_client", |
| 318 std::move(channel_handle)) {} |
309 | 319 |
310 void OnAnswer(int* answer) override { | 320 void OnAnswer(int* answer) override { |
311 *answer = 42; | 321 *answer = 42; |
312 Done(); | 322 Done(); |
313 } | 323 } |
314 }; | 324 }; |
315 | 325 |
316 void Simple(bool pump_during_send) { | 326 void Simple(bool pump_during_send) { |
317 std::vector<Worker*> workers; | 327 std::vector<Worker*> workers; |
318 workers.push_back(new SimpleServer(pump_during_send, "Simple")); | 328 mojo::MessagePipe pipe; |
319 workers.push_back(new SimpleClient("Simple")); | 329 workers.push_back( |
| 330 new SimpleServer(pump_during_send, std::move(pipe.handle0))); |
| 331 workers.push_back(new SimpleClient(std::move(pipe.handle1))); |
320 RunTest(workers); | 332 RunTest(workers); |
321 } | 333 } |
322 | 334 |
323 #if defined(OS_ANDROID) | 335 #if defined(OS_ANDROID) |
324 #define MAYBE_Simple DISABLED_Simple | 336 #define MAYBE_Simple DISABLED_Simple |
325 #else | 337 #else |
326 #define MAYBE_Simple Simple | 338 #define MAYBE_Simple Simple |
327 #endif | 339 #endif |
328 // Tests basic synchronous call | 340 // Tests basic synchronous call |
329 TEST_F(IPCSyncChannelTest, MAYBE_Simple) { | 341 TEST_F(IPCSyncChannelTest, MAYBE_Simple) { |
330 Simple(false); | 342 Simple(false); |
331 Simple(true); | 343 Simple(true); |
332 } | 344 } |
333 | 345 |
334 //------------------------------------------------------------------------------ | 346 //------------------------------------------------------------------------------ |
335 | 347 |
336 // Worker classes which override how the sync channel is created to use the | 348 // Worker classes which override how the sync channel is created to use the |
337 // two-step initialization (calling the lightweight constructor and then | 349 // two-step initialization (calling the lightweight constructor and then |
338 // ChannelProxy::Init separately) process. | 350 // ChannelProxy::Init separately) process. |
339 class TwoStepServer : public Worker { | 351 class TwoStepServer : public Worker { |
340 public: | 352 public: |
341 TwoStepServer(bool create_pipe_now, const std::string& channel_name) | 353 TwoStepServer(bool create_pipe_now, |
342 : Worker(Channel::MODE_SERVER, "simpler_server", channel_name), | 354 mojo::ScopedMessagePipeHandle channel_handle) |
| 355 : Worker(Channel::MODE_SERVER, |
| 356 "simpler_server", |
| 357 std::move(channel_handle)), |
343 create_pipe_now_(create_pipe_now) {} | 358 create_pipe_now_(create_pipe_now) {} |
344 | 359 |
345 void Run() override { | 360 void Run() override { |
346 SendAnswerToLife(false, true); | 361 SendAnswerToLife(false, true); |
347 Done(); | 362 Done(); |
348 } | 363 } |
349 | 364 |
350 SyncChannel* CreateChannel() override { | 365 SyncChannel* CreateChannel() override { |
351 SyncChannel* channel = | 366 SyncChannel* channel = |
352 SyncChannel::Create(channel_name(), mode(), this, | 367 SyncChannel::Create(TakeChannelHandle(), mode(), this, |
353 ipc_thread().task_runner().get(), create_pipe_now_, | 368 ipc_thread().task_runner(), create_pipe_now_, |
354 shutdown_event()) | 369 shutdown_event()) |
355 .release(); | 370 .release(); |
356 return channel; | 371 return channel; |
357 } | 372 } |
358 | 373 |
359 bool create_pipe_now_; | 374 bool create_pipe_now_; |
360 }; | 375 }; |
361 | 376 |
362 class TwoStepClient : public Worker { | 377 class TwoStepClient : public Worker { |
363 public: | 378 public: |
364 TwoStepClient(bool create_pipe_now, const std::string& channel_name) | 379 TwoStepClient(bool create_pipe_now, |
365 : Worker(Channel::MODE_CLIENT, "simple_client", channel_name), | 380 mojo::ScopedMessagePipeHandle channel_handle) |
| 381 : Worker(Channel::MODE_CLIENT, |
| 382 "simple_client", |
| 383 std::move(channel_handle)), |
366 create_pipe_now_(create_pipe_now) {} | 384 create_pipe_now_(create_pipe_now) {} |
367 | 385 |
368 void OnAnswer(int* answer) override { | 386 void OnAnswer(int* answer) override { |
369 *answer = 42; | 387 *answer = 42; |
370 Done(); | 388 Done(); |
371 } | 389 } |
372 | 390 |
373 SyncChannel* CreateChannel() override { | 391 SyncChannel* CreateChannel() override { |
374 SyncChannel* channel = | 392 SyncChannel* channel = |
375 SyncChannel::Create(channel_name(), mode(), this, | 393 SyncChannel::Create(TakeChannelHandle(), mode(), this, |
376 ipc_thread().task_runner().get(), create_pipe_now_, | 394 ipc_thread().task_runner(), create_pipe_now_, |
377 shutdown_event()) | 395 shutdown_event()) |
378 .release(); | 396 .release(); |
379 return channel; | 397 return channel; |
380 } | 398 } |
381 | 399 |
382 bool create_pipe_now_; | 400 bool create_pipe_now_; |
383 }; | 401 }; |
384 | 402 |
385 void TwoStep(bool create_server_pipe_now, bool create_client_pipe_now) { | 403 void TwoStep(bool create_server_pipe_now, bool create_client_pipe_now) { |
386 std::vector<Worker*> workers; | 404 std::vector<Worker*> workers; |
387 workers.push_back(new TwoStepServer(create_server_pipe_now, "TwoStep")); | 405 mojo::MessagePipe pipe; |
388 workers.push_back(new TwoStepClient(create_client_pipe_now, "TwoStep")); | 406 workers.push_back( |
| 407 new TwoStepServer(create_server_pipe_now, std::move(pipe.handle0))); |
| 408 workers.push_back( |
| 409 new TwoStepClient(create_client_pipe_now, std::move(pipe.handle1))); |
389 RunTest(workers); | 410 RunTest(workers); |
390 } | 411 } |
391 | 412 |
392 // Tests basic two-step initialization, where you call the lightweight | 413 // Tests basic two-step initialization, where you call the lightweight |
393 // constructor then Init. | 414 // constructor then Init. |
394 TEST_F(IPCSyncChannelTest, TwoStepInitialization) { | 415 TEST_F(IPCSyncChannelTest, TwoStepInitialization) { |
395 TwoStep(false, false); | 416 TwoStep(false, false); |
396 TwoStep(false, true); | 417 TwoStep(false, true); |
397 TwoStep(true, false); | 418 TwoStep(true, false); |
398 TwoStep(true, true); | 419 TwoStep(true, true); |
399 } | 420 } |
400 | 421 |
401 //------------------------------------------------------------------------------ | 422 //------------------------------------------------------------------------------ |
402 | 423 |
403 class DelayClient : public Worker { | 424 class DelayClient : public Worker { |
404 public: | 425 public: |
405 explicit DelayClient(const std::string& channel_name) | 426 explicit DelayClient(mojo::ScopedMessagePipeHandle channel_handle) |
406 : Worker(Channel::MODE_CLIENT, "delay_client", channel_name) {} | 427 : Worker(Channel::MODE_CLIENT, |
| 428 "delay_client", |
| 429 std::move(channel_handle)) {} |
407 | 430 |
408 void OnAnswerDelay(Message* reply_msg) override { | 431 void OnAnswerDelay(Message* reply_msg) override { |
409 SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42); | 432 SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42); |
410 Send(reply_msg); | 433 Send(reply_msg); |
411 Done(); | 434 Done(); |
412 } | 435 } |
413 }; | 436 }; |
414 | 437 |
415 void DelayReply(bool pump_during_send) { | 438 void DelayReply(bool pump_during_send) { |
416 std::vector<Worker*> workers; | 439 std::vector<Worker*> workers; |
417 workers.push_back(new SimpleServer(pump_during_send, "DelayReply")); | 440 mojo::MessagePipe pipe; |
418 workers.push_back(new DelayClient("DelayReply")); | 441 workers.push_back( |
| 442 new SimpleServer(pump_during_send, std::move(pipe.handle0))); |
| 443 workers.push_back(new DelayClient(std::move(pipe.handle1))); |
419 RunTest(workers); | 444 RunTest(workers); |
420 } | 445 } |
421 | 446 |
422 // Tests that asynchronous replies work | 447 // Tests that asynchronous replies work |
423 TEST_F(IPCSyncChannelTest, DelayReply) { | 448 TEST_F(IPCSyncChannelTest, DelayReply) { |
424 DelayReply(false); | 449 DelayReply(false); |
425 DelayReply(true); | 450 DelayReply(true); |
426 } | 451 } |
427 | 452 |
428 //------------------------------------------------------------------------------ | 453 //------------------------------------------------------------------------------ |
429 | 454 |
430 class NoHangServer : public Worker { | 455 class NoHangServer : public Worker { |
431 public: | 456 public: |
432 NoHangServer(WaitableEvent* got_first_reply, | 457 NoHangServer(WaitableEvent* got_first_reply, |
433 bool pump_during_send, | 458 bool pump_during_send, |
434 const std::string& channel_name) | 459 mojo::ScopedMessagePipeHandle channel_handle) |
435 : Worker(Channel::MODE_SERVER, "no_hang_server", channel_name), | 460 : Worker(Channel::MODE_SERVER, |
| 461 "no_hang_server", |
| 462 std::move(channel_handle)), |
436 got_first_reply_(got_first_reply), | 463 got_first_reply_(got_first_reply), |
437 pump_during_send_(pump_during_send) {} | 464 pump_during_send_(pump_during_send) {} |
438 void Run() override { | 465 void Run() override { |
439 SendAnswerToLife(pump_during_send_, true); | 466 SendAnswerToLife(pump_during_send_, true); |
440 got_first_reply_->Signal(); | 467 got_first_reply_->Signal(); |
441 | 468 |
442 SendAnswerToLife(pump_during_send_, false); | 469 SendAnswerToLife(pump_during_send_, false); |
443 Done(); | 470 Done(); |
444 } | 471 } |
445 | 472 |
446 WaitableEvent* got_first_reply_; | 473 WaitableEvent* got_first_reply_; |
447 bool pump_during_send_; | 474 bool pump_during_send_; |
448 }; | 475 }; |
449 | 476 |
450 class NoHangClient : public Worker { | 477 class NoHangClient : public Worker { |
451 public: | 478 public: |
452 NoHangClient(WaitableEvent* got_first_reply, const std::string& channel_name) | 479 NoHangClient(WaitableEvent* got_first_reply, |
453 : Worker(Channel::MODE_CLIENT, "no_hang_client", channel_name), | 480 mojo::ScopedMessagePipeHandle channel_handle) |
| 481 : Worker(Channel::MODE_CLIENT, |
| 482 "no_hang_client", |
| 483 std::move(channel_handle)), |
454 got_first_reply_(got_first_reply) {} | 484 got_first_reply_(got_first_reply) {} |
455 | 485 |
456 void OnAnswerDelay(Message* reply_msg) override { | 486 void OnAnswerDelay(Message* reply_msg) override { |
457 // Use the DELAY_REPLY macro so that we can force the reply to be sent | 487 // Use the DELAY_REPLY macro so that we can force the reply to be sent |
458 // before this function returns (when the channel will be reset). | 488 // before this function returns (when the channel will be reset). |
459 SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42); | 489 SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42); |
460 Send(reply_msg); | 490 Send(reply_msg); |
461 got_first_reply_->Wait(); | 491 got_first_reply_->Wait(); |
462 CloseChannel(); | 492 CloseChannel(); |
463 Done(); | 493 Done(); |
464 } | 494 } |
465 | 495 |
466 WaitableEvent* got_first_reply_; | 496 WaitableEvent* got_first_reply_; |
467 }; | 497 }; |
468 | 498 |
469 void NoHang(bool pump_during_send) { | 499 void NoHang(bool pump_during_send) { |
470 WaitableEvent got_first_reply( | 500 WaitableEvent got_first_reply( |
471 base::WaitableEvent::ResetPolicy::AUTOMATIC, | 501 base::WaitableEvent::ResetPolicy::AUTOMATIC, |
472 base::WaitableEvent::InitialState::NOT_SIGNALED); | 502 base::WaitableEvent::InitialState::NOT_SIGNALED); |
473 std::vector<Worker*> workers; | 503 std::vector<Worker*> workers; |
| 504 mojo::MessagePipe pipe; |
| 505 workers.push_back(new NoHangServer(&got_first_reply, pump_during_send, |
| 506 std::move(pipe.handle0))); |
474 workers.push_back( | 507 workers.push_back( |
475 new NoHangServer(&got_first_reply, pump_during_send, "NoHang")); | 508 new NoHangClient(&got_first_reply, std::move(pipe.handle1))); |
476 workers.push_back(new NoHangClient(&got_first_reply, "NoHang")); | |
477 RunTest(workers); | 509 RunTest(workers); |
478 } | 510 } |
479 | 511 |
480 // Tests that caller doesn't hang if receiver dies | 512 // Tests that caller doesn't hang if receiver dies |
481 TEST_F(IPCSyncChannelTest, NoHang) { | 513 TEST_F(IPCSyncChannelTest, NoHang) { |
482 NoHang(false); | 514 NoHang(false); |
483 NoHang(true); | 515 NoHang(true); |
484 } | 516 } |
485 | 517 |
486 //------------------------------------------------------------------------------ | 518 //------------------------------------------------------------------------------ |
487 | 519 |
488 class UnblockServer : public Worker { | 520 class UnblockServer : public Worker { |
489 public: | 521 public: |
490 UnblockServer(bool pump_during_send, | 522 UnblockServer(bool pump_during_send, |
491 bool delete_during_send, | 523 bool delete_during_send, |
492 const std::string& channel_name) | 524 mojo::ScopedMessagePipeHandle channel_handle) |
493 : Worker(Channel::MODE_SERVER, "unblock_server", channel_name), | 525 : Worker(Channel::MODE_SERVER, |
| 526 "unblock_server", |
| 527 std::move(channel_handle)), |
494 pump_during_send_(pump_during_send), | 528 pump_during_send_(pump_during_send), |
495 delete_during_send_(delete_during_send) {} | 529 delete_during_send_(delete_during_send) {} |
496 void Run() override { | 530 void Run() override { |
497 if (delete_during_send_) { | 531 if (delete_during_send_) { |
498 // Use custom code since race conditions mean the answer may or may not be | 532 // Use custom code since race conditions mean the answer may or may not be |
499 // available. | 533 // available. |
500 int answer = 0; | 534 int answer = 0; |
501 SyncMessage* msg = new SyncChannelTestMsg_AnswerToLife(&answer); | 535 SyncMessage* msg = new SyncChannelTestMsg_AnswerToLife(&answer); |
502 if (pump_during_send_) | 536 if (pump_during_send_) |
503 msg->EnableMessagePumping(); | 537 msg->EnableMessagePumping(); |
(...skipping 10 matching lines...) Expand all Loading... |
514 if (delete_during_send_) | 548 if (delete_during_send_) |
515 ResetChannel(); | 549 ResetChannel(); |
516 } | 550 } |
517 | 551 |
518 bool pump_during_send_; | 552 bool pump_during_send_; |
519 bool delete_during_send_; | 553 bool delete_during_send_; |
520 }; | 554 }; |
521 | 555 |
522 class UnblockClient : public Worker { | 556 class UnblockClient : public Worker { |
523 public: | 557 public: |
524 UnblockClient(bool pump_during_send, const std::string& channel_name) | 558 UnblockClient(bool pump_during_send, |
525 : Worker(Channel::MODE_CLIENT, "unblock_client", channel_name), | 559 mojo::ScopedMessagePipeHandle channel_handle) |
| 560 : Worker(Channel::MODE_CLIENT, |
| 561 "unblock_client", |
| 562 std::move(channel_handle)), |
526 pump_during_send_(pump_during_send) {} | 563 pump_during_send_(pump_during_send) {} |
527 | 564 |
528 void OnAnswer(int* answer) override { | 565 void OnAnswer(int* answer) override { |
529 SendDouble(pump_during_send_, true); | 566 SendDouble(pump_during_send_, true); |
530 *answer = 42; | 567 *answer = 42; |
531 Done(); | 568 Done(); |
532 } | 569 } |
533 | 570 |
534 bool pump_during_send_; | 571 bool pump_during_send_; |
535 }; | 572 }; |
536 | 573 |
537 void Unblock(bool server_pump, bool client_pump, bool delete_during_send) { | 574 void Unblock(bool server_pump, bool client_pump, bool delete_during_send) { |
538 std::vector<Worker*> workers; | 575 std::vector<Worker*> workers; |
539 workers.push_back( | 576 mojo::MessagePipe pipe; |
540 new UnblockServer(server_pump, delete_during_send, "Unblock")); | 577 workers.push_back(new UnblockServer(server_pump, delete_during_send, |
541 workers.push_back(new UnblockClient(client_pump, "Unblock")); | 578 std::move(pipe.handle0))); |
| 579 workers.push_back(new UnblockClient(client_pump, std::move(pipe.handle1))); |
542 RunTest(workers); | 580 RunTest(workers); |
543 } | 581 } |
544 | 582 |
545 // Tests that the caller unblocks to answer a sync message from the receiver. | 583 // Tests that the caller unblocks to answer a sync message from the receiver. |
546 TEST_F(IPCSyncChannelTest, Unblock) { | 584 TEST_F(IPCSyncChannelTest, Unblock) { |
547 Unblock(false, false, false); | 585 Unblock(false, false, false); |
548 Unblock(false, true, false); | 586 Unblock(false, true, false); |
549 Unblock(true, false, false); | 587 Unblock(true, false, false); |
550 Unblock(true, true, false); | 588 Unblock(true, true, false); |
551 } | 589 } |
(...skipping 13 matching lines...) Expand all Loading... |
565 Unblock(true, true, true); | 603 Unblock(true, true, true); |
566 } | 604 } |
567 | 605 |
568 //------------------------------------------------------------------------------ | 606 //------------------------------------------------------------------------------ |
569 | 607 |
570 class RecursiveServer : public Worker { | 608 class RecursiveServer : public Worker { |
571 public: | 609 public: |
572 RecursiveServer(bool expected_send_result, | 610 RecursiveServer(bool expected_send_result, |
573 bool pump_first, | 611 bool pump_first, |
574 bool pump_second, | 612 bool pump_second, |
575 const std::string& channel_name) | 613 mojo::ScopedMessagePipeHandle channel_handle) |
576 : Worker(Channel::MODE_SERVER, "recursive_server", channel_name), | 614 : Worker(Channel::MODE_SERVER, |
| 615 "recursive_server", |
| 616 std::move(channel_handle)), |
577 expected_send_result_(expected_send_result), | 617 expected_send_result_(expected_send_result), |
578 pump_first_(pump_first), | 618 pump_first_(pump_first), |
579 pump_second_(pump_second) {} | 619 pump_second_(pump_second) {} |
580 void Run() override { | 620 void Run() override { |
581 SendDouble(pump_first_, expected_send_result_); | 621 SendDouble(pump_first_, expected_send_result_); |
582 Done(); | 622 Done(); |
583 } | 623 } |
584 | 624 |
585 void OnDouble(int in, int* out) override { | 625 void OnDouble(int in, int* out) override { |
586 *out = in * 2; | 626 *out = in * 2; |
587 SendAnswerToLife(pump_second_, expected_send_result_); | 627 SendAnswerToLife(pump_second_, expected_send_result_); |
588 } | 628 } |
589 | 629 |
590 bool expected_send_result_, pump_first_, pump_second_; | 630 bool expected_send_result_, pump_first_, pump_second_; |
591 }; | 631 }; |
592 | 632 |
593 class RecursiveClient : public Worker { | 633 class RecursiveClient : public Worker { |
594 public: | 634 public: |
595 RecursiveClient(bool pump_during_send, | 635 RecursiveClient(bool pump_during_send, |
596 bool close_channel, | 636 bool close_channel, |
597 const std::string& channel_name) | 637 mojo::ScopedMessagePipeHandle channel_handle) |
598 : Worker(Channel::MODE_CLIENT, "recursive_client", channel_name), | 638 : Worker(Channel::MODE_CLIENT, |
| 639 "recursive_client", |
| 640 std::move(channel_handle)), |
599 pump_during_send_(pump_during_send), | 641 pump_during_send_(pump_during_send), |
600 close_channel_(close_channel) {} | 642 close_channel_(close_channel) {} |
601 | 643 |
602 void OnDoubleDelay(int in, Message* reply_msg) override { | 644 void OnDoubleDelay(int in, Message* reply_msg) override { |
603 SendDouble(pump_during_send_, !close_channel_); | 645 SendDouble(pump_during_send_, !close_channel_); |
604 if (close_channel_) { | 646 if (close_channel_) { |
605 delete reply_msg; | 647 delete reply_msg; |
606 } else { | 648 } else { |
607 SyncChannelTestMsg_Double::WriteReplyParams(reply_msg, in * 2); | 649 SyncChannelTestMsg_Double::WriteReplyParams(reply_msg, in * 2); |
608 Send(reply_msg); | 650 Send(reply_msg); |
(...skipping 10 matching lines...) Expand all Loading... |
619 Send(reply_msg); | 661 Send(reply_msg); |
620 } | 662 } |
621 } | 663 } |
622 | 664 |
623 bool pump_during_send_, close_channel_; | 665 bool pump_during_send_, close_channel_; |
624 }; | 666 }; |
625 | 667 |
626 void Recursive( | 668 void Recursive( |
627 bool server_pump_first, bool server_pump_second, bool client_pump) { | 669 bool server_pump_first, bool server_pump_second, bool client_pump) { |
628 std::vector<Worker*> workers; | 670 std::vector<Worker*> workers; |
629 workers.push_back(new RecursiveServer(true, server_pump_first, | 671 mojo::MessagePipe pipe; |
630 server_pump_second, "Recursive")); | 672 workers.push_back(new RecursiveServer( |
631 workers.push_back(new RecursiveClient(client_pump, false, "Recursive")); | 673 true, server_pump_first, server_pump_second, std::move(pipe.handle0))); |
| 674 workers.push_back( |
| 675 new RecursiveClient(client_pump, false, std::move(pipe.handle1))); |
632 RunTest(workers); | 676 RunTest(workers); |
633 } | 677 } |
634 | 678 |
635 // Tests a server calling Send while another Send is pending. | 679 // Tests a server calling Send while another Send is pending. |
636 TEST_F(IPCSyncChannelTest, Recursive) { | 680 TEST_F(IPCSyncChannelTest, Recursive) { |
637 Recursive(false, false, false); | 681 Recursive(false, false, false); |
638 Recursive(false, false, true); | 682 Recursive(false, false, true); |
639 Recursive(false, true, false); | 683 Recursive(false, true, false); |
640 Recursive(false, true, true); | 684 Recursive(false, true, true); |
641 Recursive(true, false, false); | 685 Recursive(true, false, false); |
642 Recursive(true, false, true); | 686 Recursive(true, false, true); |
643 Recursive(true, true, false); | 687 Recursive(true, true, false); |
644 Recursive(true, true, true); | 688 Recursive(true, true, true); |
645 } | 689 } |
646 | 690 |
647 //------------------------------------------------------------------------------ | 691 //------------------------------------------------------------------------------ |
648 | 692 |
649 void RecursiveNoHang( | 693 void RecursiveNoHang( |
650 bool server_pump_first, bool server_pump_second, bool client_pump) { | 694 bool server_pump_first, bool server_pump_second, bool client_pump) { |
651 std::vector<Worker*> workers; | 695 std::vector<Worker*> workers; |
652 workers.push_back(new RecursiveServer(false, server_pump_first, | 696 mojo::MessagePipe pipe; |
653 server_pump_second, "RecursiveNoHang")); | 697 workers.push_back(new RecursiveServer( |
654 workers.push_back(new RecursiveClient(client_pump, true, "RecursiveNoHang")); | 698 false, server_pump_first, server_pump_second, std::move(pipe.handle0))); |
| 699 workers.push_back( |
| 700 new RecursiveClient(client_pump, true, std::move(pipe.handle1))); |
655 RunTest(workers); | 701 RunTest(workers); |
656 } | 702 } |
657 | 703 |
658 // Tests that if a caller makes a sync call during an existing sync call and | 704 // Tests that if a caller makes a sync call during an existing sync call and |
659 // the receiver dies, neither of the Send() calls hang. | 705 // the receiver dies, neither of the Send() calls hang. |
660 TEST_F(IPCSyncChannelTest, RecursiveNoHang) { | 706 TEST_F(IPCSyncChannelTest, RecursiveNoHang) { |
661 RecursiveNoHang(false, false, false); | 707 RecursiveNoHang(false, false, false); |
662 RecursiveNoHang(false, false, true); | 708 RecursiveNoHang(false, false, true); |
663 RecursiveNoHang(false, true, false); | 709 RecursiveNoHang(false, true, false); |
664 RecursiveNoHang(false, true, true); | 710 RecursiveNoHang(false, true, true); |
665 RecursiveNoHang(true, false, false); | 711 RecursiveNoHang(true, false, false); |
666 RecursiveNoHang(true, false, true); | 712 RecursiveNoHang(true, false, true); |
667 RecursiveNoHang(true, true, false); | 713 RecursiveNoHang(true, true, false); |
668 RecursiveNoHang(true, true, true); | 714 RecursiveNoHang(true, true, true); |
669 } | 715 } |
670 | 716 |
671 //------------------------------------------------------------------------------ | 717 //------------------------------------------------------------------------------ |
672 | 718 |
673 class MultipleServer1 : public Worker { | 719 class MultipleServer1 : public Worker { |
674 public: | 720 public: |
675 explicit MultipleServer1(bool pump_during_send) | 721 MultipleServer1(bool pump_during_send, |
676 : Worker("test_channel1", Channel::MODE_SERVER), | 722 mojo::ScopedMessagePipeHandle channel_handle) |
677 pump_during_send_(pump_during_send) { } | 723 : Worker(std::move(channel_handle), Channel::MODE_SERVER), |
| 724 pump_during_send_(pump_during_send) {} |
678 | 725 |
679 void Run() override { | 726 void Run() override { |
680 SendDouble(pump_during_send_, true); | 727 SendDouble(pump_during_send_, true); |
681 Done(); | 728 Done(); |
682 } | 729 } |
683 | 730 |
684 bool pump_during_send_; | 731 bool pump_during_send_; |
685 }; | 732 }; |
686 | 733 |
687 class MultipleClient1 : public Worker { | 734 class MultipleClient1 : public Worker { |
688 public: | 735 public: |
689 MultipleClient1(WaitableEvent* client1_msg_received, | 736 MultipleClient1(WaitableEvent* client1_msg_received, |
690 WaitableEvent* client1_can_reply) : | 737 WaitableEvent* client1_can_reply, |
691 Worker("test_channel1", Channel::MODE_CLIENT), | 738 mojo::ScopedMessagePipeHandle channel_handle) |
692 client1_msg_received_(client1_msg_received), | 739 : Worker(std::move(channel_handle), Channel::MODE_CLIENT), |
693 client1_can_reply_(client1_can_reply) { } | 740 client1_msg_received_(client1_msg_received), |
| 741 client1_can_reply_(client1_can_reply) {} |
694 | 742 |
695 void OnDouble(int in, int* out) override { | 743 void OnDouble(int in, int* out) override { |
696 client1_msg_received_->Signal(); | 744 client1_msg_received_->Signal(); |
697 *out = in * 2; | 745 *out = in * 2; |
698 client1_can_reply_->Wait(); | 746 client1_can_reply_->Wait(); |
699 Done(); | 747 Done(); |
700 } | 748 } |
701 | 749 |
702 private: | 750 private: |
703 WaitableEvent *client1_msg_received_, *client1_can_reply_; | 751 WaitableEvent *client1_msg_received_, *client1_can_reply_; |
704 }; | 752 }; |
705 | 753 |
706 class MultipleServer2 : public Worker { | 754 class MultipleServer2 : public Worker { |
707 public: | 755 public: |
708 MultipleServer2() : Worker("test_channel2", Channel::MODE_SERVER) { } | 756 explicit MultipleServer2(mojo::ScopedMessagePipeHandle channel_handle) |
| 757 : Worker(std::move(channel_handle), Channel::MODE_SERVER) {} |
709 | 758 |
710 void OnAnswer(int* result) override { | 759 void OnAnswer(int* result) override { |
711 *result = 42; | 760 *result = 42; |
712 Done(); | 761 Done(); |
713 } | 762 } |
714 }; | 763 }; |
715 | 764 |
716 class MultipleClient2 : public Worker { | 765 class MultipleClient2 : public Worker { |
717 public: | 766 public: |
718 MultipleClient2( | 767 MultipleClient2(WaitableEvent* client1_msg_received, |
719 WaitableEvent* client1_msg_received, WaitableEvent* client1_can_reply, | 768 WaitableEvent* client1_can_reply, |
720 bool pump_during_send) | 769 bool pump_during_send, |
721 : Worker("test_channel2", Channel::MODE_CLIENT), | 770 mojo::ScopedMessagePipeHandle channel_handle) |
722 client1_msg_received_(client1_msg_received), | 771 : Worker(std::move(channel_handle), Channel::MODE_CLIENT), |
723 client1_can_reply_(client1_can_reply), | 772 client1_msg_received_(client1_msg_received), |
724 pump_during_send_(pump_during_send) { } | 773 client1_can_reply_(client1_can_reply), |
| 774 pump_during_send_(pump_during_send) {} |
725 | 775 |
726 void Run() override { | 776 void Run() override { |
727 client1_msg_received_->Wait(); | 777 client1_msg_received_->Wait(); |
728 SendAnswerToLife(pump_during_send_, true); | 778 SendAnswerToLife(pump_during_send_, true); |
729 client1_can_reply_->Signal(); | 779 client1_can_reply_->Signal(); |
730 Done(); | 780 Done(); |
731 } | 781 } |
732 | 782 |
733 private: | 783 private: |
734 WaitableEvent *client1_msg_received_, *client1_can_reply_; | 784 WaitableEvent *client1_msg_received_, *client1_can_reply_; |
(...skipping 12 matching lines...) Expand all Loading... |
747 // to a sync msg from client2. | 797 // to a sync msg from client2. |
748 WaitableEvent client1_msg_received( | 798 WaitableEvent client1_msg_received( |
749 base::WaitableEvent::ResetPolicy::AUTOMATIC, | 799 base::WaitableEvent::ResetPolicy::AUTOMATIC, |
750 base::WaitableEvent::InitialState::NOT_SIGNALED); | 800 base::WaitableEvent::InitialState::NOT_SIGNALED); |
751 WaitableEvent client1_can_reply( | 801 WaitableEvent client1_can_reply( |
752 base::WaitableEvent::ResetPolicy::AUTOMATIC, | 802 base::WaitableEvent::ResetPolicy::AUTOMATIC, |
753 base::WaitableEvent::InitialState::NOT_SIGNALED); | 803 base::WaitableEvent::InitialState::NOT_SIGNALED); |
754 | 804 |
755 Worker* worker; | 805 Worker* worker; |
756 | 806 |
757 worker = new MultipleServer2(); | 807 mojo::MessagePipe pipe1, pipe2; |
| 808 worker = new MultipleServer2(std::move(pipe2.handle0)); |
758 worker->OverrideThread(&worker_thread); | 809 worker->OverrideThread(&worker_thread); |
759 workers.push_back(worker); | 810 workers.push_back(worker); |
760 | 811 |
761 worker = new MultipleClient2( | 812 worker = new MultipleClient2(&client1_msg_received, &client1_can_reply, |
762 &client1_msg_received, &client1_can_reply, client_pump); | 813 client_pump, std::move(pipe2.handle1)); |
763 workers.push_back(worker); | 814 workers.push_back(worker); |
764 | 815 |
765 worker = new MultipleServer1(server_pump); | 816 worker = new MultipleServer1(server_pump, std::move(pipe1.handle0)); |
766 worker->OverrideThread(&worker_thread); | 817 worker->OverrideThread(&worker_thread); |
767 workers.push_back(worker); | 818 workers.push_back(worker); |
768 | 819 |
769 worker = new MultipleClient1( | 820 worker = new MultipleClient1(&client1_msg_received, &client1_can_reply, |
770 &client1_msg_received, &client1_can_reply); | 821 std::move(pipe1.handle1)); |
771 workers.push_back(worker); | 822 workers.push_back(worker); |
772 | 823 |
773 RunTest(workers); | 824 RunTest(workers); |
774 } | 825 } |
775 | 826 |
776 // Tests that multiple SyncObjects on the same listener thread can unblock each | 827 // Tests that multiple SyncObjects on the same listener thread can unblock each |
777 // other. | 828 // other. |
778 TEST_F(IPCSyncChannelTest, Multiple) { | 829 TEST_F(IPCSyncChannelTest, Multiple) { |
779 Multiple(false, false); | 830 Multiple(false, false); |
780 Multiple(false, true); | 831 Multiple(false, true); |
781 Multiple(true, false); | 832 Multiple(true, false); |
782 Multiple(true, true); | 833 Multiple(true, true); |
783 } | 834 } |
784 | 835 |
785 //------------------------------------------------------------------------------ | 836 //------------------------------------------------------------------------------ |
786 | 837 |
787 // This class provides server side functionality to test the case where | 838 // This class provides server side functionality to test the case where |
788 // multiple sync channels are in use on the same thread on the client and | 839 // multiple sync channels are in use on the same thread on the client and |
789 // nested calls are issued. | 840 // nested calls are issued. |
790 class QueuedReplyServer : public Worker { | 841 class QueuedReplyServer : public Worker { |
791 public: | 842 public: |
792 QueuedReplyServer(base::Thread* listener_thread, | 843 QueuedReplyServer(base::Thread* listener_thread, |
793 const std::string& channel_name, | 844 mojo::ScopedMessagePipeHandle channel_handle, |
794 const std::string& reply_text) | 845 const std::string& reply_text) |
795 : Worker(channel_name, Channel::MODE_SERVER), | 846 : Worker(std::move(channel_handle), Channel::MODE_SERVER), |
796 reply_text_(reply_text) { | 847 reply_text_(reply_text) { |
797 Worker::OverrideThread(listener_thread); | 848 Worker::OverrideThread(listener_thread); |
798 } | 849 } |
799 | 850 |
800 void OnNestedTestMsg(Message* reply_msg) override { | 851 void OnNestedTestMsg(Message* reply_msg) override { |
801 VLOG(1) << __FUNCTION__ << " Sending reply: " << reply_text_; | 852 VLOG(1) << __FUNCTION__ << " Sending reply: " << reply_text_; |
802 SyncChannelNestedTestMsg_String::WriteReplyParams(reply_msg, reply_text_); | 853 SyncChannelNestedTestMsg_String::WriteReplyParams(reply_msg, reply_text_); |
803 Send(reply_msg); | 854 Send(reply_msg); |
804 Done(); | 855 Done(); |
805 } | 856 } |
806 | 857 |
807 private: | 858 private: |
808 std::string reply_text_; | 859 std::string reply_text_; |
809 }; | 860 }; |
810 | 861 |
811 // The QueuedReplyClient class provides functionality to test the case where | 862 // The QueuedReplyClient class provides functionality to test the case where |
812 // multiple sync channels are in use on the same thread and they make nested | 863 // multiple sync channels are in use on the same thread and they make nested |
813 // sync calls, i.e. while the first channel waits for a response it makes a | 864 // sync calls, i.e. while the first channel waits for a response it makes a |
814 // sync call on another channel. | 865 // sync call on another channel. |
815 // The callstack should unwind correctly, i.e. the outermost call should | 866 // The callstack should unwind correctly, i.e. the outermost call should |
816 // complete first, and so on. | 867 // complete first, and so on. |
817 class QueuedReplyClient : public Worker { | 868 class QueuedReplyClient : public Worker { |
818 public: | 869 public: |
819 QueuedReplyClient(base::Thread* listener_thread, | 870 QueuedReplyClient(base::Thread* listener_thread, |
820 const std::string& channel_name, | 871 mojo::ScopedMessagePipeHandle channel_handle, |
821 const std::string& expected_text, | 872 const std::string& expected_text, |
822 bool pump_during_send) | 873 bool pump_during_send) |
823 : Worker(channel_name, Channel::MODE_CLIENT), | 874 : Worker(std::move(channel_handle), Channel::MODE_CLIENT), |
824 pump_during_send_(pump_during_send), | 875 pump_during_send_(pump_during_send), |
825 expected_text_(expected_text) { | 876 expected_text_(expected_text) { |
826 Worker::OverrideThread(listener_thread); | 877 Worker::OverrideThread(listener_thread); |
827 } | 878 } |
828 | 879 |
829 void Run() override { | 880 void Run() override { |
830 std::string response; | 881 std::string response; |
831 SyncMessage* msg = new SyncChannelNestedTestMsg_String(&response); | 882 SyncMessage* msg = new SyncChannelNestedTestMsg_String(&response); |
832 if (pump_during_send_) | 883 if (pump_during_send_) |
833 msg->EnableMessagePumping(); | 884 msg->EnableMessagePumping(); |
(...skipping 15 matching lines...) Expand all Loading... |
849 | 900 |
850 // A shared worker thread for servers | 901 // A shared worker thread for servers |
851 base::Thread server_worker_thread("QueuedReply_ServerListener"); | 902 base::Thread server_worker_thread("QueuedReply_ServerListener"); |
852 ASSERT_TRUE(server_worker_thread.Start()); | 903 ASSERT_TRUE(server_worker_thread.Start()); |
853 | 904 |
854 base::Thread client_worker_thread("QueuedReply_ClientListener"); | 905 base::Thread client_worker_thread("QueuedReply_ClientListener"); |
855 ASSERT_TRUE(client_worker_thread.Start()); | 906 ASSERT_TRUE(client_worker_thread.Start()); |
856 | 907 |
857 Worker* worker; | 908 Worker* worker; |
858 | 909 |
| 910 mojo::MessagePipe pipe1, pipe2; |
859 worker = new QueuedReplyServer(&server_worker_thread, | 911 worker = new QueuedReplyServer(&server_worker_thread, |
860 "QueuedReply_Server1", | 912 std::move(pipe1.handle0), "Got first message"); |
861 "Got first message"); | |
862 workers.push_back(worker); | 913 workers.push_back(worker); |
863 | 914 |
864 worker = new QueuedReplyServer(&server_worker_thread, | 915 worker = new QueuedReplyServer( |
865 "QueuedReply_Server2", | 916 &server_worker_thread, std::move(pipe2.handle0), "Got second message"); |
866 "Got second message"); | |
867 workers.push_back(worker); | 917 workers.push_back(worker); |
868 | 918 |
869 worker = new QueuedReplyClient(&client_worker_thread, | 919 worker = |
870 "QueuedReply_Server1", | 920 new QueuedReplyClient(&client_worker_thread, std::move(pipe1.handle1), |
871 "Got first message", | 921 "Got first message", client_pump); |
872 client_pump); | |
873 workers.push_back(worker); | 922 workers.push_back(worker); |
874 | 923 |
875 worker = new QueuedReplyClient(&client_worker_thread, | 924 worker = |
876 "QueuedReply_Server2", | 925 new QueuedReplyClient(&client_worker_thread, std::move(pipe2.handle1), |
877 "Got second message", | 926 "Got second message", client_pump); |
878 client_pump); | |
879 workers.push_back(worker); | 927 workers.push_back(worker); |
880 | 928 |
881 RunTest(workers); | 929 RunTest(workers); |
882 } | 930 } |
883 | 931 |
884 // While a blocking send is in progress, the listener thread might answer other | 932 // While a blocking send is in progress, the listener thread might answer other |
885 // synchronous messages. This tests that if during the response to another | 933 // synchronous messages. This tests that if during the response to another |
886 // message the reply to the original messages comes, it is queued up correctly | 934 // message the reply to the original messages comes, it is queued up correctly |
887 // and the original Send is unblocked later. | 935 // and the original Send is unblocked later. |
888 // We also test that the send call stacks unwind correctly when the channel | 936 // We also test that the send call stacks unwind correctly when the channel |
889 // pumps messages while waiting for a response. | 937 // pumps messages while waiting for a response. |
890 TEST_F(IPCSyncChannelTest, QueuedReply) { | 938 TEST_F(IPCSyncChannelTest, QueuedReply) { |
891 QueuedReply(false); | 939 QueuedReply(false); |
892 QueuedReply(true); | 940 QueuedReply(true); |
893 } | 941 } |
894 | 942 |
895 //------------------------------------------------------------------------------ | 943 //------------------------------------------------------------------------------ |
896 | 944 |
897 class ChattyClient : public Worker { | 945 class ChattyClient : public Worker { |
898 public: | 946 public: |
899 explicit ChattyClient(const std::string& channel_name) | 947 explicit ChattyClient(mojo::ScopedMessagePipeHandle channel_handle) |
900 : Worker(Channel::MODE_CLIENT, "chatty_client", channel_name) {} | 948 : Worker(Channel::MODE_CLIENT, |
| 949 "chatty_client", |
| 950 std::move(channel_handle)) {} |
901 | 951 |
902 void OnAnswer(int* answer) override { | 952 void OnAnswer(int* answer) override { |
903 // The PostMessage limit is 10k. Send 20% more than that. | 953 // The PostMessage limit is 10k. Send 20% more than that. |
904 const int kMessageLimit = 10000; | 954 const int kMessageLimit = 10000; |
905 const int kMessagesToSend = kMessageLimit * 120 / 100; | 955 const int kMessagesToSend = kMessageLimit * 120 / 100; |
906 for (int i = 0; i < kMessagesToSend; ++i) { | 956 for (int i = 0; i < kMessagesToSend; ++i) { |
907 if (!SendDouble(false, true)) | 957 if (!SendDouble(false, true)) |
908 break; | 958 break; |
909 } | 959 } |
910 *answer = 42; | 960 *answer = 42; |
911 Done(); | 961 Done(); |
912 } | 962 } |
913 }; | 963 }; |
914 | 964 |
915 void ChattyServer(bool pump_during_send) { | 965 void ChattyServer(bool pump_during_send) { |
916 std::vector<Worker*> workers; | 966 std::vector<Worker*> workers; |
917 workers.push_back(new UnblockServer(pump_during_send, false, "ChattyServer")); | 967 mojo::MessagePipe pipe; |
918 workers.push_back(new ChattyClient("ChattyServer")); | 968 workers.push_back( |
| 969 new UnblockServer(pump_during_send, false, std::move(pipe.handle0))); |
| 970 workers.push_back(new ChattyClient(std::move(pipe.handle1))); |
919 RunTest(workers); | 971 RunTest(workers); |
920 } | 972 } |
921 | 973 |
922 #if defined(OS_ANDROID) | 974 #if defined(OS_ANDROID) |
923 // Times out. | 975 // Times out. |
924 #define MAYBE_ChattyServer DISABLED_ChattyServer | 976 #define MAYBE_ChattyServer DISABLED_ChattyServer |
925 #else | 977 #else |
926 #define MAYBE_ChattyServer ChattyServer | 978 #define MAYBE_ChattyServer ChattyServer |
927 #endif | 979 #endif |
928 // Tests http://b/1093251 - that sending lots of sync messages while | 980 // Tests http://b/1093251 - that sending lots of sync messages while |
929 // the receiver is waiting for a sync reply does not overflow the PostMessage | 981 // the receiver is waiting for a sync reply does not overflow the PostMessage |
930 // queue. | 982 // queue. |
931 TEST_F(IPCSyncChannelTest, MAYBE_ChattyServer) { | 983 TEST_F(IPCSyncChannelTest, MAYBE_ChattyServer) { |
932 ChattyServer(false); | 984 ChattyServer(false); |
| 985 } |
| 986 |
| 987 #if defined(OS_ANDROID) |
| 988 // Times out. |
| 989 #define MAYBE_ChattyServerPumpDuringSend DISABLED_ChattyServerPumpDuringSend |
| 990 #else |
| 991 #define MAYBE_ChattyServerPumpDuringSend ChattyServerPumpDuringSend |
| 992 #endif |
| 993 TEST_F(IPCSyncChannelTest, MAYBE_ChattyServerPumpDuringSend) { |
933 ChattyServer(true); | 994 ChattyServer(true); |
934 } | 995 } |
935 | 996 |
936 //------------------------------------------------------------------------------ | 997 //------------------------------------------------------------------------------ |
937 | 998 |
938 void NestedCallback(Worker* server) { | 999 void NestedCallback(Worker* server) { |
939 // Sleep a bit so that we wake up after the reply has been received. | 1000 // Sleep a bit so that we wake up after the reply has been received. |
940 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(250)); | 1001 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(250)); |
941 server->SendAnswerToLife(true, true); | 1002 server->SendAnswerToLife(true, true); |
942 } | 1003 } |
943 | 1004 |
944 bool timeout_occurred = false; | 1005 bool timeout_occurred = false; |
945 | 1006 |
946 void TimeoutCallback() { | 1007 void TimeoutCallback() { |
947 timeout_occurred = true; | 1008 timeout_occurred = true; |
948 } | 1009 } |
949 | 1010 |
950 class DoneEventRaceServer : public Worker { | 1011 class DoneEventRaceServer : public Worker { |
951 public: | 1012 public: |
952 explicit DoneEventRaceServer(const std::string& channel_name) | 1013 explicit DoneEventRaceServer(mojo::ScopedMessagePipeHandle channel_handle) |
953 : Worker(Channel::MODE_SERVER, "done_event_race_server", channel_name) {} | 1014 : Worker(Channel::MODE_SERVER, |
| 1015 "done_event_race_server", |
| 1016 std::move(channel_handle)) {} |
954 | 1017 |
955 void Run() override { | 1018 void Run() override { |
956 base::ThreadTaskRunnerHandle::Get()->PostTask( | 1019 base::ThreadTaskRunnerHandle::Get()->PostTask( |
957 FROM_HERE, base::Bind(&NestedCallback, this)); | 1020 FROM_HERE, base::Bind(&NestedCallback, this)); |
958 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 1021 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
959 FROM_HERE, base::Bind(&TimeoutCallback), | 1022 FROM_HERE, base::Bind(&TimeoutCallback), |
960 base::TimeDelta::FromSeconds(9)); | 1023 base::TimeDelta::FromSeconds(9)); |
961 // Even though we have a timeout on the Send, it will succeed since for this | 1024 // Even though we have a timeout on the Send, it will succeed since for this |
962 // bug, the reply message comes back and is deserialized, however the done | 1025 // bug, the reply message comes back and is deserialized, however the done |
963 // event wasn't set. So we indirectly use the timeout task to notice if a | 1026 // event wasn't set. So we indirectly use the timeout task to notice if a |
964 // timeout occurred. | 1027 // timeout occurred. |
965 SendAnswerToLife(true, true); | 1028 SendAnswerToLife(true, true); |
966 DCHECK(!timeout_occurred); | 1029 DCHECK(!timeout_occurred); |
967 Done(); | 1030 Done(); |
968 } | 1031 } |
969 }; | 1032 }; |
970 | 1033 |
971 #if defined(OS_ANDROID) | 1034 #if defined(OS_ANDROID) |
972 #define MAYBE_DoneEventRace DISABLED_DoneEventRace | 1035 #define MAYBE_DoneEventRace DISABLED_DoneEventRace |
973 #else | 1036 #else |
974 #define MAYBE_DoneEventRace DoneEventRace | 1037 #define MAYBE_DoneEventRace DoneEventRace |
975 #endif | 1038 #endif |
976 // Tests http://b/1474092 - that if after the done_event is set but before | 1039 // Tests http://b/1474092 - that if after the done_event is set but before |
977 // OnObjectSignaled is called another message is sent out, then after its | 1040 // OnObjectSignaled is called another message is sent out, then after its |
978 // reply comes back OnObjectSignaled will be called for the first message. | 1041 // reply comes back OnObjectSignaled will be called for the first message. |
979 TEST_F(IPCSyncChannelTest, MAYBE_DoneEventRace) { | 1042 TEST_F(IPCSyncChannelTest, MAYBE_DoneEventRace) { |
980 std::vector<Worker*> workers; | 1043 std::vector<Worker*> workers; |
981 workers.push_back(new DoneEventRaceServer("DoneEventRace")); | 1044 mojo::MessagePipe pipe; |
982 workers.push_back(new SimpleClient("DoneEventRace")); | 1045 workers.push_back(new DoneEventRaceServer(std::move(pipe.handle0))); |
| 1046 workers.push_back(new SimpleClient(std::move(pipe.handle1))); |
983 RunTest(workers); | 1047 RunTest(workers); |
984 } | 1048 } |
985 | 1049 |
986 //------------------------------------------------------------------------------ | 1050 //------------------------------------------------------------------------------ |
987 | 1051 |
988 class TestSyncMessageFilter : public SyncMessageFilter { | 1052 class TestSyncMessageFilter : public SyncMessageFilter { |
989 public: | 1053 public: |
990 TestSyncMessageFilter( | 1054 TestSyncMessageFilter( |
991 base::WaitableEvent* shutdown_event, | 1055 base::WaitableEvent* shutdown_event, |
992 Worker* worker, | 1056 Worker* worker, |
(...skipping 20 matching lines...) Expand all Loading... |
1013 | 1077 |
1014 private: | 1078 private: |
1015 ~TestSyncMessageFilter() override {} | 1079 ~TestSyncMessageFilter() override {} |
1016 | 1080 |
1017 Worker* worker_; | 1081 Worker* worker_; |
1018 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 1082 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
1019 }; | 1083 }; |
1020 | 1084 |
1021 class SyncMessageFilterServer : public Worker { | 1085 class SyncMessageFilterServer : public Worker { |
1022 public: | 1086 public: |
1023 explicit SyncMessageFilterServer(const std::string& channel_name) | 1087 explicit SyncMessageFilterServer(mojo::ScopedMessagePipeHandle channel_handle) |
1024 : Worker(Channel::MODE_SERVER, | 1088 : Worker(Channel::MODE_SERVER, |
1025 "sync_message_filter_server", | 1089 "sync_message_filter_server", |
1026 channel_name), | 1090 std::move(channel_handle)), |
1027 thread_("helper_thread") { | 1091 thread_("helper_thread") { |
1028 base::Thread::Options options; | 1092 base::Thread::Options options; |
1029 options.message_loop_type = base::MessageLoop::TYPE_DEFAULT; | 1093 options.message_loop_type = base::MessageLoop::TYPE_DEFAULT; |
1030 thread_.StartWithOptions(options); | 1094 thread_.StartWithOptions(options); |
1031 filter_ = new TestSyncMessageFilter(shutdown_event(), this, | 1095 filter_ = new TestSyncMessageFilter(shutdown_event(), this, |
1032 thread_.task_runner()); | 1096 thread_.task_runner()); |
1033 } | 1097 } |
1034 | 1098 |
1035 void Run() override { | 1099 void Run() override { |
1036 channel()->AddFilter(filter_.get()); | 1100 channel()->AddFilter(filter_.get()); |
1037 } | 1101 } |
1038 | 1102 |
1039 base::Thread thread_; | 1103 base::Thread thread_; |
1040 scoped_refptr<TestSyncMessageFilter> filter_; | 1104 scoped_refptr<TestSyncMessageFilter> filter_; |
1041 }; | 1105 }; |
1042 | 1106 |
1043 // This class provides functionality to test the case that a Send on the sync | 1107 // This class provides functionality to test the case that a Send on the sync |
1044 // channel does not crash after the channel has been closed. | 1108 // channel does not crash after the channel has been closed. |
1045 class ServerSendAfterClose : public Worker { | 1109 class ServerSendAfterClose : public Worker { |
1046 public: | 1110 public: |
1047 explicit ServerSendAfterClose(const std::string& channel_name) | 1111 explicit ServerSendAfterClose(mojo::ScopedMessagePipeHandle channel_handle) |
1048 : Worker(Channel::MODE_SERVER, "simpler_server", channel_name), | 1112 : Worker(Channel::MODE_SERVER, |
| 1113 "simpler_server", |
| 1114 std::move(channel_handle)), |
1049 send_result_(true) {} | 1115 send_result_(true) {} |
1050 | 1116 |
1051 bool SendDummy() { | 1117 bool SendDummy() { |
1052 ListenerThread()->task_runner()->PostTask( | 1118 ListenerThread()->task_runner()->PostTask( |
1053 FROM_HERE, base::Bind(base::IgnoreResult(&ServerSendAfterClose::Send), | 1119 FROM_HERE, base::Bind(base::IgnoreResult(&ServerSendAfterClose::Send), |
1054 this, new SyncChannelTestMsg_NoArgs)); | 1120 this, new SyncChannelTestMsg_NoArgs)); |
1055 return true; | 1121 return true; |
1056 } | 1122 } |
1057 | 1123 |
1058 bool send_result() const { | 1124 bool send_result() const { |
(...skipping 11 matching lines...) Expand all Loading... |
1070 Done(); | 1136 Done(); |
1071 return send_result_; | 1137 return send_result_; |
1072 } | 1138 } |
1073 | 1139 |
1074 bool send_result_; | 1140 bool send_result_; |
1075 }; | 1141 }; |
1076 | 1142 |
1077 // Tests basic synchronous call | 1143 // Tests basic synchronous call |
1078 TEST_F(IPCSyncChannelTest, SyncMessageFilter) { | 1144 TEST_F(IPCSyncChannelTest, SyncMessageFilter) { |
1079 std::vector<Worker*> workers; | 1145 std::vector<Worker*> workers; |
1080 workers.push_back(new SyncMessageFilterServer("SyncMessageFilter")); | 1146 mojo::MessagePipe pipe; |
1081 workers.push_back(new SimpleClient("SyncMessageFilter")); | 1147 workers.push_back(new SyncMessageFilterServer(std::move(pipe.handle0))); |
| 1148 workers.push_back(new SimpleClient(std::move(pipe.handle1))); |
1082 RunTest(workers); | 1149 RunTest(workers); |
1083 } | 1150 } |
1084 | 1151 |
1085 // Test the case when the channel is closed and a Send is attempted after that. | 1152 // Test the case when the channel is closed and a Send is attempted after that. |
1086 TEST_F(IPCSyncChannelTest, SendAfterClose) { | 1153 TEST_F(IPCSyncChannelTest, SendAfterClose) { |
1087 ServerSendAfterClose server("SendAfterClose"); | 1154 mojo::MessagePipe pipe; |
| 1155 ServerSendAfterClose server(std::move(pipe.handle0)); |
1088 server.Start(); | 1156 server.Start(); |
1089 | 1157 |
1090 server.done_event()->Wait(); | 1158 server.done_event()->Wait(); |
1091 server.done_event()->Reset(); | 1159 server.done_event()->Reset(); |
1092 | 1160 |
1093 server.SendDummy(); | 1161 server.SendDummy(); |
1094 server.done_event()->Wait(); | 1162 server.done_event()->Wait(); |
1095 | 1163 |
1096 EXPECT_FALSE(server.send_result()); | 1164 EXPECT_FALSE(server.send_result()); |
1097 | 1165 |
1098 server.Shutdown(); | 1166 server.Shutdown(); |
1099 } | 1167 } |
1100 | 1168 |
1101 //------------------------------------------------------------------------------ | 1169 //------------------------------------------------------------------------------ |
1102 | 1170 |
1103 class RestrictedDispatchServer : public Worker { | 1171 class RestrictedDispatchServer : public Worker { |
1104 public: | 1172 public: |
1105 RestrictedDispatchServer(WaitableEvent* sent_ping_event, | 1173 RestrictedDispatchServer(WaitableEvent* sent_ping_event, |
1106 WaitableEvent* wait_event) | 1174 WaitableEvent* wait_event, |
1107 : Worker("restricted_channel", Channel::MODE_SERVER), | 1175 mojo::ScopedMessagePipeHandle channel_handle) |
| 1176 : Worker(std::move(channel_handle), Channel::MODE_SERVER), |
1108 sent_ping_event_(sent_ping_event), | 1177 sent_ping_event_(sent_ping_event), |
1109 wait_event_(wait_event) { } | 1178 wait_event_(wait_event) {} |
1110 | 1179 |
1111 void OnDoPing(int ping) { | 1180 void OnDoPing(int ping) { |
1112 // Send an asynchronous message that unblocks the caller. | 1181 // Send an asynchronous message that unblocks the caller. |
1113 Message* msg = new SyncChannelTestMsg_Ping(ping); | 1182 Message* msg = new SyncChannelTestMsg_Ping(ping); |
1114 msg->set_unblock(true); | 1183 msg->set_unblock(true); |
1115 Send(msg); | 1184 Send(msg); |
1116 // Signal the event after the message has been sent on the channel, on the | 1185 // Signal the event after the message has been sent on the channel, on the |
1117 // IPC thread. | 1186 // IPC thread. |
1118 ipc_thread().task_runner()->PostTask( | 1187 ipc_thread().task_runner()->PostTask( |
1119 FROM_HERE, base::Bind(&RestrictedDispatchServer::OnPingSent, this)); | 1188 FROM_HERE, base::Bind(&RestrictedDispatchServer::OnPingSent, this)); |
(...skipping 20 matching lines...) Expand all Loading... |
1140 sent_ping_event_->Signal(); | 1209 sent_ping_event_->Signal(); |
1141 } | 1210 } |
1142 | 1211 |
1143 void OnNoArgs() { } | 1212 void OnNoArgs() { } |
1144 WaitableEvent* sent_ping_event_; | 1213 WaitableEvent* sent_ping_event_; |
1145 WaitableEvent* wait_event_; | 1214 WaitableEvent* wait_event_; |
1146 }; | 1215 }; |
1147 | 1216 |
1148 class NonRestrictedDispatchServer : public Worker { | 1217 class NonRestrictedDispatchServer : public Worker { |
1149 public: | 1218 public: |
1150 NonRestrictedDispatchServer(WaitableEvent* signal_event) | 1219 NonRestrictedDispatchServer(WaitableEvent* signal_event, |
1151 : Worker("non_restricted_channel", Channel::MODE_SERVER), | 1220 mojo::ScopedMessagePipeHandle channel_handle) |
| 1221 : Worker(std::move(channel_handle), Channel::MODE_SERVER), |
1152 signal_event_(signal_event) {} | 1222 signal_event_(signal_event) {} |
1153 | 1223 |
1154 base::Thread* ListenerThread() { return Worker::ListenerThread(); } | 1224 base::Thread* ListenerThread() { return Worker::ListenerThread(); } |
1155 | 1225 |
1156 void OnDoPingTTL(int ping) { | 1226 void OnDoPingTTL(int ping) { |
1157 int value = 0; | 1227 int value = 0; |
1158 Send(new SyncChannelTestMsg_PingTTL(ping, &value)); | 1228 Send(new SyncChannelTestMsg_PingTTL(ping, &value)); |
1159 signal_event_->Signal(); | 1229 signal_event_->Signal(); |
1160 } | 1230 } |
1161 | 1231 |
1162 private: | 1232 private: |
1163 bool OnMessageReceived(const Message& message) override { | 1233 bool OnMessageReceived(const Message& message) override { |
1164 IPC_BEGIN_MESSAGE_MAP(NonRestrictedDispatchServer, message) | 1234 IPC_BEGIN_MESSAGE_MAP(NonRestrictedDispatchServer, message) |
1165 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs, OnNoArgs) | 1235 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs, OnNoArgs) |
1166 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done, Done) | 1236 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done, Done) |
1167 IPC_END_MESSAGE_MAP() | 1237 IPC_END_MESSAGE_MAP() |
1168 return true; | 1238 return true; |
1169 } | 1239 } |
1170 | 1240 |
1171 void OnNoArgs() { } | 1241 void OnNoArgs() { } |
1172 WaitableEvent* signal_event_; | 1242 WaitableEvent* signal_event_; |
1173 }; | 1243 }; |
1174 | 1244 |
1175 class RestrictedDispatchClient : public Worker { | 1245 class RestrictedDispatchClient : public Worker { |
1176 public: | 1246 public: |
1177 RestrictedDispatchClient(WaitableEvent* sent_ping_event, | 1247 RestrictedDispatchClient( |
1178 RestrictedDispatchServer* server, | 1248 WaitableEvent* sent_ping_event, |
1179 NonRestrictedDispatchServer* server2, | 1249 RestrictedDispatchServer* server, |
1180 int* success) | 1250 NonRestrictedDispatchServer* server2, |
1181 : Worker("restricted_channel", Channel::MODE_CLIENT), | 1251 int* success, |
| 1252 mojo::ScopedMessagePipeHandle restricted_channel_handle, |
| 1253 mojo::ScopedMessagePipeHandle non_restricted_channel_handle) |
| 1254 : Worker(std::move(restricted_channel_handle), Channel::MODE_CLIENT), |
1182 ping_(0), | 1255 ping_(0), |
1183 server_(server), | 1256 server_(server), |
1184 server2_(server2), | 1257 server2_(server2), |
1185 success_(success), | 1258 success_(success), |
1186 sent_ping_event_(sent_ping_event) {} | 1259 sent_ping_event_(sent_ping_event), |
| 1260 non_restricted_channel_handle_( |
| 1261 std::move(non_restricted_channel_handle)) {} |
1187 | 1262 |
1188 void Run() override { | 1263 void Run() override { |
1189 // Incoming messages from our channel should only be dispatched when we | 1264 // Incoming messages from our channel should only be dispatched when we |
1190 // send a message on that same channel. | 1265 // send a message on that same channel. |
1191 channel()->SetRestrictDispatchChannelGroup(1); | 1266 channel()->SetRestrictDispatchChannelGroup(1); |
1192 | 1267 |
1193 server_->ListenerThread()->task_runner()->PostTask( | 1268 server_->ListenerThread()->task_runner()->PostTask( |
1194 FROM_HERE, base::Bind(&RestrictedDispatchServer::OnDoPing, server_, 1)); | 1269 FROM_HERE, base::Bind(&RestrictedDispatchServer::OnDoPing, server_, 1)); |
1195 sent_ping_event_->Wait(); | 1270 sent_ping_event_->Wait(); |
1196 Send(new SyncChannelTestMsg_NoArgs); | 1271 Send(new SyncChannelTestMsg_NoArgs); |
1197 if (ping_ == 1) | 1272 if (ping_ == 1) |
1198 ++*success_; | 1273 ++*success_; |
1199 else | 1274 else |
1200 LOG(ERROR) << "Send failed to dispatch incoming message on same channel"; | 1275 LOG(ERROR) << "Send failed to dispatch incoming message on same channel"; |
1201 | 1276 |
1202 non_restricted_channel_ = SyncChannel::Create( | 1277 non_restricted_channel_ = SyncChannel::Create( |
1203 "non_restricted_channel", IPC::Channel::MODE_CLIENT, this, | 1278 non_restricted_channel_handle_.release(), IPC::Channel::MODE_CLIENT, |
1204 ipc_thread().task_runner().get(), true, shutdown_event()); | 1279 this, ipc_thread().task_runner(), true, shutdown_event()); |
1205 | 1280 |
1206 server_->ListenerThread()->task_runner()->PostTask( | 1281 server_->ListenerThread()->task_runner()->PostTask( |
1207 FROM_HERE, base::Bind(&RestrictedDispatchServer::OnDoPing, server_, 2)); | 1282 FROM_HERE, base::Bind(&RestrictedDispatchServer::OnDoPing, server_, 2)); |
1208 sent_ping_event_->Wait(); | 1283 sent_ping_event_->Wait(); |
1209 // Check that the incoming message is *not* dispatched when sending on the | 1284 // Check that the incoming message is *not* dispatched when sending on the |
1210 // non restricted channel. | 1285 // non restricted channel. |
1211 // TODO(piman): there is a possibility of a false positive race condition | 1286 // TODO(piman): there is a possibility of a false positive race condition |
1212 // here, if the message that was posted on the server-side end of the pipe | 1287 // here, if the message that was posted on the server-side end of the pipe |
1213 // is not visible yet on the client side, but I don't know how to solve this | 1288 // is not visible yet on the client side, but I don't know how to solve this |
1214 // without hooking into the internals of SyncChannel. I haven't seen it in | 1289 // without hooking into the internals of SyncChannel. I haven't seen it in |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1264 SyncChannelTestMsg_PingTTL::WriteReplyParams(reply, ping); | 1339 SyncChannelTestMsg_PingTTL::WriteReplyParams(reply, ping); |
1265 non_restricted_channel_->Send(reply); | 1340 non_restricted_channel_->Send(reply); |
1266 } | 1341 } |
1267 | 1342 |
1268 int ping_; | 1343 int ping_; |
1269 RestrictedDispatchServer* server_; | 1344 RestrictedDispatchServer* server_; |
1270 NonRestrictedDispatchServer* server2_; | 1345 NonRestrictedDispatchServer* server2_; |
1271 int* success_; | 1346 int* success_; |
1272 WaitableEvent* sent_ping_event_; | 1347 WaitableEvent* sent_ping_event_; |
1273 std::unique_ptr<SyncChannel> non_restricted_channel_; | 1348 std::unique_ptr<SyncChannel> non_restricted_channel_; |
| 1349 mojo::ScopedMessagePipeHandle non_restricted_channel_handle_; |
1274 }; | 1350 }; |
1275 | 1351 |
1276 TEST_F(IPCSyncChannelTest, RestrictedDispatch) { | 1352 TEST_F(IPCSyncChannelTest, RestrictedDispatch) { |
1277 WaitableEvent sent_ping_event( | 1353 WaitableEvent sent_ping_event( |
1278 base::WaitableEvent::ResetPolicy::AUTOMATIC, | 1354 base::WaitableEvent::ResetPolicy::AUTOMATIC, |
1279 base::WaitableEvent::InitialState::NOT_SIGNALED); | 1355 base::WaitableEvent::InitialState::NOT_SIGNALED); |
1280 WaitableEvent wait_event(base::WaitableEvent::ResetPolicy::AUTOMATIC, | 1356 WaitableEvent wait_event(base::WaitableEvent::ResetPolicy::AUTOMATIC, |
1281 base::WaitableEvent::InitialState::NOT_SIGNALED); | 1357 base::WaitableEvent::InitialState::NOT_SIGNALED); |
1282 RestrictedDispatchServer* server = | 1358 mojo::MessagePipe restricted_pipe, non_restricted_pipe; |
1283 new RestrictedDispatchServer(&sent_ping_event, &wait_event); | 1359 RestrictedDispatchServer* server = new RestrictedDispatchServer( |
1284 NonRestrictedDispatchServer* server2 = | 1360 &sent_ping_event, &wait_event, std::move(restricted_pipe.handle0)); |
1285 new NonRestrictedDispatchServer(&wait_event); | 1361 NonRestrictedDispatchServer* server2 = new NonRestrictedDispatchServer( |
| 1362 &wait_event, std::move(non_restricted_pipe.handle0)); |
1286 | 1363 |
1287 int success = 0; | 1364 int success = 0; |
1288 std::vector<Worker*> workers; | 1365 std::vector<Worker*> workers; |
1289 workers.push_back(server); | 1366 workers.push_back(server); |
1290 workers.push_back(server2); | 1367 workers.push_back(server2); |
1291 workers.push_back(new RestrictedDispatchClient( | 1368 workers.push_back( |
1292 &sent_ping_event, server, server2, &success)); | 1369 new RestrictedDispatchClient(&sent_ping_event, server, server2, &success, |
| 1370 std::move(restricted_pipe.handle1), |
| 1371 std::move(non_restricted_pipe.handle1))); |
1293 RunTest(workers); | 1372 RunTest(workers); |
1294 EXPECT_EQ(4, success); | 1373 EXPECT_EQ(4, success); |
1295 } | 1374 } |
1296 | 1375 |
1297 //------------------------------------------------------------------------------ | 1376 //------------------------------------------------------------------------------ |
1298 | 1377 |
1299 // This test case inspired by crbug.com/108491 | 1378 // This test case inspired by crbug.com/108491 |
1300 // We create two servers that use the same ListenerThread but have | 1379 // We create two servers that use the same ListenerThread but have |
1301 // SetRestrictDispatchToSameChannel set to true. | 1380 // SetRestrictDispatchToSameChannel set to true. |
1302 // We create clients, then use some specific WaitableEvent wait/signalling to | 1381 // We create clients, then use some specific WaitableEvent wait/signalling to |
(...skipping 18 matching lines...) Expand all Loading... |
1321 // event 0: indicate to client1 that server listener is in OnDoServerTask | 1400 // event 0: indicate to client1 that server listener is in OnDoServerTask |
1322 // event 1: indicate to client1 that client2 listener is in OnDoClient2Task | 1401 // event 1: indicate to client1 that client2 listener is in OnDoClient2Task |
1323 // event 2: indicate to server1 that client2 listener is in OnDoClient2Task | 1402 // event 2: indicate to server1 that client2 listener is in OnDoClient2Task |
1324 // event 3: indicate to client2 that server listener is in OnDoServerTask | 1403 // event 3: indicate to client2 that server listener is in OnDoServerTask |
1325 | 1404 |
1326 class RestrictedDispatchDeadlockServer : public Worker { | 1405 class RestrictedDispatchDeadlockServer : public Worker { |
1327 public: | 1406 public: |
1328 RestrictedDispatchDeadlockServer(int server_num, | 1407 RestrictedDispatchDeadlockServer(int server_num, |
1329 WaitableEvent* server_ready_event, | 1408 WaitableEvent* server_ready_event, |
1330 WaitableEvent** events, | 1409 WaitableEvent** events, |
1331 RestrictedDispatchDeadlockServer* peer) | 1410 RestrictedDispatchDeadlockServer* peer, |
1332 : Worker(server_num == 1 ? "channel1" : "channel2", Channel::MODE_SERVER), | 1411 mojo::ScopedMessagePipeHandle channel_handle) |
| 1412 : Worker(std::move(channel_handle), Channel::MODE_SERVER), |
1333 server_num_(server_num), | 1413 server_num_(server_num), |
1334 server_ready_event_(server_ready_event), | 1414 server_ready_event_(server_ready_event), |
1335 events_(events), | 1415 events_(events), |
1336 peer_(peer) { } | 1416 peer_(peer) {} |
1337 | 1417 |
1338 void OnDoServerTask() { | 1418 void OnDoServerTask() { |
1339 events_[3]->Signal(); | 1419 events_[3]->Signal(); |
1340 events_[2]->Wait(); | 1420 events_[2]->Wait(); |
1341 events_[0]->Signal(); | 1421 events_[0]->Signal(); |
1342 SendMessageToClient(); | 1422 SendMessageToClient(); |
1343 } | 1423 } |
1344 | 1424 |
1345 void Run() override { | 1425 void Run() override { |
1346 channel()->SetRestrictDispatchChannelGroup(1); | 1426 channel()->SetRestrictDispatchChannelGroup(1); |
(...skipping 26 matching lines...) Expand all Loading... |
1373 } | 1453 } |
1374 | 1454 |
1375 int server_num_; | 1455 int server_num_; |
1376 WaitableEvent* server_ready_event_; | 1456 WaitableEvent* server_ready_event_; |
1377 WaitableEvent** events_; | 1457 WaitableEvent** events_; |
1378 RestrictedDispatchDeadlockServer* peer_; | 1458 RestrictedDispatchDeadlockServer* peer_; |
1379 }; | 1459 }; |
1380 | 1460 |
1381 class RestrictedDispatchDeadlockClient2 : public Worker { | 1461 class RestrictedDispatchDeadlockClient2 : public Worker { |
1382 public: | 1462 public: |
1383 RestrictedDispatchDeadlockClient2(RestrictedDispatchDeadlockServer* server, | 1463 RestrictedDispatchDeadlockClient2( |
1384 WaitableEvent* server_ready_event, | 1464 RestrictedDispatchDeadlockServer* server, |
1385 WaitableEvent** events) | 1465 WaitableEvent* server_ready_event, |
1386 : Worker("channel2", Channel::MODE_CLIENT), | 1466 WaitableEvent** events, |
| 1467 mojo::ScopedMessagePipeHandle channel_handle) |
| 1468 : Worker(std::move(channel_handle), Channel::MODE_CLIENT), |
1387 server_ready_event_(server_ready_event), | 1469 server_ready_event_(server_ready_event), |
1388 events_(events), | 1470 events_(events), |
1389 received_msg_(false), | 1471 received_msg_(false), |
1390 received_noarg_reply_(false), | 1472 received_noarg_reply_(false), |
1391 done_issued_(false) {} | 1473 done_issued_(false) {} |
1392 | 1474 |
1393 void Run() override { | 1475 void Run() override { |
1394 server_ready_event_->Wait(); | 1476 server_ready_event_->Wait(); |
1395 } | 1477 } |
1396 | 1478 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1431 | 1513 |
1432 WaitableEvent* server_ready_event_; | 1514 WaitableEvent* server_ready_event_; |
1433 WaitableEvent** events_; | 1515 WaitableEvent** events_; |
1434 bool received_msg_; | 1516 bool received_msg_; |
1435 bool received_noarg_reply_; | 1517 bool received_noarg_reply_; |
1436 bool done_issued_; | 1518 bool done_issued_; |
1437 }; | 1519 }; |
1438 | 1520 |
1439 class RestrictedDispatchDeadlockClient1 : public Worker { | 1521 class RestrictedDispatchDeadlockClient1 : public Worker { |
1440 public: | 1522 public: |
1441 RestrictedDispatchDeadlockClient1(RestrictedDispatchDeadlockServer* server, | 1523 RestrictedDispatchDeadlockClient1( |
1442 RestrictedDispatchDeadlockClient2* peer, | 1524 RestrictedDispatchDeadlockServer* server, |
1443 WaitableEvent* server_ready_event, | 1525 RestrictedDispatchDeadlockClient2* peer, |
1444 WaitableEvent** events) | 1526 WaitableEvent* server_ready_event, |
1445 : Worker("channel1", Channel::MODE_CLIENT), | 1527 WaitableEvent** events, |
| 1528 mojo::ScopedMessagePipeHandle channel_handle) |
| 1529 : Worker(std::move(channel_handle), Channel::MODE_CLIENT), |
1446 server_(server), | 1530 server_(server), |
1447 peer_(peer), | 1531 peer_(peer), |
1448 server_ready_event_(server_ready_event), | 1532 server_ready_event_(server_ready_event), |
1449 events_(events), | 1533 events_(events), |
1450 received_msg_(false), | 1534 received_msg_(false), |
1451 received_noarg_reply_(false), | 1535 received_noarg_reply_(false), |
1452 done_issued_(false) {} | 1536 done_issued_(false) {} |
1453 | 1537 |
1454 void Run() override { | 1538 void Run() override { |
1455 server_ready_event_->Wait(); | 1539 server_ready_event_->Wait(); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1521 base::WaitableEvent::InitialState::NOT_SIGNALED); | 1605 base::WaitableEvent::InitialState::NOT_SIGNALED); |
1522 WaitableEvent event3(base::WaitableEvent::ResetPolicy::AUTOMATIC, | 1606 WaitableEvent event3(base::WaitableEvent::ResetPolicy::AUTOMATIC, |
1523 base::WaitableEvent::InitialState::NOT_SIGNALED); | 1607 base::WaitableEvent::InitialState::NOT_SIGNALED); |
1524 WaitableEvent* events[4] = {&event0, &event1, &event2, &event3}; | 1608 WaitableEvent* events[4] = {&event0, &event1, &event2, &event3}; |
1525 | 1609 |
1526 RestrictedDispatchDeadlockServer* server1; | 1610 RestrictedDispatchDeadlockServer* server1; |
1527 RestrictedDispatchDeadlockServer* server2; | 1611 RestrictedDispatchDeadlockServer* server2; |
1528 RestrictedDispatchDeadlockClient1* client1; | 1612 RestrictedDispatchDeadlockClient1* client1; |
1529 RestrictedDispatchDeadlockClient2* client2; | 1613 RestrictedDispatchDeadlockClient2* client2; |
1530 | 1614 |
1531 server2 = new RestrictedDispatchDeadlockServer(2, &server2_ready, events, | 1615 mojo::MessagePipe pipe1, pipe2; |
1532 NULL); | 1616 server2 = new RestrictedDispatchDeadlockServer( |
| 1617 2, &server2_ready, events, NULL, std::move(pipe2.handle0)); |
1533 server2->OverrideThread(&worker_thread); | 1618 server2->OverrideThread(&worker_thread); |
1534 workers.push_back(server2); | 1619 workers.push_back(server2); |
1535 | 1620 |
1536 client2 = new RestrictedDispatchDeadlockClient2(server2, &server2_ready, | 1621 client2 = new RestrictedDispatchDeadlockClient2( |
1537 events); | 1622 server2, &server2_ready, events, std::move(pipe2.handle1)); |
1538 workers.push_back(client2); | 1623 workers.push_back(client2); |
1539 | 1624 |
1540 server1 = new RestrictedDispatchDeadlockServer(1, &server1_ready, events, | 1625 server1 = new RestrictedDispatchDeadlockServer( |
1541 server2); | 1626 1, &server1_ready, events, server2, std::move(pipe1.handle0)); |
1542 server1->OverrideThread(&worker_thread); | 1627 server1->OverrideThread(&worker_thread); |
1543 workers.push_back(server1); | 1628 workers.push_back(server1); |
1544 | 1629 |
1545 client1 = new RestrictedDispatchDeadlockClient1(server1, client2, | 1630 client1 = new RestrictedDispatchDeadlockClient1( |
1546 &server1_ready, events); | 1631 server1, client2, &server1_ready, events, std::move(pipe1.handle1)); |
1547 workers.push_back(client1); | 1632 workers.push_back(client1); |
1548 | 1633 |
1549 RunTest(workers); | 1634 RunTest(workers); |
1550 } | 1635 } |
1551 | 1636 |
1552 //------------------------------------------------------------------------------ | 1637 //------------------------------------------------------------------------------ |
1553 | 1638 |
1554 // This test case inspired by crbug.com/120530 | 1639 // This test case inspired by crbug.com/120530 |
1555 // We create 4 workers that pipe to each other W1->W2->W3->W4->W1 then we send a | 1640 // We create 4 workers that pipe to each other W1->W2->W3->W4->W1 then we send a |
1556 // message that recurses through 3, 4 or 5 steps to make sure, say, W1 can | 1641 // message that recurses through 3, 4 or 5 steps to make sure, say, W1 can |
1557 // re-enter when called from W4 while it's sending a message to W2. | 1642 // re-enter when called from W4 while it's sending a message to W2. |
1558 // The first worker drives the whole test so it must be treated specially. | 1643 // The first worker drives the whole test so it must be treated specially. |
1559 | 1644 |
1560 class RestrictedDispatchPipeWorker : public Worker { | 1645 class RestrictedDispatchPipeWorker : public Worker { |
1561 public: | 1646 public: |
1562 RestrictedDispatchPipeWorker( | 1647 RestrictedDispatchPipeWorker(mojo::ScopedMessagePipeHandle channel_handle1, |
1563 const std::string &channel1, | 1648 WaitableEvent* event1, |
1564 WaitableEvent* event1, | 1649 mojo::ScopedMessagePipeHandle channel_handle2, |
1565 const std::string &channel2, | 1650 WaitableEvent* event2, |
1566 WaitableEvent* event2, | 1651 int group, |
1567 int group, | 1652 int* success) |
1568 int* success) | 1653 : Worker(std::move(channel_handle1), Channel::MODE_SERVER), |
1569 : Worker(channel1, Channel::MODE_SERVER), | |
1570 event1_(event1), | 1654 event1_(event1), |
1571 event2_(event2), | 1655 event2_(event2), |
1572 other_channel_name_(channel2), | 1656 other_channel_handle_(std::move(channel_handle2)), |
1573 group_(group), | 1657 group_(group), |
1574 success_(success) { | 1658 success_(success) {} |
1575 } | |
1576 | 1659 |
1577 void OnPingTTL(int ping, int* ret) { | 1660 void OnPingTTL(int ping, int* ret) { |
1578 *ret = 0; | 1661 *ret = 0; |
1579 if (!ping) | 1662 if (!ping) |
1580 return; | 1663 return; |
1581 other_channel_->Send(new SyncChannelTestMsg_PingTTL(ping - 1, ret)); | 1664 other_channel_->Send(new SyncChannelTestMsg_PingTTL(ping - 1, ret)); |
1582 ++*ret; | 1665 ++*ret; |
1583 } | 1666 } |
1584 | 1667 |
1585 void OnDone() { | 1668 void OnDone() { |
1586 if (is_first()) | 1669 if (is_first()) |
1587 return; | 1670 return; |
1588 other_channel_->Send(new SyncChannelTestMsg_Done); | 1671 other_channel_->Send(new SyncChannelTestMsg_Done); |
1589 other_channel_.reset(); | 1672 other_channel_.reset(); |
1590 Done(); | 1673 Done(); |
1591 } | 1674 } |
1592 | 1675 |
1593 void Run() override { | 1676 void Run() override { |
1594 channel()->SetRestrictDispatchChannelGroup(group_); | 1677 channel()->SetRestrictDispatchChannelGroup(group_); |
1595 if (is_first()) | 1678 if (is_first()) |
1596 event1_->Signal(); | 1679 event1_->Signal(); |
1597 event2_->Wait(); | 1680 event2_->Wait(); |
1598 other_channel_ = SyncChannel::Create( | 1681 other_channel_ = SyncChannel::Create( |
1599 other_channel_name_, IPC::Channel::MODE_CLIENT, this, | 1682 other_channel_handle_.release(), IPC::Channel::MODE_CLIENT, this, |
1600 ipc_thread().task_runner().get(), true, shutdown_event()); | 1683 ipc_thread().task_runner(), true, shutdown_event()); |
1601 other_channel_->SetRestrictDispatchChannelGroup(group_); | 1684 other_channel_->SetRestrictDispatchChannelGroup(group_); |
1602 if (!is_first()) { | 1685 if (!is_first()) { |
1603 event1_->Signal(); | 1686 event1_->Signal(); |
1604 return; | 1687 return; |
1605 } | 1688 } |
1606 *success_ = 0; | 1689 *success_ = 0; |
1607 int value = 0; | 1690 int value = 0; |
1608 OnPingTTL(3, &value); | 1691 OnPingTTL(3, &value); |
1609 *success_ += (value == 3); | 1692 *success_ += (value == 3); |
1610 OnPingTTL(4, &value); | 1693 OnPingTTL(4, &value); |
(...skipping 12 matching lines...) Expand all Loading... |
1623 IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchPipeWorker, message) | 1706 IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchPipeWorker, message) |
1624 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_PingTTL, OnPingTTL) | 1707 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_PingTTL, OnPingTTL) |
1625 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done, OnDone) | 1708 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done, OnDone) |
1626 IPC_END_MESSAGE_MAP() | 1709 IPC_END_MESSAGE_MAP() |
1627 return true; | 1710 return true; |
1628 } | 1711 } |
1629 | 1712 |
1630 std::unique_ptr<SyncChannel> other_channel_; | 1713 std::unique_ptr<SyncChannel> other_channel_; |
1631 WaitableEvent* event1_; | 1714 WaitableEvent* event1_; |
1632 WaitableEvent* event2_; | 1715 WaitableEvent* event2_; |
1633 std::string other_channel_name_; | 1716 mojo::ScopedMessagePipeHandle other_channel_handle_; |
1634 int group_; | 1717 int group_; |
1635 int* success_; | 1718 int* success_; |
1636 }; | 1719 }; |
1637 | 1720 |
1638 #if defined(OS_ANDROID) | 1721 #if defined(OS_ANDROID) |
1639 #define MAYBE_RestrictedDispatch4WayDeadlock \ | 1722 #define MAYBE_RestrictedDispatch4WayDeadlock \ |
1640 DISABLED_RestrictedDispatch4WayDeadlock | 1723 DISABLED_RestrictedDispatch4WayDeadlock |
1641 #else | 1724 #else |
1642 #define MAYBE_RestrictedDispatch4WayDeadlock RestrictedDispatch4WayDeadlock | 1725 #define MAYBE_RestrictedDispatch4WayDeadlock RestrictedDispatch4WayDeadlock |
1643 #endif | 1726 #endif |
1644 TEST_F(IPCSyncChannelTest, MAYBE_RestrictedDispatch4WayDeadlock) { | 1727 TEST_F(IPCSyncChannelTest, MAYBE_RestrictedDispatch4WayDeadlock) { |
1645 int success = 0; | 1728 int success = 0; |
1646 std::vector<Worker*> workers; | 1729 std::vector<Worker*> workers; |
1647 WaitableEvent event0(base::WaitableEvent::ResetPolicy::MANUAL, | 1730 WaitableEvent event0(base::WaitableEvent::ResetPolicy::MANUAL, |
1648 base::WaitableEvent::InitialState::NOT_SIGNALED); | 1731 base::WaitableEvent::InitialState::NOT_SIGNALED); |
1649 WaitableEvent event1(base::WaitableEvent::ResetPolicy::MANUAL, | 1732 WaitableEvent event1(base::WaitableEvent::ResetPolicy::MANUAL, |
1650 base::WaitableEvent::InitialState::NOT_SIGNALED); | 1733 base::WaitableEvent::InitialState::NOT_SIGNALED); |
1651 WaitableEvent event2(base::WaitableEvent::ResetPolicy::MANUAL, | 1734 WaitableEvent event2(base::WaitableEvent::ResetPolicy::MANUAL, |
1652 base::WaitableEvent::InitialState::NOT_SIGNALED); | 1735 base::WaitableEvent::InitialState::NOT_SIGNALED); |
1653 WaitableEvent event3(base::WaitableEvent::ResetPolicy::MANUAL, | 1736 WaitableEvent event3(base::WaitableEvent::ResetPolicy::MANUAL, |
1654 base::WaitableEvent::InitialState::NOT_SIGNALED); | 1737 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 1738 mojo::MessagePipe pipe0, pipe1, pipe2, pipe3; |
1655 workers.push_back(new RestrictedDispatchPipeWorker( | 1739 workers.push_back(new RestrictedDispatchPipeWorker( |
1656 "channel0", &event0, "channel1", &event1, 1, &success)); | 1740 std::move(pipe0.handle0), &event0, std::move(pipe1.handle1), &event1, 1, |
| 1741 &success)); |
1657 workers.push_back(new RestrictedDispatchPipeWorker( | 1742 workers.push_back(new RestrictedDispatchPipeWorker( |
1658 "channel1", &event1, "channel2", &event2, 2, NULL)); | 1743 std::move(pipe1.handle0), &event1, std::move(pipe2.handle1), &event2, 2, |
| 1744 NULL)); |
1659 workers.push_back(new RestrictedDispatchPipeWorker( | 1745 workers.push_back(new RestrictedDispatchPipeWorker( |
1660 "channel2", &event2, "channel3", &event3, 3, NULL)); | 1746 std::move(pipe2.handle0), &event2, std::move(pipe3.handle1), &event3, 3, |
| 1747 NULL)); |
1661 workers.push_back(new RestrictedDispatchPipeWorker( | 1748 workers.push_back(new RestrictedDispatchPipeWorker( |
1662 "channel3", &event3, "channel0", &event0, 4, NULL)); | 1749 std::move(pipe3.handle0), &event3, std::move(pipe0.handle1), &event0, 4, |
| 1750 NULL)); |
1663 RunTest(workers); | 1751 RunTest(workers); |
1664 EXPECT_EQ(3, success); | 1752 EXPECT_EQ(3, success); |
1665 } | 1753 } |
1666 | 1754 |
1667 //------------------------------------------------------------------------------ | 1755 //------------------------------------------------------------------------------ |
1668 | 1756 |
1669 // This test case inspired by crbug.com/122443 | 1757 // This test case inspired by crbug.com/122443 |
1670 // We want to make sure a reply message with the unblock flag set correctly | 1758 // We want to make sure a reply message with the unblock flag set correctly |
1671 // behaves as a reply, not a regular message. | 1759 // behaves as a reply, not a regular message. |
1672 // We have 3 workers. Server1 will send a message to Server2 (which will block), | 1760 // We have 3 workers. Server1 will send a message to Server2 (which will block), |
1673 // during which it will dispatch a message comming from Client, at which point | 1761 // during which it will dispatch a message comming from Client, at which point |
1674 // it will send another message to Server2. While sending that second message it | 1762 // it will send another message to Server2. While sending that second message it |
1675 // will receive a reply from Server1 with the unblock flag. | 1763 // will receive a reply from Server1 with the unblock flag. |
1676 | 1764 |
1677 class ReentrantReplyServer1 : public Worker { | 1765 class ReentrantReplyServer1 : public Worker { |
1678 public: | 1766 public: |
1679 ReentrantReplyServer1(WaitableEvent* server_ready) | 1767 ReentrantReplyServer1(WaitableEvent* server_ready, |
1680 : Worker("reentrant_reply1", Channel::MODE_SERVER), | 1768 mojo::ScopedMessagePipeHandle channel_handle1, |
1681 server_ready_(server_ready) { } | 1769 mojo::ScopedMessagePipeHandle channel_handle2) |
| 1770 : Worker(std::move(channel_handle1), Channel::MODE_SERVER), |
| 1771 server_ready_(server_ready), |
| 1772 other_channel_handle_(std::move(channel_handle2)) {} |
1682 | 1773 |
1683 void Run() override { | 1774 void Run() override { |
1684 server2_channel_ = SyncChannel::Create( | 1775 server2_channel_ = SyncChannel::Create( |
1685 "reentrant_reply2", IPC::Channel::MODE_CLIENT, this, | 1776 other_channel_handle_.release(), IPC::Channel::MODE_CLIENT, this, |
1686 ipc_thread().task_runner().get(), true, shutdown_event()); | 1777 ipc_thread().task_runner(), true, shutdown_event()); |
1687 server_ready_->Signal(); | 1778 server_ready_->Signal(); |
1688 Message* msg = new SyncChannelTestMsg_Reentrant1(); | 1779 Message* msg = new SyncChannelTestMsg_Reentrant1(); |
1689 server2_channel_->Send(msg); | 1780 server2_channel_->Send(msg); |
1690 server2_channel_.reset(); | 1781 server2_channel_.reset(); |
1691 Done(); | 1782 Done(); |
1692 } | 1783 } |
1693 | 1784 |
1694 private: | 1785 private: |
1695 bool OnMessageReceived(const Message& message) override { | 1786 bool OnMessageReceived(const Message& message) override { |
1696 IPC_BEGIN_MESSAGE_MAP(ReentrantReplyServer1, message) | 1787 IPC_BEGIN_MESSAGE_MAP(ReentrantReplyServer1, message) |
1697 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Reentrant2, OnReentrant2) | 1788 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Reentrant2, OnReentrant2) |
1698 IPC_REPLY_HANDLER(OnReply) | 1789 IPC_REPLY_HANDLER(OnReply) |
1699 IPC_END_MESSAGE_MAP() | 1790 IPC_END_MESSAGE_MAP() |
1700 return true; | 1791 return true; |
1701 } | 1792 } |
1702 | 1793 |
1703 void OnReentrant2() { | 1794 void OnReentrant2() { |
1704 Message* msg = new SyncChannelTestMsg_Reentrant3(); | 1795 Message* msg = new SyncChannelTestMsg_Reentrant3(); |
1705 server2_channel_->Send(msg); | 1796 server2_channel_->Send(msg); |
1706 } | 1797 } |
1707 | 1798 |
1708 void OnReply(const Message& message) { | 1799 void OnReply(const Message& message) { |
1709 // If we get here, the Send() will never receive the reply (thus would | 1800 // If we get here, the Send() will never receive the reply (thus would |
1710 // hang), so abort instead. | 1801 // hang), so abort instead. |
1711 LOG(FATAL) << "Reply message was dispatched"; | 1802 LOG(FATAL) << "Reply message was dispatched"; |
1712 } | 1803 } |
1713 | 1804 |
1714 WaitableEvent* server_ready_; | 1805 WaitableEvent* server_ready_; |
1715 std::unique_ptr<SyncChannel> server2_channel_; | 1806 std::unique_ptr<SyncChannel> server2_channel_; |
| 1807 mojo::ScopedMessagePipeHandle other_channel_handle_; |
1716 }; | 1808 }; |
1717 | 1809 |
1718 class ReentrantReplyServer2 : public Worker { | 1810 class ReentrantReplyServer2 : public Worker { |
1719 public: | 1811 public: |
1720 ReentrantReplyServer2() | 1812 ReentrantReplyServer2(mojo::ScopedMessagePipeHandle channel_handle) |
1721 : Worker("reentrant_reply2", Channel::MODE_SERVER), | 1813 : Worker(std::move(channel_handle), Channel::MODE_SERVER), reply_(NULL) {} |
1722 reply_(NULL) { } | |
1723 | 1814 |
1724 private: | 1815 private: |
1725 bool OnMessageReceived(const Message& message) override { | 1816 bool OnMessageReceived(const Message& message) override { |
1726 IPC_BEGIN_MESSAGE_MAP(ReentrantReplyServer2, message) | 1817 IPC_BEGIN_MESSAGE_MAP(ReentrantReplyServer2, message) |
1727 IPC_MESSAGE_HANDLER_DELAY_REPLY( | 1818 IPC_MESSAGE_HANDLER_DELAY_REPLY( |
1728 SyncChannelTestMsg_Reentrant1, OnReentrant1) | 1819 SyncChannelTestMsg_Reentrant1, OnReentrant1) |
1729 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Reentrant3, OnReentrant3) | 1820 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Reentrant3, OnReentrant3) |
1730 IPC_END_MESSAGE_MAP() | 1821 IPC_END_MESSAGE_MAP() |
1731 return true; | 1822 return true; |
1732 } | 1823 } |
(...skipping 10 matching lines...) Expand all Loading... |
1743 reply->set_unblock(true); | 1834 reply->set_unblock(true); |
1744 Send(reply); | 1835 Send(reply); |
1745 Done(); | 1836 Done(); |
1746 } | 1837 } |
1747 | 1838 |
1748 Message* reply_; | 1839 Message* reply_; |
1749 }; | 1840 }; |
1750 | 1841 |
1751 class ReentrantReplyClient : public Worker { | 1842 class ReentrantReplyClient : public Worker { |
1752 public: | 1843 public: |
1753 ReentrantReplyClient(WaitableEvent* server_ready) | 1844 ReentrantReplyClient(WaitableEvent* server_ready, |
1754 : Worker("reentrant_reply1", Channel::MODE_CLIENT), | 1845 mojo::ScopedMessagePipeHandle channel_handle) |
1755 server_ready_(server_ready) { } | 1846 : Worker(std::move(channel_handle), Channel::MODE_CLIENT), |
| 1847 server_ready_(server_ready) {} |
1756 | 1848 |
1757 void Run() override { | 1849 void Run() override { |
1758 server_ready_->Wait(); | 1850 server_ready_->Wait(); |
1759 Send(new SyncChannelTestMsg_Reentrant2()); | 1851 Send(new SyncChannelTestMsg_Reentrant2()); |
1760 Done(); | 1852 Done(); |
1761 } | 1853 } |
1762 | 1854 |
1763 private: | 1855 private: |
1764 WaitableEvent* server_ready_; | 1856 WaitableEvent* server_ready_; |
1765 }; | 1857 }; |
1766 | 1858 |
1767 TEST_F(IPCSyncChannelTest, ReentrantReply) { | 1859 TEST_F(IPCSyncChannelTest, ReentrantReply) { |
1768 std::vector<Worker*> workers; | 1860 std::vector<Worker*> workers; |
1769 WaitableEvent server_ready(base::WaitableEvent::ResetPolicy::AUTOMATIC, | 1861 WaitableEvent server_ready(base::WaitableEvent::ResetPolicy::AUTOMATIC, |
1770 base::WaitableEvent::InitialState::NOT_SIGNALED); | 1862 base::WaitableEvent::InitialState::NOT_SIGNALED); |
1771 workers.push_back(new ReentrantReplyServer2()); | 1863 mojo::MessagePipe pipe1, pipe2; |
1772 workers.push_back(new ReentrantReplyServer1(&server_ready)); | 1864 workers.push_back(new ReentrantReplyServer2(std::move(pipe2.handle0))); |
1773 workers.push_back(new ReentrantReplyClient(&server_ready)); | 1865 workers.push_back(new ReentrantReplyServer1( |
| 1866 &server_ready, std::move(pipe1.handle0), std::move(pipe2.handle1))); |
| 1867 workers.push_back( |
| 1868 new ReentrantReplyClient(&server_ready, std::move(pipe1.handle1))); |
1774 RunTest(workers); | 1869 RunTest(workers); |
1775 } | 1870 } |
1776 | 1871 |
1777 //------------------------------------------------------------------------------ | |
1778 | |
1779 // Generate a validated channel ID using Channel::GenerateVerifiedChannelID(). | |
1780 | |
1781 class VerifiedServer : public Worker { | |
1782 public: | |
1783 VerifiedServer(base::Thread* listener_thread, | |
1784 const std::string& channel_name, | |
1785 const std::string& reply_text) | |
1786 : Worker(channel_name, Channel::MODE_SERVER), | |
1787 reply_text_(reply_text) { | |
1788 Worker::OverrideThread(listener_thread); | |
1789 } | |
1790 | |
1791 void OnNestedTestMsg(Message* reply_msg) override { | |
1792 VLOG(1) << __FUNCTION__ << " Sending reply: " << reply_text_; | |
1793 SyncChannelNestedTestMsg_String::WriteReplyParams(reply_msg, reply_text_); | |
1794 Send(reply_msg); | |
1795 ASSERT_EQ(channel()->GetPeerPID(), base::GetCurrentProcId()); | |
1796 Done(); | |
1797 } | |
1798 | |
1799 private: | |
1800 std::string reply_text_; | |
1801 }; | |
1802 | |
1803 class VerifiedClient : public Worker { | |
1804 public: | |
1805 VerifiedClient(base::Thread* listener_thread, | |
1806 const std::string& channel_name, | |
1807 const std::string& expected_text) | |
1808 : Worker(channel_name, Channel::MODE_CLIENT), | |
1809 expected_text_(expected_text) { | |
1810 Worker::OverrideThread(listener_thread); | |
1811 } | |
1812 | |
1813 void OnChannelConnected(int32_t peer_pid) override { | |
1814 ListenerThread()->task_runner()->PostTask( | |
1815 FROM_HERE, base::Bind(&VerifiedClient::RunTestOnConnected, this)); | |
1816 } | |
1817 | |
1818 void RunTestOnConnected() { | |
1819 std::string response; | |
1820 SyncMessage* msg = new SyncChannelNestedTestMsg_String(&response); | |
1821 bool result = Send(msg); | |
1822 DCHECK(result); | |
1823 DCHECK_EQ(response, expected_text_); | |
1824 // expected_text_ is only used in the above DCHECK. This line suppresses the | |
1825 // "unused private field" warning in release builds. | |
1826 (void)expected_text_; | |
1827 | |
1828 VLOG(1) << __FUNCTION__ << " Received reply: " << response; | |
1829 ASSERT_EQ(channel()->GetPeerPID(), base::GetCurrentProcId()); | |
1830 Done(); | |
1831 } | |
1832 | |
1833 private: | |
1834 std::string expected_text_; | |
1835 }; | |
1836 | |
1837 void Verified() { | |
1838 std::vector<Worker*> workers; | |
1839 | |
1840 // A shared worker thread for servers | |
1841 base::Thread server_worker_thread("Verified_ServerListener"); | |
1842 ASSERT_TRUE(server_worker_thread.Start()); | |
1843 | |
1844 base::Thread client_worker_thread("Verified_ClientListener"); | |
1845 ASSERT_TRUE(client_worker_thread.Start()); | |
1846 | |
1847 std::string channel_id = Channel::GenerateVerifiedChannelID("Verified"); | |
1848 Worker* worker; | |
1849 | |
1850 worker = new VerifiedServer(&server_worker_thread, | |
1851 channel_id, | |
1852 "Got first message"); | |
1853 workers.push_back(worker); | |
1854 | |
1855 worker = new VerifiedClient(&client_worker_thread, | |
1856 channel_id, | |
1857 "Got first message"); | |
1858 workers.push_back(worker); | |
1859 | |
1860 RunTest(workers); | |
1861 } | |
1862 | |
1863 // Windows needs to send an out-of-band secret to verify the client end of the | |
1864 // channel. Test that we still connect correctly in that case. | |
1865 TEST_F(IPCSyncChannelTest, Verified) { | |
1866 Verified(); | |
1867 } | |
1868 | |
1869 } // namespace | 1872 } // namespace |
1870 } // namespace IPC | 1873 } // namespace IPC |
OLD | NEW |