| 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> |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 namespace IPC { | 35 namespace IPC { |
| 36 namespace { | 36 namespace { |
| 37 | 37 |
| 38 // Base class for a "process" with listener and IPC threads. | 38 // Base class for a "process" with listener and IPC threads. |
| 39 class Worker : public Listener, public Sender { | 39 class Worker : public Listener, public Sender { |
| 40 public: | 40 public: |
| 41 // Will create a channel without a name. | 41 // Will create a channel without a name. |
| 42 Worker(Channel::Mode mode, | 42 Worker(Channel::Mode mode, |
| 43 const std::string& thread_name, | 43 const std::string& thread_name, |
| 44 const std::string& channel_name) | 44 const std::string& channel_name) |
| 45 : done_(new WaitableEvent(false, false)), | 45 : done_( |
| 46 channel_created_(new WaitableEvent(false, false)), | 46 new WaitableEvent(base::WaitableEvent::ResetPolicy::AUTOMATIC, |
| 47 base::WaitableEvent::InitialState::NOT_SIGNALED)), |
| 48 channel_created_( |
| 49 new WaitableEvent(base::WaitableEvent::ResetPolicy::AUTOMATIC, |
| 50 base::WaitableEvent::InitialState::NOT_SIGNALED)), |
| 47 channel_name_(channel_name), | 51 channel_name_(channel_name), |
| 48 mode_(mode), | 52 mode_(mode), |
| 49 ipc_thread_((thread_name + "_ipc").c_str()), | 53 ipc_thread_((thread_name + "_ipc").c_str()), |
| 50 listener_thread_((thread_name + "_listener").c_str()), | 54 listener_thread_((thread_name + "_listener").c_str()), |
| 51 overrided_thread_(NULL), | 55 overrided_thread_(NULL), |
| 52 shutdown_event_(true, false), | 56 shutdown_event_(base::WaitableEvent::ResetPolicy::MANUAL, |
| 57 base::WaitableEvent::InitialState::NOT_SIGNALED), |
| 53 is_shutdown_(false) {} | 58 is_shutdown_(false) {} |
| 54 | 59 |
| 55 // 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. |
| 56 Worker(const std::string& channel_name, Channel::Mode mode) | 61 Worker(const std::string& channel_name, Channel::Mode mode) |
| 57 : done_(new WaitableEvent(false, false)), | 62 : done_( |
| 58 channel_created_(new WaitableEvent(false, false)), | 63 new WaitableEvent(base::WaitableEvent::ResetPolicy::AUTOMATIC, |
| 64 base::WaitableEvent::InitialState::NOT_SIGNALED)), |
| 65 channel_created_( |
| 66 new WaitableEvent(base::WaitableEvent::ResetPolicy::AUTOMATIC, |
| 67 base::WaitableEvent::InitialState::NOT_SIGNALED)), |
| 59 channel_name_(channel_name), | 68 channel_name_(channel_name), |
| 60 mode_(mode), | 69 mode_(mode), |
| 61 ipc_thread_((channel_name + "_ipc").c_str()), | 70 ipc_thread_((channel_name + "_ipc").c_str()), |
| 62 listener_thread_((channel_name + "_listener").c_str()), | 71 listener_thread_((channel_name + "_listener").c_str()), |
| 63 overrided_thread_(NULL), | 72 overrided_thread_(NULL), |
| 64 shutdown_event_(true, false), | 73 shutdown_event_(base::WaitableEvent::ResetPolicy::MANUAL, |
| 65 is_shutdown_(false) { | 74 base::WaitableEvent::InitialState::NOT_SIGNALED), |
| 66 } | 75 is_shutdown_(false) {} |
| 67 | 76 |
| 68 ~Worker() override { | 77 ~Worker() override { |
| 69 // Shutdown() must be called before destruction. | 78 // Shutdown() must be called before destruction. |
| 70 CHECK(is_shutdown_); | 79 CHECK(is_shutdown_); |
| 71 } | 80 } |
| 72 void AddRef() { } | 81 void AddRef() { } |
| 73 void Release() { } | 82 void Release() { } |
| 74 bool Send(Message* msg) override { return channel_->Send(msg); } | 83 bool Send(Message* msg) override { return channel_->Send(msg); } |
| 75 void WaitForChannelCreation() { channel_created_->Wait(); } | 84 void WaitForChannelCreation() { channel_created_->Wait(); } |
| 76 void CloseChannel() { | 85 void CloseChannel() { |
| 77 DCHECK(base::MessageLoop::current() == ListenerThread()->message_loop()); | 86 DCHECK(base::MessageLoop::current() == ListenerThread()->message_loop()); |
| 78 channel_->Close(); | 87 channel_->Close(); |
| 79 } | 88 } |
| 80 void Start() { | 89 void Start() { |
| 81 StartThread(&listener_thread_, base::MessageLoop::TYPE_DEFAULT); | 90 StartThread(&listener_thread_, base::MessageLoop::TYPE_DEFAULT); |
| 82 ListenerThread()->task_runner()->PostTask( | 91 ListenerThread()->task_runner()->PostTask( |
| 83 FROM_HERE, base::Bind(&Worker::OnStart, this)); | 92 FROM_HERE, base::Bind(&Worker::OnStart, this)); |
| 84 } | 93 } |
| 85 void Shutdown() { | 94 void Shutdown() { |
| 86 // The IPC thread needs to outlive SyncChannel. We can't do this in | 95 // The IPC thread needs to outlive SyncChannel. We can't do this in |
| 87 // ~Worker(), since that'll reset the vtable pointer (to Worker's), which | 96 // ~Worker(), since that'll reset the vtable pointer (to Worker's), which |
| 88 // may result in a race conditions. See http://crbug.com/25841. | 97 // may result in a race conditions. See http://crbug.com/25841. |
| 89 WaitableEvent listener_done(false, false), ipc_done(false, false); | 98 WaitableEvent listener_done( |
| 99 base::WaitableEvent::ResetPolicy::AUTOMATIC, |
| 100 base::WaitableEvent::InitialState::NOT_SIGNALED), |
| 101 ipc_done(base::WaitableEvent::ResetPolicy::AUTOMATIC, |
| 102 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 90 ListenerThread()->task_runner()->PostTask( | 103 ListenerThread()->task_runner()->PostTask( |
| 91 FROM_HERE, base::Bind(&Worker::OnListenerThreadShutdown1, this, | 104 FROM_HERE, base::Bind(&Worker::OnListenerThreadShutdown1, this, |
| 92 &listener_done, &ipc_done)); | 105 &listener_done, &ipc_done)); |
| 93 listener_done.Wait(); | 106 listener_done.Wait(); |
| 94 ipc_done.Wait(); | 107 ipc_done.Wait(); |
| 95 ipc_thread_.Stop(); | 108 ipc_thread_.Stop(); |
| 96 listener_thread_.Stop(); | 109 listener_thread_.Stop(); |
| 97 is_shutdown_ = true; | 110 is_shutdown_ = true; |
| 98 } | 111 } |
| 99 void OverrideThread(base::Thread* overrided_thread) { | 112 void OverrideThread(base::Thread* overrided_thread) { |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 447 Send(reply_msg); | 460 Send(reply_msg); |
| 448 got_first_reply_->Wait(); | 461 got_first_reply_->Wait(); |
| 449 CloseChannel(); | 462 CloseChannel(); |
| 450 Done(); | 463 Done(); |
| 451 } | 464 } |
| 452 | 465 |
| 453 WaitableEvent* got_first_reply_; | 466 WaitableEvent* got_first_reply_; |
| 454 }; | 467 }; |
| 455 | 468 |
| 456 void NoHang(bool pump_during_send) { | 469 void NoHang(bool pump_during_send) { |
| 457 WaitableEvent got_first_reply(false, false); | 470 WaitableEvent got_first_reply( |
| 471 base::WaitableEvent::ResetPolicy::AUTOMATIC, |
| 472 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 458 std::vector<Worker*> workers; | 473 std::vector<Worker*> workers; |
| 459 workers.push_back( | 474 workers.push_back( |
| 460 new NoHangServer(&got_first_reply, pump_during_send, "NoHang")); | 475 new NoHangServer(&got_first_reply, pump_during_send, "NoHang")); |
| 461 workers.push_back(new NoHangClient(&got_first_reply, "NoHang")); | 476 workers.push_back(new NoHangClient(&got_first_reply, "NoHang")); |
| 462 RunTest(workers); | 477 RunTest(workers); |
| 463 } | 478 } |
| 464 | 479 |
| 465 // Tests that caller doesn't hang if receiver dies | 480 // Tests that caller doesn't hang if receiver dies |
| 466 TEST_F(IPCSyncChannelTest, NoHang) { | 481 TEST_F(IPCSyncChannelTest, NoHang) { |
| 467 NoHang(false); | 482 NoHang(false); |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 723 void Multiple(bool server_pump, bool client_pump) { | 738 void Multiple(bool server_pump, bool client_pump) { |
| 724 std::vector<Worker*> workers; | 739 std::vector<Worker*> workers; |
| 725 | 740 |
| 726 // A shared worker thread so that server1 and server2 run on one thread. | 741 // A shared worker thread so that server1 and server2 run on one thread. |
| 727 base::Thread worker_thread("Multiple"); | 742 base::Thread worker_thread("Multiple"); |
| 728 ASSERT_TRUE(worker_thread.Start()); | 743 ASSERT_TRUE(worker_thread.Start()); |
| 729 | 744 |
| 730 // Server1 sends a sync msg to client1, which blocks the reply until | 745 // Server1 sends a sync msg to client1, which blocks the reply until |
| 731 // server2 (which runs on the same worker thread as server1) responds | 746 // server2 (which runs on the same worker thread as server1) responds |
| 732 // to a sync msg from client2. | 747 // to a sync msg from client2. |
| 733 WaitableEvent client1_msg_received(false, false); | 748 WaitableEvent client1_msg_received( |
| 734 WaitableEvent client1_can_reply(false, false); | 749 base::WaitableEvent::ResetPolicy::AUTOMATIC, |
| 750 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 751 WaitableEvent client1_can_reply( |
| 752 base::WaitableEvent::ResetPolicy::AUTOMATIC, |
| 753 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 735 | 754 |
| 736 Worker* worker; | 755 Worker* worker; |
| 737 | 756 |
| 738 worker = new MultipleServer2(); | 757 worker = new MultipleServer2(); |
| 739 worker->OverrideThread(&worker_thread); | 758 worker->OverrideThread(&worker_thread); |
| 740 workers.push_back(worker); | 759 workers.push_back(worker); |
| 741 | 760 |
| 742 worker = new MultipleClient2( | 761 worker = new MultipleClient2( |
| 743 &client1_msg_received, &client1_can_reply, client_pump); | 762 &client1_msg_received, &client1_can_reply, client_pump); |
| 744 workers.push_back(worker); | 763 workers.push_back(worker); |
| (...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1248 | 1267 |
| 1249 int ping_; | 1268 int ping_; |
| 1250 RestrictedDispatchServer* server_; | 1269 RestrictedDispatchServer* server_; |
| 1251 NonRestrictedDispatchServer* server2_; | 1270 NonRestrictedDispatchServer* server2_; |
| 1252 int* success_; | 1271 int* success_; |
| 1253 WaitableEvent* sent_ping_event_; | 1272 WaitableEvent* sent_ping_event_; |
| 1254 std::unique_ptr<SyncChannel> non_restricted_channel_; | 1273 std::unique_ptr<SyncChannel> non_restricted_channel_; |
| 1255 }; | 1274 }; |
| 1256 | 1275 |
| 1257 TEST_F(IPCSyncChannelTest, RestrictedDispatch) { | 1276 TEST_F(IPCSyncChannelTest, RestrictedDispatch) { |
| 1258 WaitableEvent sent_ping_event(false, false); | 1277 WaitableEvent sent_ping_event( |
| 1259 WaitableEvent wait_event(false, false); | 1278 base::WaitableEvent::ResetPolicy::AUTOMATIC, |
| 1279 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 1280 WaitableEvent wait_event(base::WaitableEvent::ResetPolicy::AUTOMATIC, |
| 1281 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 1260 RestrictedDispatchServer* server = | 1282 RestrictedDispatchServer* server = |
| 1261 new RestrictedDispatchServer(&sent_ping_event, &wait_event); | 1283 new RestrictedDispatchServer(&sent_ping_event, &wait_event); |
| 1262 NonRestrictedDispatchServer* server2 = | 1284 NonRestrictedDispatchServer* server2 = |
| 1263 new NonRestrictedDispatchServer(&wait_event); | 1285 new NonRestrictedDispatchServer(&wait_event); |
| 1264 | 1286 |
| 1265 int success = 0; | 1287 int success = 0; |
| 1266 std::vector<Worker*> workers; | 1288 std::vector<Worker*> workers; |
| 1267 workers.push_back(server); | 1289 workers.push_back(server); |
| 1268 workers.push_back(server2); | 1290 workers.push_back(server2); |
| 1269 workers.push_back(new RestrictedDispatchClient( | 1291 workers.push_back(new RestrictedDispatchClient( |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1479 bool done_issued_; | 1501 bool done_issued_; |
| 1480 }; | 1502 }; |
| 1481 | 1503 |
| 1482 TEST_F(IPCSyncChannelTest, RestrictedDispatchDeadlock) { | 1504 TEST_F(IPCSyncChannelTest, RestrictedDispatchDeadlock) { |
| 1483 std::vector<Worker*> workers; | 1505 std::vector<Worker*> workers; |
| 1484 | 1506 |
| 1485 // A shared worker thread so that server1 and server2 run on one thread. | 1507 // A shared worker thread so that server1 and server2 run on one thread. |
| 1486 base::Thread worker_thread("RestrictedDispatchDeadlock"); | 1508 base::Thread worker_thread("RestrictedDispatchDeadlock"); |
| 1487 ASSERT_TRUE(worker_thread.Start()); | 1509 ASSERT_TRUE(worker_thread.Start()); |
| 1488 | 1510 |
| 1489 WaitableEvent server1_ready(false, false); | 1511 WaitableEvent server1_ready(base::WaitableEvent::ResetPolicy::AUTOMATIC, |
| 1490 WaitableEvent server2_ready(false, false); | 1512 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 1513 WaitableEvent server2_ready(base::WaitableEvent::ResetPolicy::AUTOMATIC, |
| 1514 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 1491 | 1515 |
| 1492 WaitableEvent event0(false, false); | 1516 WaitableEvent event0(base::WaitableEvent::ResetPolicy::AUTOMATIC, |
| 1493 WaitableEvent event1(false, false); | 1517 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 1494 WaitableEvent event2(false, false); | 1518 WaitableEvent event1(base::WaitableEvent::ResetPolicy::AUTOMATIC, |
| 1495 WaitableEvent event3(false, false); | 1519 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 1520 WaitableEvent event2(base::WaitableEvent::ResetPolicy::AUTOMATIC, |
| 1521 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 1522 WaitableEvent event3(base::WaitableEvent::ResetPolicy::AUTOMATIC, |
| 1523 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 1496 WaitableEvent* events[4] = {&event0, &event1, &event2, &event3}; | 1524 WaitableEvent* events[4] = {&event0, &event1, &event2, &event3}; |
| 1497 | 1525 |
| 1498 RestrictedDispatchDeadlockServer* server1; | 1526 RestrictedDispatchDeadlockServer* server1; |
| 1499 RestrictedDispatchDeadlockServer* server2; | 1527 RestrictedDispatchDeadlockServer* server2; |
| 1500 RestrictedDispatchDeadlockClient1* client1; | 1528 RestrictedDispatchDeadlockClient1* client1; |
| 1501 RestrictedDispatchDeadlockClient2* client2; | 1529 RestrictedDispatchDeadlockClient2* client2; |
| 1502 | 1530 |
| 1503 server2 = new RestrictedDispatchDeadlockServer(2, &server2_ready, events, | 1531 server2 = new RestrictedDispatchDeadlockServer(2, &server2_ready, events, |
| 1504 NULL); | 1532 NULL); |
| 1505 server2->OverrideThread(&worker_thread); | 1533 server2->OverrideThread(&worker_thread); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1609 | 1637 |
| 1610 #if defined(OS_ANDROID) | 1638 #if defined(OS_ANDROID) |
| 1611 #define MAYBE_RestrictedDispatch4WayDeadlock \ | 1639 #define MAYBE_RestrictedDispatch4WayDeadlock \ |
| 1612 DISABLED_RestrictedDispatch4WayDeadlock | 1640 DISABLED_RestrictedDispatch4WayDeadlock |
| 1613 #else | 1641 #else |
| 1614 #define MAYBE_RestrictedDispatch4WayDeadlock RestrictedDispatch4WayDeadlock | 1642 #define MAYBE_RestrictedDispatch4WayDeadlock RestrictedDispatch4WayDeadlock |
| 1615 #endif | 1643 #endif |
| 1616 TEST_F(IPCSyncChannelTest, MAYBE_RestrictedDispatch4WayDeadlock) { | 1644 TEST_F(IPCSyncChannelTest, MAYBE_RestrictedDispatch4WayDeadlock) { |
| 1617 int success = 0; | 1645 int success = 0; |
| 1618 std::vector<Worker*> workers; | 1646 std::vector<Worker*> workers; |
| 1619 WaitableEvent event0(true, false); | 1647 WaitableEvent event0(base::WaitableEvent::ResetPolicy::MANUAL, |
| 1620 WaitableEvent event1(true, false); | 1648 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 1621 WaitableEvent event2(true, false); | 1649 WaitableEvent event1(base::WaitableEvent::ResetPolicy::MANUAL, |
| 1622 WaitableEvent event3(true, false); | 1650 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 1651 WaitableEvent event2(base::WaitableEvent::ResetPolicy::MANUAL, |
| 1652 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 1653 WaitableEvent event3(base::WaitableEvent::ResetPolicy::MANUAL, |
| 1654 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 1623 workers.push_back(new RestrictedDispatchPipeWorker( | 1655 workers.push_back(new RestrictedDispatchPipeWorker( |
| 1624 "channel0", &event0, "channel1", &event1, 1, &success)); | 1656 "channel0", &event0, "channel1", &event1, 1, &success)); |
| 1625 workers.push_back(new RestrictedDispatchPipeWorker( | 1657 workers.push_back(new RestrictedDispatchPipeWorker( |
| 1626 "channel1", &event1, "channel2", &event2, 2, NULL)); | 1658 "channel1", &event1, "channel2", &event2, 2, NULL)); |
| 1627 workers.push_back(new RestrictedDispatchPipeWorker( | 1659 workers.push_back(new RestrictedDispatchPipeWorker( |
| 1628 "channel2", &event2, "channel3", &event3, 3, NULL)); | 1660 "channel2", &event2, "channel3", &event3, 3, NULL)); |
| 1629 workers.push_back(new RestrictedDispatchPipeWorker( | 1661 workers.push_back(new RestrictedDispatchPipeWorker( |
| 1630 "channel3", &event3, "channel0", &event0, 4, NULL)); | 1662 "channel3", &event3, "channel0", &event0, 4, NULL)); |
| 1631 RunTest(workers); | 1663 RunTest(workers); |
| 1632 EXPECT_EQ(3, success); | 1664 EXPECT_EQ(3, success); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1727 Send(new SyncChannelTestMsg_Reentrant2()); | 1759 Send(new SyncChannelTestMsg_Reentrant2()); |
| 1728 Done(); | 1760 Done(); |
| 1729 } | 1761 } |
| 1730 | 1762 |
| 1731 private: | 1763 private: |
| 1732 WaitableEvent* server_ready_; | 1764 WaitableEvent* server_ready_; |
| 1733 }; | 1765 }; |
| 1734 | 1766 |
| 1735 TEST_F(IPCSyncChannelTest, ReentrantReply) { | 1767 TEST_F(IPCSyncChannelTest, ReentrantReply) { |
| 1736 std::vector<Worker*> workers; | 1768 std::vector<Worker*> workers; |
| 1737 WaitableEvent server_ready(false, false); | 1769 WaitableEvent server_ready(base::WaitableEvent::ResetPolicy::AUTOMATIC, |
| 1770 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 1738 workers.push_back(new ReentrantReplyServer2()); | 1771 workers.push_back(new ReentrantReplyServer2()); |
| 1739 workers.push_back(new ReentrantReplyServer1(&server_ready)); | 1772 workers.push_back(new ReentrantReplyServer1(&server_ready)); |
| 1740 workers.push_back(new ReentrantReplyClient(&server_ready)); | 1773 workers.push_back(new ReentrantReplyClient(&server_ready)); |
| 1741 RunTest(workers); | 1774 RunTest(workers); |
| 1742 } | 1775 } |
| 1743 | 1776 |
| 1744 //------------------------------------------------------------------------------ | 1777 //------------------------------------------------------------------------------ |
| 1745 | 1778 |
| 1746 // Generate a validated channel ID using Channel::GenerateVerifiedChannelID(). | 1779 // Generate a validated channel ID using Channel::GenerateVerifiedChannelID(). |
| 1747 | 1780 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1823 } | 1856 } |
| 1824 | 1857 |
| 1825 // Windows needs to send an out-of-band secret to verify the client end of the | 1858 // Windows needs to send an out-of-band secret to verify the client end of the |
| 1826 // channel. Test that we still connect correctly in that case. | 1859 // channel. Test that we still connect correctly in that case. |
| 1827 TEST_F(IPCSyncChannelTest, Verified) { | 1860 TEST_F(IPCSyncChannelTest, Verified) { |
| 1828 Verified(); | 1861 Verified(); |
| 1829 } | 1862 } |
| 1830 | 1863 |
| 1831 } // namespace | 1864 } // namespace |
| 1832 } // namespace IPC | 1865 } // namespace IPC |
| OLD | NEW |