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