| Index: base/message_loop/message_pump_libevent_unittest.cc
|
| diff --git a/base/message_loop/message_pump_libevent_unittest.cc b/base/message_loop/message_pump_libevent_unittest.cc
|
| index 1058ee8697671e97d5671689568b1bb6dd8bb56c..65d721727284f35cfdc3ad621c63ddb5fa51e9e7 100644
|
| --- a/base/message_loop/message_pump_libevent_unittest.cc
|
| +++ b/base/message_loop/message_pump_libevent_unittest.cc
|
| @@ -7,9 +7,14 @@
|
| #include <unistd.h>
|
|
|
| #include "base/bind.h"
|
| +#include "base/bind_helpers.h"
|
| +#include "base/files/file_util.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| #include "base/message_loop/message_loop.h"
|
| #include "base/posix/eintr_wrapper.h"
|
| #include "base/run_loop.h"
|
| +#include "base/synchronization/waitable_event.h"
|
| +#include "base/synchronization/waitable_event_watcher.h"
|
| #include "base/threading/thread.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| #include "third_party/libevent/event.h"
|
| @@ -19,7 +24,7 @@ namespace base {
|
| class MessagePumpLibeventTest : public testing::Test {
|
| protected:
|
| MessagePumpLibeventTest()
|
| - : ui_loop_(MessageLoop::TYPE_UI),
|
| + : ui_loop_(new MessageLoop(MessageLoop::TYPE_UI)),
|
| io_thread_("MessagePumpLibeventTestIOThread") {}
|
| ~MessagePumpLibeventTest() override {}
|
|
|
| @@ -38,7 +43,6 @@ class MessagePumpLibeventTest : public testing::Test {
|
| PLOG(ERROR) << "close";
|
| }
|
|
|
| - MessageLoop* ui_loop() { return &ui_loop_; }
|
| MessageLoopForIO* io_loop() const {
|
| return static_cast<MessageLoopForIO*>(io_thread_.message_loop());
|
| }
|
| @@ -50,9 +54,9 @@ class MessagePumpLibeventTest : public testing::Test {
|
| }
|
|
|
| int pipefds_[2];
|
| + scoped_ptr<MessageLoop> ui_loop_;
|
|
|
| private:
|
| - MessageLoop ui_loop_;
|
| Thread io_thread_;
|
| };
|
|
|
| @@ -194,6 +198,69 @@ TEST_F(MessagePumpLibeventTest, NestedPumpWatcher) {
|
| OnLibeventNotification(pump.get(), &watcher);
|
| }
|
|
|
| +void FatalClosure() {
|
| + FAIL() << "Reached fatal closure.";
|
| +}
|
| +
|
| +class QuitWatcher : public BaseWatcher {
|
| + public:
|
| + QuitWatcher(MessagePumpLibevent::FileDescriptorWatcher* controller,
|
| + RunLoop* run_loop)
|
| + : BaseWatcher(controller), run_loop_(run_loop) {}
|
| + ~QuitWatcher() override {}
|
| +
|
| + void OnFileCanReadWithoutBlocking(int /* fd */) override {
|
| + // Post a fatal closure to the MessageLoop before we quit it.
|
| + MessageLoop::current()->PostTask(FROM_HERE, Bind(&FatalClosure));
|
| +
|
| + // Now quit the MessageLoop.
|
| + run_loop_->Quit();
|
| + }
|
| +
|
| + private:
|
| + RunLoop* run_loop_; // weak
|
| +};
|
| +
|
| +void WriteFDWrapper(const int fd,
|
| + const char* buf,
|
| + int size,
|
| + WaitableEvent* event) {
|
| + ASSERT_TRUE(WriteFileDescriptor(fd, buf, size));
|
| +}
|
| +
|
| +// Tests that MessagePumpLibevent quits immediately when it is quit from
|
| +// libevent's event_base_loop().
|
| +TEST_F(MessagePumpLibeventTest, QuitWatcher) {
|
| + // Delete the old MessageLoop so that we can manage our own one here.
|
| + ui_loop_.reset();
|
| +
|
| + MessagePumpLibevent* pump = new MessagePumpLibevent; // owned by |loop|.
|
| + MessageLoop loop(make_scoped_ptr(pump));
|
| + RunLoop run_loop;
|
| + MessagePumpLibevent::FileDescriptorWatcher controller;
|
| + QuitWatcher delegate(&controller, &run_loop);
|
| + WaitableEvent event(false /* manual_reset */, false /* initially_signaled */);
|
| + WaitableEventWatcher watcher;
|
| +
|
| + // Tell the pump to watch the pipe.
|
| + pump->WatchFileDescriptor(pipefds_[0], false, MessagePumpLibevent::WATCH_READ,
|
| + &controller, &delegate);
|
| +
|
| + // Make the IO thread wait for |event| before writing to pipefds[1].
|
| + const char buf = 0;
|
| + const WaitableEventWatcher::EventCallback write_fd_task =
|
| + Bind(&WriteFDWrapper, pipefds_[1], &buf, 1);
|
| + io_loop()->PostTask(FROM_HERE,
|
| + Bind(IgnoreResult(&WaitableEventWatcher::StartWatching),
|
| + Unretained(&watcher), &event, write_fd_task));
|
| +
|
| + // Queue |event| to signal on |loop|.
|
| + loop.PostTask(FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&event)));
|
| +
|
| + // Now run the MessageLoop.
|
| + run_loop.Run();
|
| +}
|
| +
|
| } // namespace
|
|
|
| } // namespace base
|
|
|