OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/message_pump_libevent.h" | 5 #include "base/message_pump_io_ios.h" |
6 | 6 |
7 #include <unistd.h> | 7 #include <unistd.h> |
8 | 8 |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/posix/eintr_wrapper.h" | 10 #include "base/posix/eintr_wrapper.h" |
11 #include "base/threading/thread.h" | 11 #include "base/threading/thread.h" |
12 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
13 | 13 |
14 #if defined(USE_SYSTEM_LIBEVENT) | |
15 #include <event.h> | |
16 #else | |
17 #include "third_party/libevent/event.h" | |
18 #endif | |
19 | |
20 namespace base { | 14 namespace base { |
21 | 15 |
22 class MessagePumpLibeventTest : public testing::Test { | 16 class MessagePumpIOSForIOTest : public testing::Test { |
23 protected: | 17 protected: |
24 MessagePumpLibeventTest() | 18 MessagePumpIOSForIOTest() |
25 : ui_loop_(MessageLoop::TYPE_UI), | 19 : ui_loop_(MessageLoop::TYPE_UI), |
26 io_thread_("MessagePumpLibeventTestIOThread") {} | 20 io_thread_("MessagePumpIOSForIOTestIOThread") {} |
27 virtual ~MessagePumpLibeventTest() {} | 21 virtual ~MessagePumpIOSForIOTest() {} |
28 | 22 |
29 virtual void SetUp() OVERRIDE { | 23 virtual void SetUp() { |
30 Thread::Options options(MessageLoop::TYPE_IO, 0); | 24 Thread::Options options(MessageLoop::TYPE_IO, 0); |
31 ASSERT_TRUE(io_thread_.StartWithOptions(options)); | 25 ASSERT_TRUE(io_thread_.StartWithOptions(options)); |
32 ASSERT_EQ(MessageLoop::TYPE_IO, io_thread_.message_loop()->type()); | 26 ASSERT_EQ(MessageLoop::TYPE_IO, io_thread_.message_loop()->type()); |
33 int err = pipe(pipefds_); | 27 int ret = pipe(pipefds_); |
34 ASSERT_EQ(0, err); | 28 ASSERT_EQ(0, ret); |
29 ret = pipe(alternate_pipefds_); | |
30 ASSERT_EQ(0, ret); | |
35 } | 31 } |
36 | 32 |
37 virtual void TearDown() OVERRIDE { | 33 virtual void TearDown() OVERRIDE { |
38 if (HANDLE_EINTR(close(pipefds_[0])) < 0) | 34 if (HANDLE_EINTR(close(pipefds_[0])) < 0) |
39 PLOG(ERROR) << "close"; | 35 PLOG(ERROR) << "close"; |
40 if (HANDLE_EINTR(close(pipefds_[1])) < 0) | 36 if (HANDLE_EINTR(close(pipefds_[1])) < 0) |
41 PLOG(ERROR) << "close"; | 37 PLOG(ERROR) << "close"; |
42 } | 38 } |
43 | 39 |
44 MessageLoop* ui_loop() { return &ui_loop_; } | 40 MessageLoop* ui_loop() { return &ui_loop_; } |
45 MessageLoopForIO* io_loop() const { | 41 MessageLoopForIO* io_loop() const { |
46 return static_cast<MessageLoopForIO*>(io_thread_.message_loop()); | 42 return static_cast<MessageLoopForIO*>(io_thread_.message_loop()); |
47 } | 43 } |
48 | 44 |
49 void OnLibeventNotification( | 45 void SetWatcherDelegate(MessageLoopForIO::FileDescriptorWatcher* watcher, |
50 MessagePumpLibevent* pump, | 46 MessageLoopForIO::Watcher* delegate) { |
51 MessagePumpLibevent::FileDescriptorWatcher* controller) { | 47 watcher->set_watcher(delegate); |
52 pump->OnLibeventNotification(0, EV_WRITE | EV_READ, controller); | |
53 } | 48 } |
54 | 49 |
50 void HandleFdIOEvent(MessageLoopForIO::FileDescriptorWatcher* watcher) { | |
51 MessagePumpIOSForIO::HandleFdIOEvent(watcher->fdref_, | |
52 kCFFileDescriptorReadCallBack | kCFFileDescriptorWriteCallBack, | |
53 watcher); | |
54 } | |
55 | |
56 int pipefds_[2]; | |
57 int alternate_pipefds_[2]; | |
58 | |
59 private: | |
55 MessageLoop ui_loop_; | 60 MessageLoop ui_loop_; |
56 Thread io_thread_; | 61 Thread io_thread_; |
57 int pipefds_[2]; | 62 |
63 DISALLOW_COPY_AND_ASSIGN(MessagePumpIOSForIOTest); | |
58 }; | 64 }; |
59 | 65 |
60 namespace { | 66 namespace { |
61 | 67 |
62 // Concrete implementation of MessagePumpLibevent::Watcher that does | 68 // Concrete implementation of MessagePumpIOSForIO::Watcher that does |
63 // nothing useful. | 69 // nothing useful. |
64 class StupidWatcher : public MessagePumpLibevent::Watcher { | 70 class StupidWatcher : public MessagePumpIOSForIO::Watcher { |
65 public: | 71 public: |
66 virtual ~StupidWatcher() {} | 72 virtual ~StupidWatcher() {} |
67 | 73 |
68 // base:MessagePumpLibevent::Watcher interface | 74 // base:MessagePumpIOSForIO::Watcher interface |
69 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE {} | 75 virtual void OnFileCanReadWithoutBlocking(int fd) {} |
70 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {} | 76 virtual void OnFileCanWriteWithoutBlocking(int fd) {} |
71 }; | 77 }; |
72 | 78 |
73 #if GTEST_HAS_DEATH_TEST && !defined(NDEBUG) | 79 #if GTEST_HAS_DEATH_TEST |
74 | 80 |
75 // Test to make sure that we catch calling WatchFileDescriptor off of the | 81 // Test to make sure that we catch calling WatchFileDescriptor off of the |
76 // wrong thread. | 82 // wrong thread. |
77 TEST_F(MessagePumpLibeventTest, TestWatchingFromBadThread) { | 83 TEST_F(MessagePumpIOSForIOTest, TestWatchingFromBadThread) { |
78 MessagePumpLibevent::FileDescriptorWatcher watcher; | 84 MessagePumpIOSForIO::FileDescriptorWatcher watcher; |
79 StupidWatcher delegate; | 85 StupidWatcher delegate; |
80 | 86 |
81 ASSERT_DEATH(io_loop()->WatchFileDescriptor( | 87 ASSERT_DEBUG_DEATH(io_loop()->WatchFileDescriptor( |
82 STDOUT_FILENO, false, MessageLoopForIO::WATCH_READ, &watcher, &delegate), | 88 STDOUT_FILENO, false, MessageLoopForIO::WATCH_READ, &watcher, &delegate), |
83 "Check failed: " | 89 "Check failed: " |
84 "watch_file_descriptor_caller_checker_.CalledOnValidThread()"); | 90 "watch_file_descriptor_caller_checker_.CalledOnValidThread()"); |
85 } | 91 } |
86 | 92 |
87 #endif // GTEST_HAS_DEATH_TEST && !defined(NDEBUG) | 93 #endif // GTEST_HAS_DEATH_TEST |
88 | 94 |
89 class BaseWatcher : public MessagePumpLibevent::Watcher { | 95 class BaseWatcher : public MessagePumpIOSForIO::Watcher { |
90 public: | 96 public: |
91 BaseWatcher(MessagePumpLibevent::FileDescriptorWatcher* controller) | 97 BaseWatcher(MessagePumpIOSForIO::FileDescriptorWatcher* controller) |
92 : controller_(controller) { | 98 : controller_(controller) { |
93 DCHECK(controller_); | 99 DCHECK(controller_); |
94 } | 100 } |
95 virtual ~BaseWatcher() {} | 101 virtual ~BaseWatcher() {} |
96 | 102 |
97 // base:MessagePumpLibevent::Watcher interface | 103 // MessagePumpIOSForIO::Watcher interface |
98 virtual void OnFileCanReadWithoutBlocking(int /* fd */) OVERRIDE { | 104 virtual void OnFileCanReadWithoutBlocking(int /* fd */) OVERRIDE { |
99 NOTREACHED(); | 105 NOTREACHED(); |
100 } | 106 } |
101 | 107 |
102 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE { | 108 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE { |
103 NOTREACHED(); | 109 NOTREACHED(); |
104 } | 110 } |
105 | 111 |
106 protected: | 112 protected: |
107 MessagePumpLibevent::FileDescriptorWatcher* controller_; | 113 MessagePumpIOSForIO::FileDescriptorWatcher* controller_; |
108 }; | 114 }; |
109 | 115 |
110 class DeleteWatcher : public BaseWatcher { | 116 class DeleteWatcher : public BaseWatcher { |
111 public: | 117 public: |
112 explicit DeleteWatcher( | 118 explicit DeleteWatcher( |
113 MessagePumpLibevent::FileDescriptorWatcher* controller) | 119 MessagePumpIOSForIO::FileDescriptorWatcher* controller) |
114 : BaseWatcher(controller) {} | 120 : BaseWatcher(controller) {} |
115 | 121 |
116 virtual ~DeleteWatcher() { | 122 virtual ~DeleteWatcher() { |
117 DCHECK(!controller_); | 123 DCHECK(!controller_); |
118 } | 124 } |
119 | 125 |
120 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE { | 126 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE { |
121 DCHECK(controller_); | 127 DCHECK(controller_); |
122 delete controller_; | 128 delete controller_; |
123 controller_ = NULL; | 129 controller_ = NULL; |
124 } | 130 } |
125 }; | 131 }; |
126 | 132 |
127 TEST_F(MessagePumpLibeventTest, DeleteWatcher) { | 133 TEST_F(MessagePumpIOSForIOTest, DeleteWatcher) { |
128 scoped_refptr<MessagePumpLibevent> pump(new MessagePumpLibevent); | 134 scoped_refptr<MessagePumpIOSForIO> pump(new MessagePumpIOSForIO); |
129 MessagePumpLibevent::FileDescriptorWatcher* watcher = | 135 MessagePumpIOSForIO::FileDescriptorWatcher* watcher = |
130 new MessagePumpLibevent::FileDescriptorWatcher; | 136 new MessagePumpIOSForIO::FileDescriptorWatcher; |
131 DeleteWatcher delegate(watcher); | 137 DeleteWatcher delegate(watcher); |
138 SetWatcherDelegate(watcher, &delegate); | |
139 | |
132 pump->WatchFileDescriptor(pipefds_[1], | 140 pump->WatchFileDescriptor(pipefds_[1], |
133 false, MessagePumpLibevent::WATCH_READ_WRITE, watcher, &delegate); | 141 false, MessagePumpIOSForIO::WATCH_READ_WRITE, watcher, &delegate); |
134 | 142 |
135 // Spoof a libevent notification. | 143 // Spoof a callback. |
136 OnLibeventNotification(pump, watcher); | 144 HandleFdIOEvent(watcher); |
137 } | 145 } |
138 | 146 |
139 class StopWatcher : public BaseWatcher { | 147 class StopWatcher : public BaseWatcher { |
140 public: | 148 public: |
141 explicit StopWatcher( | 149 explicit StopWatcher( |
142 MessagePumpLibevent::FileDescriptorWatcher* controller) | 150 MessagePumpIOSForIO::FileDescriptorWatcher* controller, |
143 : BaseWatcher(controller) {} | 151 MessagePumpIOSForIO* pump, |
152 int fd_to_start_watching = 0) | |
wtc
2012/11/29 20:30:34
1. Remove "explicit".
2. Nit: the native fd 0 is
blundell
2012/11/30 11:19:52
1. Done.
2. Changed the value of the default argu
| |
153 : BaseWatcher(controller), | |
154 pump_(pump), | |
155 fd_to_start_watching_(fd_to_start_watching) {} | |
144 | 156 |
145 virtual ~StopWatcher() {} | 157 virtual ~StopWatcher() {} |
146 | 158 |
147 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE { | 159 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE { |
148 controller_->StopWatchingFileDescriptor(); | 160 controller_->StopWatchingFileDescriptor(); |
161 if (fd_to_start_watching_) { | |
wtc
2012/11/29 20:30:34
If you use -1 as the default value, this test shou
blundell
2012/11/30 11:19:52
Done.
| |
162 pump_->WatchFileDescriptor(fd_to_start_watching_, | |
163 false, MessagePumpIOSForIO::WATCH_READ_WRITE, controller_, this); | |
164 } | |
149 } | 165 } |
166 | |
167 private: | |
168 MessagePumpIOSForIO* pump_; | |
169 int fd_to_start_watching_; | |
150 }; | 170 }; |
151 | 171 |
152 TEST_F(MessagePumpLibeventTest, StopWatcher) { | 172 TEST_F(MessagePumpIOSForIOTest, StopWatcher) { |
153 scoped_refptr<MessagePumpLibevent> pump(new MessagePumpLibevent); | 173 scoped_refptr<MessagePumpIOSForIO> pump(new MessagePumpIOSForIO); |
154 MessagePumpLibevent::FileDescriptorWatcher watcher; | 174 MessagePumpIOSForIO::FileDescriptorWatcher watcher; |
155 StopWatcher delegate(&watcher); | 175 StopWatcher delegate(&watcher, pump); |
176 SetWatcherDelegate(&watcher, &delegate); | |
177 | |
156 pump->WatchFileDescriptor(pipefds_[1], | 178 pump->WatchFileDescriptor(pipefds_[1], |
157 false, MessagePumpLibevent::WATCH_READ_WRITE, &watcher, &delegate); | 179 false, MessagePumpIOSForIO::WATCH_READ_WRITE, &watcher, &delegate); |
158 | 180 |
159 // Spoof a libevent notification. | 181 // Spoof a callback. |
160 OnLibeventNotification(pump, &watcher); | 182 HandleFdIOEvent(&watcher); |
183 } | |
184 | |
185 TEST_F(MessagePumpIOSForIOTest, StopWatcherAndWatchSomethingElse) { | |
186 scoped_refptr<MessagePumpIOSForIO> pump(new MessagePumpIOSForIO); | |
187 MessagePumpIOSForIO::FileDescriptorWatcher watcher; | |
188 StopWatcher delegate(&watcher, pump, alternate_pipefds_[1]); | |
189 SetWatcherDelegate(&watcher, &delegate); | |
190 | |
191 pump->WatchFileDescriptor(pipefds_[1], | |
192 false, MessagePumpIOSForIO::WATCH_READ_WRITE, &watcher, &delegate); | |
193 | |
194 // Spoof a callback. | |
195 HandleFdIOEvent(&watcher); | |
161 } | 196 } |
162 | 197 |
163 } // namespace | 198 } // namespace |
164 | 199 |
165 } // namespace base | 200 } // namespace base |
OLD | NEW |