Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Side by Side Diff: base/message_pump_io_ios_unittest.cc

Issue 11412101: Provide an iOS message pump for IO implementation. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Back to old approach for maintaining safety Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698