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