blob: 94245cec8a91eddbc43fddbd3ddbf8a8ea3a8d0b [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"
13
[email protected]8d5f3ac2011-07-20 16:01:3214#if defined(USE_SYSTEM_LIBEVENT)
15#include <event.h>
16#else
17#include "third_party/libevent/event.h"
18#endif
19
20namespace base {
[email protected]b4339c3a2011-05-13 16:19:2321
22class MessagePumpLibeventTest : public testing::Test {
[email protected]8d5f3ac2011-07-20 16:01:3223 protected:
[email protected]b4339c3a2011-05-13 16:19:2324 MessagePumpLibeventTest()
25 : ui_loop_(MessageLoop::TYPE_UI),
26 io_thread_("MessagePumpLibeventTestIOThread") {}
27 virtual ~MessagePumpLibeventTest() {}
28
[email protected]44106182012-04-06 03:53:0229 virtual void SetUp() OVERRIDE {
[email protected]8d5f3ac2011-07-20 16:01:3230 Thread::Options options(MessageLoop::TYPE_IO, 0);
[email protected]b4339c3a2011-05-13 16:19:2331 ASSERT_TRUE(io_thread_.StartWithOptions(options));
32 ASSERT_EQ(MessageLoop::TYPE_IO, io_thread_.message_loop()->type());
[email protected]96364fe2012-07-11 03:25:4033 int err = pipe(pipefds_);
34 ASSERT_EQ(0, err);
35 }
36
37 virtual void TearDown() OVERRIDE {
38 if (HANDLE_EINTR(close(pipefds_[0])) < 0)
39 PLOG(ERROR) << "close";
40 if (HANDLE_EINTR(close(pipefds_[1])) < 0)
41 PLOG(ERROR) << "close";
[email protected]b4339c3a2011-05-13 16:19:2342 }
43
44 MessageLoop* ui_loop() { return &ui_loop_; }
45 MessageLoopForIO* io_loop() const {
46 return static_cast<MessageLoopForIO*>(io_thread_.message_loop());
47 }
48
[email protected]8d5f3ac2011-07-20 16:01:3249 void OnLibeventNotification(
50 MessagePumpLibevent* pump,
51 MessagePumpLibevent::FileDescriptorWatcher* controller) {
52 pump->OnLibeventNotification(0, EV_WRITE | EV_READ, controller);
53 }
54
[email protected]b4339c3a2011-05-13 16:19:2355 MessageLoop ui_loop_;
[email protected]8d5f3ac2011-07-20 16:01:3256 Thread io_thread_;
[email protected]96364fe2012-07-11 03:25:4057 int pipefds_[2];
[email protected]b4339c3a2011-05-13 16:19:2358};
59
[email protected]8d5f3ac2011-07-20 16:01:3260namespace {
61
62// Concrete implementation of MessagePumpLibevent::Watcher that does
[email protected]b4339c3a2011-05-13 16:19:2363// nothing useful.
[email protected]8d5f3ac2011-07-20 16:01:3264class StupidWatcher : public MessagePumpLibevent::Watcher {
[email protected]b4339c3a2011-05-13 16:19:2365 public:
66 virtual ~StupidWatcher() {}
67
[email protected]a27de262011-06-22 06:33:0568 // base:MessagePumpLibevent::Watcher interface
[email protected]44106182012-04-06 03:53:0269 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE {}
70 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {}
[email protected]b4339c3a2011-05-13 16:19:2371};
72
[email protected]8c3881ab2012-01-04 19:02:3873#if GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
[email protected]b4339c3a2011-05-13 16:19:2374
75// Test to make sure that we catch calling WatchFileDescriptor off of the
76// wrong thread.
77TEST_F(MessagePumpLibeventTest, TestWatchingFromBadThread) {
[email protected]8d5f3ac2011-07-20 16:01:3278 MessagePumpLibevent::FileDescriptorWatcher watcher;
[email protected]b4339c3a2011-05-13 16:19:2379 StupidWatcher delegate;
80
[email protected]8c3881ab2012-01-04 19:02:3881 ASSERT_DEATH(io_loop()->WatchFileDescriptor(
[email protected]b4339c3a2011-05-13 16:19:2382 STDOUT_FILENO, false, MessageLoopForIO::WATCH_READ, &watcher, &delegate),
83 "Check failed: "
84 "watch_file_descriptor_caller_checker_.CalledOnValidThread()");
85}
86
[email protected]8c3881ab2012-01-04 19:02:3887#endif // GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
[email protected]8d5f3ac2011-07-20 16:01:3288
[email protected]96364fe2012-07-11 03:25:4089class BaseWatcher : public MessagePumpLibevent::Watcher {
[email protected]8d5f3ac2011-07-20 16:01:3290 public:
[email protected]96364fe2012-07-11 03:25:4091 BaseWatcher(MessagePumpLibevent::FileDescriptorWatcher* controller)
[email protected]8d5f3ac2011-07-20 16:01:3292 : controller_(controller) {
93 DCHECK(controller_);
94 }
[email protected]96364fe2012-07-11 03:25:4095 virtual ~BaseWatcher() {}
[email protected]8d5f3ac2011-07-20 16:01:3296
97 // base:MessagePumpLibevent::Watcher interface
[email protected]44106182012-04-06 03:53:0298 virtual void OnFileCanReadWithoutBlocking(int /* fd */) OVERRIDE {
[email protected]8d5f3ac2011-07-20 16:01:3299 NOTREACHED();
100 }
[email protected]96364fe2012-07-11 03:25:40101
102 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE {
103 NOTREACHED();
104 }
105
106 protected:
107 MessagePumpLibevent::FileDescriptorWatcher* controller_;
108};
109
110class DeleteWatcher : public BaseWatcher {
111 public:
112 explicit DeleteWatcher(
113 MessagePumpLibevent::FileDescriptorWatcher* controller)
114 : BaseWatcher(controller) {}
115
116 virtual ~DeleteWatcher() {
117 DCHECK(!controller_);
118 }
119
[email protected]44106182012-04-06 03:53:02120 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE {
[email protected]5f19e4012012-06-01 08:41:06121 DCHECK(controller_);
[email protected]8d5f3ac2011-07-20 16:01:32122 delete controller_;
[email protected]5f19e4012012-06-01 08:41:06123 controller_ = NULL;
[email protected]8d5f3ac2011-07-20 16:01:32124 }
[email protected]8d5f3ac2011-07-20 16:01:32125};
126
127TEST_F(MessagePumpLibeventTest, DeleteWatcher) {
128 scoped_refptr<MessagePumpLibevent> pump(new MessagePumpLibevent);
129 MessagePumpLibevent::FileDescriptorWatcher* watcher =
130 new MessagePumpLibevent::FileDescriptorWatcher;
131 DeleteWatcher delegate(watcher);
[email protected]96364fe2012-07-11 03:25:40132 pump->WatchFileDescriptor(pipefds_[1],
133 false, MessagePumpLibevent::WATCH_READ_WRITE, watcher, &delegate);
[email protected]8d5f3ac2011-07-20 16:01:32134
135 // Spoof a libevent notification.
136 OnLibeventNotification(pump, watcher);
137}
138
[email protected]96364fe2012-07-11 03:25:40139class StopWatcher : public BaseWatcher {
[email protected]8d5f3ac2011-07-20 16:01:32140 public:
141 explicit StopWatcher(
142 MessagePumpLibevent::FileDescriptorWatcher* controller)
[email protected]96364fe2012-07-11 03:25:40143 : BaseWatcher(controller) {}
144
[email protected]8d5f3ac2011-07-20 16:01:32145 virtual ~StopWatcher() {}
146
[email protected]44106182012-04-06 03:53:02147 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE {
[email protected]8d5f3ac2011-07-20 16:01:32148 controller_->StopWatchingFileDescriptor();
149 }
[email protected]8d5f3ac2011-07-20 16:01:32150};
151
152TEST_F(MessagePumpLibeventTest, StopWatcher) {
153 scoped_refptr<MessagePumpLibevent> pump(new MessagePumpLibevent);
154 MessagePumpLibevent::FileDescriptorWatcher watcher;
155 StopWatcher delegate(&watcher);
[email protected]96364fe2012-07-11 03:25:40156 pump->WatchFileDescriptor(pipefds_[1],
157 false, MessagePumpLibevent::WATCH_READ_WRITE, &watcher, &delegate);
[email protected]8d5f3ac2011-07-20 16:01:32158
159 // Spoof a libevent notification.
160 OnLibeventNotification(pump, &watcher);
161}
162
163} // namespace
164
165} // namespace base