fd_watch_controller_posix_unittest.cc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  1. // Copyright 2017 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 <sys/socket.h>
  5. #include "base/bind.h"
  6. #include "base/compiler_specific.h"
  7. #include "base/files/file_util.h"
  8. #include "base/files/scoped_file.h"
  9. #include "base/logging.h"
  10. #include "base/memory/ptr_util.h"
  11. #include "base/message_loop/message_pump_for_io.h"
  12. #include "base/posix/eintr_wrapper.h"
  13. #include "base/run_loop.h"
  14. #include "base/task/current_thread.h"
  15. #include "base/test/gtest_util.h"
  16. #include "base/test/task_environment.h"
  17. #include "build/build_config.h"
  18. #include "testing/gtest/include/gtest/gtest.h"
  19. namespace base {
  20. #if !BUILDFLAG(IS_NACL)
  21. namespace {
  22. class FdWatchControllerPosixTest : public testing::Test {
  23. public:
  24. FdWatchControllerPosixTest() = default;
  25. FdWatchControllerPosixTest(const FdWatchControllerPosixTest&) = delete;
  26. FdWatchControllerPosixTest& operator=(const FdWatchControllerPosixTest&) =
  27. delete;
  28. // testing::Test interface.
  29. void SetUp() override {
  30. // Create a file descriptor. Doesn't need to be readable or writable,
  31. // as we don't need to actually get any notifications.
  32. // pipe() is just the easiest way to do it.
  33. int pipefds[2];
  34. int err = pipe(pipefds);
  35. ASSERT_EQ(0, err);
  36. read_fd_ = ScopedFD(pipefds[0]);
  37. write_fd_ = ScopedFD(pipefds[1]);
  38. }
  39. void TriggerReadEvent() {
  40. // Write from the other end of the pipe to trigger the event.
  41. char c = '\0';
  42. EXPECT_EQ(1, HANDLE_EINTR(write(write_fd_.get(), &c, 1)));
  43. }
  44. protected:
  45. ScopedFD read_fd_;
  46. ScopedFD write_fd_;
  47. };
  48. class TestHandler : public MessagePumpForIO::FdWatcher {
  49. public:
  50. void OnFileCanReadWithoutBlocking(int fd) override {
  51. watcher_to_delete_ = nullptr;
  52. is_readable_ = true;
  53. RunLoop::QuitCurrentWhenIdleDeprecated();
  54. }
  55. void OnFileCanWriteWithoutBlocking(int fd) override {
  56. watcher_to_delete_ = nullptr;
  57. is_writable_ = true;
  58. RunLoop::QuitCurrentWhenIdleDeprecated();
  59. }
  60. bool is_readable_ = false;
  61. bool is_writable_ = false;
  62. // If set then the contained watcher will be deleted on notification.
  63. std::unique_ptr<MessagePumpForIO::FdWatchController> watcher_to_delete_;
  64. };
  65. // Watcher that calls specified closures when read/write events occur. Verifies
  66. // that each non-null closure passed to this class is called once and only once.
  67. // Also resets the read event by reading from the FD.
  68. class CallClosureHandler : public MessagePumpForIO::FdWatcher {
  69. public:
  70. CallClosureHandler(OnceClosure read_closure, OnceClosure write_closure)
  71. : read_closure_(std::move(read_closure)),
  72. write_closure_(std::move(write_closure)) {}
  73. ~CallClosureHandler() override {
  74. EXPECT_TRUE(read_closure_.is_null());
  75. EXPECT_TRUE(write_closure_.is_null());
  76. }
  77. void SetReadClosure(OnceClosure read_closure) {
  78. EXPECT_TRUE(read_closure_.is_null());
  79. read_closure_ = std::move(read_closure);
  80. }
  81. void SetWriteClosure(OnceClosure write_closure) {
  82. EXPECT_TRUE(write_closure_.is_null());
  83. write_closure_ = std::move(write_closure);
  84. }
  85. // base::WatchableIOMessagePumpPosix::FdWatcher:
  86. void OnFileCanReadWithoutBlocking(int fd) override {
  87. // Empty the pipe buffer to reset the event. Otherwise libevent
  88. // implementation of MessageLoop may call the event handler again even if
  89. // |read_closure_| below quits the RunLoop.
  90. char c;
  91. int result = HANDLE_EINTR(read(fd, &c, 1));
  92. if (result == -1) {
  93. PLOG(ERROR) << "read";
  94. FAIL();
  95. }
  96. EXPECT_EQ(result, 1);
  97. ASSERT_FALSE(read_closure_.is_null());
  98. std::move(read_closure_).Run();
  99. }
  100. void OnFileCanWriteWithoutBlocking(int fd) override {
  101. ASSERT_FALSE(write_closure_.is_null());
  102. std::move(write_closure_).Run();
  103. }
  104. private:
  105. OnceClosure read_closure_;
  106. OnceClosure write_closure_;
  107. };
  108. TEST_F(FdWatchControllerPosixTest, FileDescriptorWatcherOutlivesMessageLoop) {
  109. // Simulate a MessageLoop that dies before an FileDescriptorWatcher.
  110. // This could happen when people use the Singleton pattern or atexit.
  111. // Arrange for watcher to live longer than message loop.
  112. MessagePumpForIO::FdWatchController watcher(FROM_HERE);
  113. TestHandler handler;
  114. {
  115. test::TaskEnvironment env(test::TaskEnvironment::MainThreadType::IO);
  116. CurrentIOThread::Get()->WatchFileDescriptor(write_fd_.get(), true,
  117. MessagePumpForIO::WATCH_WRITE,
  118. &watcher, &handler);
  119. // Don't run the message loop, just destroy it.
  120. }
  121. ASSERT_FALSE(handler.is_readable_);
  122. ASSERT_FALSE(handler.is_writable_);
  123. }
  124. TEST_F(FdWatchControllerPosixTest, FileDescriptorWatcherDoubleStop) {
  125. // Verify that it's ok to call StopWatchingFileDescriptor().
  126. // Arrange for message loop to live longer than watcher.
  127. test::TaskEnvironment env(test::TaskEnvironment::MainThreadType::IO);
  128. {
  129. MessagePumpForIO::FdWatchController watcher(FROM_HERE);
  130. TestHandler handler;
  131. CurrentIOThread::Get()->WatchFileDescriptor(write_fd_.get(), true,
  132. MessagePumpForIO::WATCH_WRITE,
  133. &watcher, &handler);
  134. ASSERT_TRUE(watcher.StopWatchingFileDescriptor());
  135. ASSERT_TRUE(watcher.StopWatchingFileDescriptor());
  136. }
  137. }
  138. TEST_F(FdWatchControllerPosixTest, FileDescriptorWatcherDeleteInCallback) {
  139. // Verify that it is OK to delete the FileDescriptorWatcher from within a
  140. // callback.
  141. test::TaskEnvironment env(test::TaskEnvironment::MainThreadType::IO);
  142. TestHandler handler;
  143. handler.watcher_to_delete_ =
  144. std::make_unique<MessagePumpForIO::FdWatchController>(FROM_HERE);
  145. CurrentIOThread::Get()->WatchFileDescriptor(
  146. write_fd_.get(), true, MessagePumpForIO::WATCH_WRITE,
  147. handler.watcher_to_delete_.get(), &handler);
  148. RunLoop().Run();
  149. }
  150. // A watcher that owns its controller and will either delete itself or stop
  151. // watching the FD after observing the specified event type.
  152. class ReaderWriterHandler : public MessagePumpForIO::FdWatcher {
  153. public:
  154. enum Action {
  155. // Just call StopWatchingFileDescriptor().
  156. kStopWatching,
  157. // Delete |this| and its owned controller.
  158. kDelete,
  159. };
  160. enum ActWhen {
  161. // Take the Action after observing a read event.
  162. kOnReadEvent,
  163. // Take the Action after observing a write event.
  164. kOnWriteEvent,
  165. };
  166. ReaderWriterHandler(Action action,
  167. ActWhen when,
  168. OnceClosure idle_quit_closure)
  169. : action_(action),
  170. when_(when),
  171. controller_(FROM_HERE),
  172. idle_quit_closure_(std::move(idle_quit_closure)) {}
  173. ReaderWriterHandler(const ReaderWriterHandler&) = delete;
  174. ReaderWriterHandler& operator=(const ReaderWriterHandler&) = delete;
  175. // base::WatchableIOMessagePumpPosix::FdWatcher:
  176. void OnFileCanReadWithoutBlocking(int fd) override {
  177. if (when_ == kOnReadEvent) {
  178. DoAction();
  179. } else {
  180. char c;
  181. EXPECT_EQ(1, HANDLE_EINTR(read(fd, &c, 1)));
  182. }
  183. }
  184. void OnFileCanWriteWithoutBlocking(int fd) override {
  185. if (when_ == kOnWriteEvent) {
  186. DoAction();
  187. } else {
  188. char c = '\0';
  189. EXPECT_EQ(1, HANDLE_EINTR(write(fd, &c, 1)));
  190. }
  191. }
  192. MessagePumpForIO::FdWatchController* controller() { return &controller_; }
  193. private:
  194. void DoAction() {
  195. OnceClosure idle_quit_closure = std::move(idle_quit_closure_);
  196. if (action_ == kDelete) {
  197. delete this;
  198. } else if (action_ == kStopWatching) {
  199. controller_.StopWatchingFileDescriptor();
  200. }
  201. std::move(idle_quit_closure).Run();
  202. }
  203. Action action_;
  204. ActWhen when_;
  205. MessagePumpForIO::FdWatchController controller_;
  206. OnceClosure idle_quit_closure_;
  207. };
  208. class MessageLoopForIoPosixReadAndWriteTest
  209. : public testing::TestWithParam<ReaderWriterHandler::Action> {
  210. protected:
  211. bool CreateSocketPair(ScopedFD* one, ScopedFD* two) {
  212. int fds[2];
  213. if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == -1)
  214. return false;
  215. one->reset(fds[0]);
  216. two->reset(fds[1]);
  217. return true;
  218. }
  219. };
  220. INSTANTIATE_TEST_SUITE_P(StopWatchingOrDelete,
  221. MessageLoopForIoPosixReadAndWriteTest,
  222. testing::Values(ReaderWriterHandler::kStopWatching,
  223. ReaderWriterHandler::kDelete));
  224. // Test deleting or stopping watch after a read event for a watcher that is
  225. // registered for both read and write.
  226. TEST_P(MessageLoopForIoPosixReadAndWriteTest, AfterRead) {
  227. test::TaskEnvironment env(test::TaskEnvironment::MainThreadType::IO);
  228. ScopedFD one, two;
  229. ASSERT_TRUE(CreateSocketPair(&one, &two));
  230. RunLoop run_loop;
  231. ReaderWriterHandler* handler =
  232. new ReaderWriterHandler(GetParam(), ReaderWriterHandler::kOnReadEvent,
  233. run_loop.QuitWhenIdleClosure());
  234. // Trigger a read event on |one| by writing to |two|.
  235. char c = '\0';
  236. EXPECT_EQ(1, HANDLE_EINTR(write(two.get(), &c, 1)));
  237. // The triggered read will cause the watcher action to run. |one| would
  238. // also be immediately available for writing, so this should not cause a
  239. // use-after-free on the |handler|.
  240. CurrentIOThread::Get()->WatchFileDescriptor(
  241. one.get(), true, MessagePumpForIO::WATCH_READ_WRITE,
  242. handler->controller(), handler);
  243. run_loop.Run();
  244. if (GetParam() == ReaderWriterHandler::kStopWatching) {
  245. delete handler;
  246. }
  247. }
  248. // Test deleting or stopping watch after a write event for a watcher that is
  249. // registered for both read and write.
  250. TEST_P(MessageLoopForIoPosixReadAndWriteTest, AfterWrite) {
  251. test::TaskEnvironment env(test::TaskEnvironment::MainThreadType::IO);
  252. ScopedFD one, two;
  253. ASSERT_TRUE(CreateSocketPair(&one, &two));
  254. RunLoop run_loop;
  255. ReaderWriterHandler* handler =
  256. new ReaderWriterHandler(GetParam(), ReaderWriterHandler::kOnWriteEvent,
  257. run_loop.QuitWhenIdleClosure());
  258. // Trigger two read events on |one| by writing to |two|. Because each read
  259. // event only reads one char, |one| will be available for reading again after
  260. // the first read event is handled.
  261. char c = '\0';
  262. EXPECT_EQ(1, HANDLE_EINTR(write(two.get(), &c, 1)));
  263. EXPECT_EQ(1, HANDLE_EINTR(write(two.get(), &c, 1)));
  264. // The triggered read and the immediate availability of |one| for writing
  265. // should cause both the read and write watchers to be triggered. The
  266. // |handler| will do its action in response to the write event, which should
  267. // not trigger a use-after-free for the second read that was queued.
  268. CurrentIOThread::Get()->WatchFileDescriptor(
  269. one.get(), true, MessagePumpForIO::WATCH_READ_WRITE,
  270. handler->controller(), handler);
  271. run_loop.Run();
  272. if (GetParam() == ReaderWriterHandler::kStopWatching) {
  273. delete handler;
  274. }
  275. }
  276. // Verify that basic readable notification works.
  277. TEST_F(FdWatchControllerPosixTest, WatchReadable) {
  278. test::TaskEnvironment env(test::TaskEnvironment::MainThreadType::IO);
  279. MessagePumpForIO::FdWatchController watcher(FROM_HERE);
  280. TestHandler handler;
  281. // Watch the pipe for readability.
  282. ASSERT_TRUE(CurrentIOThread::Get()->WatchFileDescriptor(
  283. read_fd_.get(), /*persistent=*/false, MessagePumpForIO::WATCH_READ,
  284. &watcher, &handler));
  285. // The pipe should not be readable when first created.
  286. RunLoop().RunUntilIdle();
  287. ASSERT_FALSE(handler.is_readable_);
  288. ASSERT_FALSE(handler.is_writable_);
  289. TriggerReadEvent();
  290. // We don't want to assume that the read fd becomes readable the
  291. // instant a bytes is written, so Run until quit by an event.
  292. RunLoop().Run();
  293. ASSERT_TRUE(handler.is_readable_);
  294. ASSERT_FALSE(handler.is_writable_);
  295. }
  296. // Verify that watching a file descriptor for writability succeeds.
  297. TEST_F(FdWatchControllerPosixTest, WatchWritable) {
  298. test::TaskEnvironment env(test::TaskEnvironment::MainThreadType::IO);
  299. MessagePumpForIO::FdWatchController watcher(FROM_HERE);
  300. TestHandler handler;
  301. // Watch the pipe for writability.
  302. ASSERT_TRUE(CurrentIOThread::Get()->WatchFileDescriptor(
  303. write_fd_.get(), /*persistent=*/false, MessagePumpForIO::WATCH_WRITE,
  304. &watcher, &handler));
  305. // We should not receive a writable notification until we process events.
  306. ASSERT_FALSE(handler.is_readable_);
  307. ASSERT_FALSE(handler.is_writable_);
  308. // The pipe should be writable immediately, but wait for the quit closure
  309. // anyway, to be sure.
  310. RunLoop().Run();
  311. ASSERT_FALSE(handler.is_readable_);
  312. ASSERT_TRUE(handler.is_writable_);
  313. }
  314. // Verify that RunUntilIdle() receives IO notifications.
  315. TEST_F(FdWatchControllerPosixTest, RunUntilIdle) {
  316. test::TaskEnvironment env(test::TaskEnvironment::MainThreadType::IO);
  317. MessagePumpForIO::FdWatchController watcher(FROM_HERE);
  318. TestHandler handler;
  319. // Watch the pipe for readability.
  320. ASSERT_TRUE(CurrentIOThread::Get()->WatchFileDescriptor(
  321. read_fd_.get(), /*persistent=*/false, MessagePumpForIO::WATCH_READ,
  322. &watcher, &handler));
  323. // The pipe should not be readable when first created.
  324. RunLoop().RunUntilIdle();
  325. ASSERT_FALSE(handler.is_readable_);
  326. TriggerReadEvent();
  327. while (!handler.is_readable_)
  328. RunLoop().RunUntilIdle();
  329. }
  330. void StopWatching(MessagePumpForIO::FdWatchController* controller,
  331. RunLoop* run_loop) {
  332. controller->StopWatchingFileDescriptor();
  333. run_loop->Quit();
  334. }
  335. // Verify that StopWatchingFileDescriptor() works from an event handler.
  336. TEST_F(FdWatchControllerPosixTest, StopFromHandler) {
  337. test::TaskEnvironment env(test::TaskEnvironment::MainThreadType::IO);
  338. RunLoop run_loop;
  339. MessagePumpForIO::FdWatchController watcher(FROM_HERE);
  340. CallClosureHandler handler(BindOnce(&StopWatching, &watcher, &run_loop),
  341. OnceClosure());
  342. // Create persistent watcher.
  343. ASSERT_TRUE(CurrentIOThread::Get()->WatchFileDescriptor(
  344. read_fd_.get(), /*persistent=*/true, MessagePumpForIO::WATCH_READ,
  345. &watcher, &handler));
  346. TriggerReadEvent();
  347. run_loop.Run();
  348. // Trigger the event again. The event handler should not be called again.
  349. TriggerReadEvent();
  350. RunLoop().RunUntilIdle();
  351. }
  352. // Verify that non-persistent watcher is called only once.
  353. TEST_F(FdWatchControllerPosixTest, NonPersistentWatcher) {
  354. test::TaskEnvironment env(test::TaskEnvironment::MainThreadType::IO);
  355. MessagePumpForIO::FdWatchController watcher(FROM_HERE);
  356. RunLoop run_loop;
  357. CallClosureHandler handler(run_loop.QuitClosure(), OnceClosure());
  358. // Create a non-persistent watcher.
  359. ASSERT_TRUE(CurrentIOThread::Get()->WatchFileDescriptor(
  360. read_fd_.get(), /*persistent=*/false, MessagePumpForIO::WATCH_READ,
  361. &watcher, &handler));
  362. TriggerReadEvent();
  363. run_loop.Run();
  364. // Trigger the event again. handler should not be called again.
  365. TriggerReadEvent();
  366. RunLoop().RunUntilIdle();
  367. }
  368. // Verify that persistent watcher is called every time the event is triggered.
  369. TEST_F(FdWatchControllerPosixTest, PersistentWatcher) {
  370. test::TaskEnvironment env(test::TaskEnvironment::MainThreadType::IO);
  371. MessagePumpForIO::FdWatchController watcher(FROM_HERE);
  372. RunLoop run_loop1;
  373. CallClosureHandler handler(run_loop1.QuitClosure(), OnceClosure());
  374. // Create persistent watcher.
  375. ASSERT_TRUE(CurrentIOThread::Get()->WatchFileDescriptor(
  376. read_fd_.get(), /*persistent=*/true, MessagePumpForIO::WATCH_READ,
  377. &watcher, &handler));
  378. TriggerReadEvent();
  379. run_loop1.Run();
  380. RunLoop run_loop2;
  381. handler.SetReadClosure(run_loop2.QuitClosure());
  382. // Trigger the event again. handler should be called now, which will quit
  383. // run_loop2.
  384. TriggerReadEvent();
  385. run_loop2.Run();
  386. }
  387. void StopWatchingAndWatchAgain(MessagePumpForIO::FdWatchController* controller,
  388. int fd,
  389. MessagePumpForIO::FdWatcher* new_handler,
  390. RunLoop* run_loop) {
  391. controller->StopWatchingFileDescriptor();
  392. ASSERT_TRUE(CurrentIOThread::Get()->WatchFileDescriptor(
  393. fd, /*persistent=*/true, MessagePumpForIO::WATCH_READ, controller,
  394. new_handler));
  395. run_loop->Quit();
  396. }
  397. // Verify that a watcher can be stopped and reused from an event handler.
  398. TEST_F(FdWatchControllerPosixTest, StopAndRestartFromHandler) {
  399. test::TaskEnvironment env(test::TaskEnvironment::MainThreadType::IO);
  400. MessagePumpForIO::FdWatchController watcher(FROM_HERE);
  401. RunLoop run_loop1;
  402. RunLoop run_loop2;
  403. CallClosureHandler handler2(run_loop2.QuitClosure(), OnceClosure());
  404. CallClosureHandler handler1(BindOnce(&StopWatchingAndWatchAgain, &watcher,
  405. read_fd_.get(), &handler2, &run_loop1),
  406. OnceClosure());
  407. // Create persistent watcher.
  408. ASSERT_TRUE(CurrentIOThread::Get()->WatchFileDescriptor(
  409. read_fd_.get(), /*persistent=*/true, MessagePumpForIO::WATCH_READ,
  410. &watcher, &handler1));
  411. TriggerReadEvent();
  412. run_loop1.Run();
  413. // Trigger the event again. handler2 should be called now, which will quit
  414. // run_loop2
  415. TriggerReadEvent();
  416. run_loop2.Run();
  417. }
  418. // Verify that the pump properly handles a delayed task after an IO event.
  419. TEST_F(FdWatchControllerPosixTest, IoEventThenTimer) {
  420. test::TaskEnvironment env(test::TaskEnvironment::MainThreadType::IO);
  421. MessagePumpForIO::FdWatchController watcher(FROM_HERE);
  422. RunLoop timer_run_loop;
  423. env.GetMainThreadTaskRunner()->PostDelayedTask(
  424. FROM_HERE, timer_run_loop.QuitClosure(), base::Milliseconds(10));
  425. RunLoop watcher_run_loop;
  426. CallClosureHandler handler(watcher_run_loop.QuitClosure(), OnceClosure());
  427. // Create a non-persistent watcher.
  428. ASSERT_TRUE(CurrentIOThread::Get()->WatchFileDescriptor(
  429. read_fd_.get(), /*persistent=*/false, MessagePumpForIO::WATCH_READ,
  430. &watcher, &handler));
  431. TriggerReadEvent();
  432. // Normally the IO event will be received before the delayed task is
  433. // executed, so this run loop will first handle the IO event and then quit on
  434. // the timer.
  435. timer_run_loop.Run();
  436. // Run watcher_run_loop in case the IO event wasn't received before the
  437. // delayed task.
  438. watcher_run_loop.Run();
  439. }
  440. // Verify that the pipe can handle an IO event after a delayed task.
  441. TEST_F(FdWatchControllerPosixTest, TimerThenIoEvent) {
  442. test::TaskEnvironment env(test::TaskEnvironment::MainThreadType::IO);
  443. MessagePumpForIO::FdWatchController watcher(FROM_HERE);
  444. // Trigger read event from a delayed task.
  445. env.GetMainThreadTaskRunner()->PostDelayedTask(
  446. FROM_HERE,
  447. BindOnce(&FdWatchControllerPosixTest::TriggerReadEvent, Unretained(this)),
  448. Milliseconds(1));
  449. RunLoop run_loop;
  450. CallClosureHandler handler(run_loop.QuitClosure(), OnceClosure());
  451. // Create a non-persistent watcher.
  452. ASSERT_TRUE(CurrentIOThread::Get()->WatchFileDescriptor(
  453. read_fd_.get(), /*persistent=*/false, MessagePumpForIO::WATCH_READ,
  454. &watcher, &handler));
  455. run_loop.Run();
  456. }
  457. } // namespace
  458. #endif // !BUILDFLAG(IS_NACL)
  459. } // namespace base