message_pump_io_ios_unittest.cc 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. // Copyright 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "base/message_loop/message_pump_io_ios.h"
  5. #include <unistd.h>
  6. #include "base/logging.h"
  7. #include "base/message_loop/message_pump_for_io.h"
  8. #include "base/posix/eintr_wrapper.h"
  9. #include "base/test/gtest_util.h"
  10. #include "base/threading/thread.h"
  11. #include "testing/gtest/include/gtest/gtest.h"
  12. namespace base {
  13. class MessagePumpIOSForIOTest : public testing::Test {
  14. public:
  15. MessagePumpIOSForIOTest(const MessagePumpIOSForIOTest&) = delete;
  16. MessagePumpIOSForIOTest& operator=(const MessagePumpIOSForIOTest&) = delete;
  17. protected:
  18. MessagePumpIOSForIOTest() = default;
  19. ~MessagePumpIOSForIOTest() override = default;
  20. void SetUp() override {
  21. int ret = pipe(pipefds_);
  22. ASSERT_EQ(0, ret);
  23. ret = pipe(alternate_pipefds_);
  24. ASSERT_EQ(0, ret);
  25. }
  26. void TearDown() override {
  27. if (IGNORE_EINTR(close(pipefds_[0])) < 0)
  28. PLOG(ERROR) << "close";
  29. if (IGNORE_EINTR(close(pipefds_[1])) < 0)
  30. PLOG(ERROR) << "close";
  31. }
  32. void HandleFdIOEvent(MessagePumpForIO::FdWatchController* watcher) {
  33. MessagePumpIOSForIO::HandleFdIOEvent(watcher->fdref_.get(),
  34. kCFFileDescriptorReadCallBack | kCFFileDescriptorWriteCallBack,
  35. watcher);
  36. }
  37. int pipefds_[2];
  38. int alternate_pipefds_[2];
  39. };
  40. namespace {
  41. // Concrete implementation of MessagePumpIOSForIO::FdWatcher that does
  42. // nothing useful.
  43. class StupidWatcher : public MessagePumpIOSForIO::FdWatcher {
  44. public:
  45. ~StupidWatcher() override {}
  46. // base:MessagePumpIOSForIO::FdWatcher interface
  47. void OnFileCanReadWithoutBlocking(int fd) override {}
  48. void OnFileCanWriteWithoutBlocking(int fd) override {}
  49. };
  50. class BaseWatcher : public MessagePumpIOSForIO::FdWatcher {
  51. public:
  52. BaseWatcher(MessagePumpIOSForIO::FdWatchController* controller)
  53. : controller_(controller) {
  54. DCHECK(controller_);
  55. }
  56. ~BaseWatcher() override {}
  57. // MessagePumpIOSForIO::FdWatcher interface
  58. void OnFileCanReadWithoutBlocking(int /* fd */) override { NOTREACHED(); }
  59. void OnFileCanWriteWithoutBlocking(int /* fd */) override { NOTREACHED(); }
  60. protected:
  61. MessagePumpIOSForIO::FdWatchController* controller_;
  62. };
  63. class DeleteWatcher : public BaseWatcher {
  64. public:
  65. explicit DeleteWatcher(MessagePumpIOSForIO::FdWatchController* controller)
  66. : BaseWatcher(controller) {}
  67. ~DeleteWatcher() override { DCHECK(!controller_); }
  68. void OnFileCanWriteWithoutBlocking(int /* fd */) override {
  69. DCHECK(controller_);
  70. delete controller_;
  71. controller_ = NULL;
  72. }
  73. };
  74. TEST_F(MessagePumpIOSForIOTest, DeleteWatcher) {
  75. std::unique_ptr<MessagePumpIOSForIO> pump(new MessagePumpIOSForIO);
  76. MessagePumpIOSForIO::FdWatchController* watcher =
  77. new MessagePumpIOSForIO::FdWatchController(FROM_HERE);
  78. DeleteWatcher delegate(watcher);
  79. pump->WatchFileDescriptor(pipefds_[1],
  80. false, MessagePumpIOSForIO::WATCH_READ_WRITE, watcher, &delegate);
  81. // Spoof a callback.
  82. HandleFdIOEvent(watcher);
  83. }
  84. class StopWatcher : public BaseWatcher {
  85. public:
  86. StopWatcher(MessagePumpIOSForIO::FdWatchController* controller,
  87. MessagePumpIOSForIO* pump,
  88. int fd_to_start_watching = -1)
  89. : BaseWatcher(controller),
  90. pump_(pump),
  91. fd_to_start_watching_(fd_to_start_watching) {}
  92. ~StopWatcher() override {}
  93. void OnFileCanWriteWithoutBlocking(int /* fd */) override {
  94. controller_->StopWatchingFileDescriptor();
  95. if (fd_to_start_watching_ >= 0) {
  96. pump_->WatchFileDescriptor(fd_to_start_watching_,
  97. false, MessagePumpIOSForIO::WATCH_READ_WRITE, controller_, this);
  98. }
  99. }
  100. private:
  101. MessagePumpIOSForIO* pump_;
  102. int fd_to_start_watching_;
  103. };
  104. TEST_F(MessagePumpIOSForIOTest, StopWatcher) {
  105. std::unique_ptr<MessagePumpIOSForIO> pump(new MessagePumpIOSForIO);
  106. MessagePumpIOSForIO::FdWatchController watcher(FROM_HERE);
  107. StopWatcher delegate(&watcher, pump.get());
  108. pump->WatchFileDescriptor(pipefds_[1],
  109. false, MessagePumpIOSForIO::WATCH_READ_WRITE, &watcher, &delegate);
  110. // Spoof a callback.
  111. HandleFdIOEvent(&watcher);
  112. }
  113. TEST_F(MessagePumpIOSForIOTest, StopWatcherAndWatchSomethingElse) {
  114. std::unique_ptr<MessagePumpIOSForIO> pump(new MessagePumpIOSForIO);
  115. MessagePumpIOSForIO::FdWatchController watcher(FROM_HERE);
  116. StopWatcher delegate(&watcher, pump.get(), alternate_pipefds_[1]);
  117. pump->WatchFileDescriptor(pipefds_[1],
  118. false, MessagePumpIOSForIO::WATCH_READ_WRITE, &watcher, &delegate);
  119. // Spoof a callback.
  120. HandleFdIOEvent(&watcher);
  121. }
  122. } // namespace
  123. } // namespace base