blob: c7d908e5fd79eb3a8efd9faab0659b5d15814601 [file] [log] [blame]
[email protected]8c3881ab2012-01-04 19:02:381// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]b4339c3a2011-05-13 16:19:232// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/message_pump_libevent.h"
6
7#include <unistd.h>
8
9#include "base/message_loop.h"
[email protected]2025d002012-11-14 20:54:3510#include "base/posix/eintr_wrapper.h"
[email protected]b4339c3a2011-05-13 16:19:2311#include "base/threading/thread.h"
12#include "testing/gtest/include/gtest/gtest.h"
[email protected]8d5f3ac2011-07-20 16:01:3213#include "third_party/libevent/event.h"
[email protected]8d5f3ac2011-07-20 16:01:3214
15namespace base {
[email protected]b4339c3a2011-05-13 16:19:2316
17class MessagePumpLibeventTest : public testing::Test {
[email protected]8d5f3ac2011-07-20 16:01:3218 protected:
[email protected]b4339c3a2011-05-13 16:19:2319 MessagePumpLibeventTest()
20 : ui_loop_(MessageLoop::TYPE_UI),
21 io_thread_("MessagePumpLibeventTestIOThread") {}
22 virtual ~MessagePumpLibeventTest() {}
23
[email protected]44106182012-04-06 03:53:0224 virtual void SetUp() OVERRIDE {
[email protected]8d5f3ac2011-07-20 16:01:3225 Thread::Options options(MessageLoop::TYPE_IO, 0);
[email protected]b4339c3a2011-05-13 16:19:2326 ASSERT_TRUE(io_thread_.StartWithOptions(options));
27 ASSERT_EQ(MessageLoop::TYPE_IO, io_thread_.message_loop()->type());
[email protected]d6bafc32012-11-30 17:29:4028 int ret = pipe(pipefds_);
29 ASSERT_EQ(0, ret);
[email protected]96364fe2012-07-11 03:25:4030 }
31
32 virtual void TearDown() OVERRIDE {
33 if (HANDLE_EINTR(close(pipefds_[0])) < 0)
34 PLOG(ERROR) << "close";
35 if (HANDLE_EINTR(close(pipefds_[1])) < 0)
36 PLOG(ERROR) << "close";
[email protected]b4339c3a2011-05-13 16:19:2337 }
38
39 MessageLoop* ui_loop() { return &ui_loop_; }
40 MessageLoopForIO* io_loop() const {
41 return static_cast<MessageLoopForIO*>(io_thread_.message_loop());
42 }
43
[email protected]8d5f3ac2011-07-20 16:01:3244 void OnLibeventNotification(
45 MessagePumpLibevent* pump,
46 MessagePumpLibevent::FileDescriptorWatcher* controller) {
47 pump->OnLibeventNotification(0, EV_WRITE | EV_READ, controller);
48 }
49
[email protected]d6bafc32012-11-30 17:29:4050 int pipefds_[2];
51
52 private:
[email protected]b4339c3a2011-05-13 16:19:2353 MessageLoop ui_loop_;
[email protected]8d5f3ac2011-07-20 16:01:3254 Thread io_thread_;
[email protected]b4339c3a2011-05-13 16:19:2355};
56
[email protected]8d5f3ac2011-07-20 16:01:3257namespace {
58
59// Concrete implementation of MessagePumpLibevent::Watcher that does
[email protected]b4339c3a2011-05-13 16:19:2360// nothing useful.
[email protected]8d5f3ac2011-07-20 16:01:3261class StupidWatcher : public MessagePumpLibevent::Watcher {
[email protected]b4339c3a2011-05-13 16:19:2362 public:
63 virtual ~StupidWatcher() {}
64
[email protected]a27de262011-06-22 06:33:0565 // base:MessagePumpLibevent::Watcher interface
[email protected]44106182012-04-06 03:53:0266 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE {}
67 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {}
[email protected]b4339c3a2011-05-13 16:19:2368};
69
[email protected]8c3881ab2012-01-04 19:02:3870#if GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
[email protected]b4339c3a2011-05-13 16:19:2371
72// Test to make sure that we catch calling WatchFileDescriptor off of the
73// wrong thread.
74TEST_F(MessagePumpLibeventTest, TestWatchingFromBadThread) {
[email protected]8d5f3ac2011-07-20 16:01:3275 MessagePumpLibevent::FileDescriptorWatcher watcher;
[email protected]b4339c3a2011-05-13 16:19:2376 StupidWatcher delegate;
77
[email protected]8c3881ab2012-01-04 19:02:3878 ASSERT_DEATH(io_loop()->WatchFileDescriptor(
[email protected]b4339c3a2011-05-13 16:19:2379 STDOUT_FILENO, false, MessageLoopForIO::WATCH_READ, &watcher, &delegate),
80 "Check failed: "
81 "watch_file_descriptor_caller_checker_.CalledOnValidThread()");
82}
83
[email protected]8c3881ab2012-01-04 19:02:3884#endif // GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
[email protected]8d5f3ac2011-07-20 16:01:3285
[email protected]96364fe2012-07-11 03:25:4086class BaseWatcher : public MessagePumpLibevent::Watcher {
[email protected]8d5f3ac2011-07-20 16:01:3287 public:
[email protected]f3c697c52013-01-15 10:52:1188 explicit BaseWatcher(MessagePumpLibevent::FileDescriptorWatcher* controller)
[email protected]8d5f3ac2011-07-20 16:01:3289 : controller_(controller) {
90 DCHECK(controller_);
91 }
[email protected]96364fe2012-07-11 03:25:4092 virtual ~BaseWatcher() {}
[email protected]8d5f3ac2011-07-20 16:01:3293
94 // base:MessagePumpLibevent::Watcher interface
[email protected]44106182012-04-06 03:53:0295 virtual void OnFileCanReadWithoutBlocking(int /* fd */) OVERRIDE {
[email protected]8d5f3ac2011-07-20 16:01:3296 NOTREACHED();
97 }
[email protected]96364fe2012-07-11 03:25:4098
99 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE {
100 NOTREACHED();
101 }
102
103 protected:
104 MessagePumpLibevent::FileDescriptorWatcher* controller_;
105};
106
107class DeleteWatcher : public BaseWatcher {
108 public:
109 explicit DeleteWatcher(
110 MessagePumpLibevent::FileDescriptorWatcher* controller)
111 : BaseWatcher(controller) {}
112
113 virtual ~DeleteWatcher() {
114 DCHECK(!controller_);
115 }
116
[email protected]44106182012-04-06 03:53:02117 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE {
[email protected]5f19e4012012-06-01 08:41:06118 DCHECK(controller_);
[email protected]8d5f3ac2011-07-20 16:01:32119 delete controller_;
[email protected]5f19e4012012-06-01 08:41:06120 controller_ = NULL;
[email protected]8d5f3ac2011-07-20 16:01:32121 }
[email protected]8d5f3ac2011-07-20 16:01:32122};
123
124TEST_F(MessagePumpLibeventTest, DeleteWatcher) {
125 scoped_refptr<MessagePumpLibevent> pump(new MessagePumpLibevent);
126 MessagePumpLibevent::FileDescriptorWatcher* watcher =
127 new MessagePumpLibevent::FileDescriptorWatcher;
128 DeleteWatcher delegate(watcher);
[email protected]96364fe2012-07-11 03:25:40129 pump->WatchFileDescriptor(pipefds_[1],
130 false, MessagePumpLibevent::WATCH_READ_WRITE, watcher, &delegate);
[email protected]8d5f3ac2011-07-20 16:01:32131
132 // Spoof a libevent notification.
133 OnLibeventNotification(pump, watcher);
134}
135
[email protected]96364fe2012-07-11 03:25:40136class StopWatcher : public BaseWatcher {
[email protected]8d5f3ac2011-07-20 16:01:32137 public:
138 explicit StopWatcher(
139 MessagePumpLibevent::FileDescriptorWatcher* controller)
[email protected]96364fe2012-07-11 03:25:40140 : BaseWatcher(controller) {}
141
[email protected]8d5f3ac2011-07-20 16:01:32142 virtual ~StopWatcher() {}
143
[email protected]44106182012-04-06 03:53:02144 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE {
[email protected]8d5f3ac2011-07-20 16:01:32145 controller_->StopWatchingFileDescriptor();
146 }
[email protected]8d5f3ac2011-07-20 16:01:32147};
148
149TEST_F(MessagePumpLibeventTest, StopWatcher) {
150 scoped_refptr<MessagePumpLibevent> pump(new MessagePumpLibevent);
151 MessagePumpLibevent::FileDescriptorWatcher watcher;
152 StopWatcher delegate(&watcher);
[email protected]96364fe2012-07-11 03:25:40153 pump->WatchFileDescriptor(pipefds_[1],
154 false, MessagePumpLibevent::WATCH_READ_WRITE, &watcher, &delegate);
[email protected]8d5f3ac2011-07-20 16:01:32155
156 // Spoof a libevent notification.
157 OnLibeventNotification(pump, &watcher);
158}
159
160} // namespace
161
162} // namespace base