blob: e48a9c53090429921294408e2c4ea2efe7d15084 [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]d6bafc32012-11-30 17:29:4033 int ret = pipe(pipefds_);
34 ASSERT_EQ(0, ret);
[email protected]96364fe2012-07-11 03:25:4035 }
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]d6bafc32012-11-30 17:29:4055 int pipefds_[2];
56
57 private:
[email protected]b4339c3a2011-05-13 16:19:2358 MessageLoop ui_loop_;
[email protected]8d5f3ac2011-07-20 16:01:3259 Thread io_thread_;
[email protected]b4339c3a2011-05-13 16:19:2360};
61
[email protected]8d5f3ac2011-07-20 16:01:3262namespace {
63
64// Concrete implementation of MessagePumpLibevent::Watcher that does
[email protected]b4339c3a2011-05-13 16:19:2365// nothing useful.
[email protected]8d5f3ac2011-07-20 16:01:3266class StupidWatcher : public MessagePumpLibevent::Watcher {
[email protected]b4339c3a2011-05-13 16:19:2367 public:
68 virtual ~StupidWatcher() {}
69
[email protected]a27de262011-06-22 06:33:0570 // base:MessagePumpLibevent::Watcher interface
[email protected]44106182012-04-06 03:53:0271 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE {}
72 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {}
[email protected]b4339c3a2011-05-13 16:19:2373};
74
[email protected]8c3881ab2012-01-04 19:02:3875#if GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
[email protected]b4339c3a2011-05-13 16:19:2376
77// Test to make sure that we catch calling WatchFileDescriptor off of the
78// wrong thread.
79TEST_F(MessagePumpLibeventTest, TestWatchingFromBadThread) {
[email protected]8d5f3ac2011-07-20 16:01:3280 MessagePumpLibevent::FileDescriptorWatcher watcher;
[email protected]b4339c3a2011-05-13 16:19:2381 StupidWatcher delegate;
82
[email protected]8c3881ab2012-01-04 19:02:3883 ASSERT_DEATH(io_loop()->WatchFileDescriptor(
[email protected]b4339c3a2011-05-13 16:19:2384 STDOUT_FILENO, false, MessageLoopForIO::WATCH_READ, &watcher, &delegate),
85 "Check failed: "
86 "watch_file_descriptor_caller_checker_.CalledOnValidThread()");
87}
88
[email protected]8c3881ab2012-01-04 19:02:3889#endif // GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
[email protected]8d5f3ac2011-07-20 16:01:3290
[email protected]96364fe2012-07-11 03:25:4091class BaseWatcher : public MessagePumpLibevent::Watcher {
[email protected]8d5f3ac2011-07-20 16:01:3292 public:
[email protected]96364fe2012-07-11 03:25:4093 BaseWatcher(MessagePumpLibevent::FileDescriptorWatcher* controller)
[email protected]8d5f3ac2011-07-20 16:01:3294 : controller_(controller) {
95 DCHECK(controller_);
96 }
[email protected]96364fe2012-07-11 03:25:4097 virtual ~BaseWatcher() {}
[email protected]8d5f3ac2011-07-20 16:01:3298
99 // base:MessagePumpLibevent::Watcher interface
[email protected]44106182012-04-06 03:53:02100 virtual void OnFileCanReadWithoutBlocking(int /* fd */) OVERRIDE {
[email protected]8d5f3ac2011-07-20 16:01:32101 NOTREACHED();
102 }
[email protected]96364fe2012-07-11 03:25:40103
104 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE {
105 NOTREACHED();
106 }
107
108 protected:
109 MessagePumpLibevent::FileDescriptorWatcher* controller_;
110};
111
112class DeleteWatcher : public BaseWatcher {
113 public:
114 explicit DeleteWatcher(
115 MessagePumpLibevent::FileDescriptorWatcher* controller)
116 : BaseWatcher(controller) {}
117
118 virtual ~DeleteWatcher() {
119 DCHECK(!controller_);
120 }
121
[email protected]44106182012-04-06 03:53:02122 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE {
[email protected]5f19e4012012-06-01 08:41:06123 DCHECK(controller_);
[email protected]8d5f3ac2011-07-20 16:01:32124 delete controller_;
[email protected]5f19e4012012-06-01 08:41:06125 controller_ = NULL;
[email protected]8d5f3ac2011-07-20 16:01:32126 }
[email protected]8d5f3ac2011-07-20 16:01:32127};
128
129TEST_F(MessagePumpLibeventTest, DeleteWatcher) {
130 scoped_refptr<MessagePumpLibevent> pump(new MessagePumpLibevent);
131 MessagePumpLibevent::FileDescriptorWatcher* watcher =
132 new MessagePumpLibevent::FileDescriptorWatcher;
133 DeleteWatcher delegate(watcher);
[email protected]96364fe2012-07-11 03:25:40134 pump->WatchFileDescriptor(pipefds_[1],
135 false, MessagePumpLibevent::WATCH_READ_WRITE, watcher, &delegate);
[email protected]8d5f3ac2011-07-20 16:01:32136
137 // Spoof a libevent notification.
138 OnLibeventNotification(pump, watcher);
139}
140
[email protected]96364fe2012-07-11 03:25:40141class StopWatcher : public BaseWatcher {
[email protected]8d5f3ac2011-07-20 16:01:32142 public:
143 explicit StopWatcher(
144 MessagePumpLibevent::FileDescriptorWatcher* controller)
[email protected]96364fe2012-07-11 03:25:40145 : BaseWatcher(controller) {}
146
[email protected]8d5f3ac2011-07-20 16:01:32147 virtual ~StopWatcher() {}
148
[email protected]44106182012-04-06 03:53:02149 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE {
[email protected]8d5f3ac2011-07-20 16:01:32150 controller_->StopWatchingFileDescriptor();
151 }
[email protected]8d5f3ac2011-07-20 16:01:32152};
153
154TEST_F(MessagePumpLibeventTest, StopWatcher) {
155 scoped_refptr<MessagePumpLibevent> pump(new MessagePumpLibevent);
156 MessagePumpLibevent::FileDescriptorWatcher watcher;
157 StopWatcher delegate(&watcher);
[email protected]96364fe2012-07-11 03:25:40158 pump->WatchFileDescriptor(pipefds_[1],
159 false, MessagePumpLibevent::WATCH_READ_WRITE, &watcher, &delegate);
[email protected]8d5f3ac2011-07-20 16:01:32160
161 // Spoof a libevent notification.
162 OnLibeventNotification(pump, &watcher);
163}
164
165} // namespace
166
167} // namespace base