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

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: Response to wtc's review 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
« no previous file with comments | « base/message_pump_io_ios.cc ('k') | base/message_pump_libevent.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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() OVERRIDE {
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 HandleFdIOEvent(MessageLoopForIO::FileDescriptorWatcher* watcher) {
50 MessagePumpLibevent* pump, 46 MessagePumpIOSForIO::HandleFdIOEvent(watcher->fdref_,
51 MessagePumpLibevent::FileDescriptorWatcher* controller) { 47 kCFFileDescriptorReadCallBack | kCFFileDescriptorWriteCallBack,
52 pump->OnLibeventNotification(0, EV_WRITE | EV_READ, controller); 48 watcher);
53 } 49 }
54 50
51 int pipefds_[2];
52 int alternate_pipefds_[2];
53
54 private:
55 MessageLoop ui_loop_; 55 MessageLoop ui_loop_;
56 Thread io_thread_; 56 Thread io_thread_;
57 int pipefds_[2]; 57
58 DISALLOW_COPY_AND_ASSIGN(MessagePumpIOSForIOTest);
58 }; 59 };
59 60
60 namespace { 61 namespace {
61 62
62 // Concrete implementation of MessagePumpLibevent::Watcher that does 63 // Concrete implementation of MessagePumpIOSForIO::Watcher that does
63 // nothing useful. 64 // nothing useful.
64 class StupidWatcher : public MessagePumpLibevent::Watcher { 65 class StupidWatcher : public MessagePumpIOSForIO::Watcher {
65 public: 66 public:
66 virtual ~StupidWatcher() {} 67 virtual ~StupidWatcher() {}
67 68
68 // base:MessagePumpLibevent::Watcher interface 69 // base:MessagePumpIOSForIO::Watcher interface
69 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE {} 70 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE {}
70 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {} 71 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {}
71 }; 72 };
72 73
73 #if GTEST_HAS_DEATH_TEST && !defined(NDEBUG) 74 #if GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
74 75
75 // Test to make sure that we catch calling WatchFileDescriptor off of the 76 // Test to make sure that we catch calling WatchFileDescriptor off of the
76 // wrong thread. 77 // wrong thread.
77 TEST_F(MessagePumpLibeventTest, TestWatchingFromBadThread) { 78 TEST_F(MessagePumpIOSForIOTest, TestWatchingFromBadThread) {
78 MessagePumpLibevent::FileDescriptorWatcher watcher; 79 MessagePumpIOSForIO::FileDescriptorWatcher watcher;
79 StupidWatcher delegate; 80 StupidWatcher delegate;
80 81
81 ASSERT_DEATH(io_loop()->WatchFileDescriptor( 82 ASSERT_DEBUG(io_loop()->WatchFileDescriptor(
82 STDOUT_FILENO, false, MessageLoopForIO::WATCH_READ, &watcher, &delegate), 83 STDOUT_FILENO, false, MessageLoopForIO::WATCH_READ, &watcher, &delegate),
83 "Check failed: " 84 "Check failed: "
84 "watch_file_descriptor_caller_checker_.CalledOnValidThread()"); 85 "watch_file_descriptor_caller_checker_.CalledOnValidThread()");
85 } 86 }
86 87
87 #endif // GTEST_HAS_DEATH_TEST && !defined(NDEBUG) 88 #endif // GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
88 89
89 class BaseWatcher : public MessagePumpLibevent::Watcher { 90 class BaseWatcher : public MessagePumpIOSForIO::Watcher {
90 public: 91 public:
91 BaseWatcher(MessagePumpLibevent::FileDescriptorWatcher* controller) 92 BaseWatcher(MessagePumpIOSForIO::FileDescriptorWatcher* controller)
92 : controller_(controller) { 93 : controller_(controller) {
93 DCHECK(controller_); 94 DCHECK(controller_);
94 } 95 }
95 virtual ~BaseWatcher() {} 96 virtual ~BaseWatcher() {}
96 97
97 // base:MessagePumpLibevent::Watcher interface 98 // MessagePumpIOSForIO::Watcher interface
98 virtual void OnFileCanReadWithoutBlocking(int /* fd */) OVERRIDE { 99 virtual void OnFileCanReadWithoutBlocking(int /* fd */) OVERRIDE {
99 NOTREACHED(); 100 NOTREACHED();
100 } 101 }
101 102
102 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE { 103 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE {
103 NOTREACHED(); 104 NOTREACHED();
104 } 105 }
105 106
106 protected: 107 protected:
107 MessagePumpLibevent::FileDescriptorWatcher* controller_; 108 MessagePumpIOSForIO::FileDescriptorWatcher* controller_;
108 }; 109 };
109 110
110 class DeleteWatcher : public BaseWatcher { 111 class DeleteWatcher : public BaseWatcher {
111 public: 112 public:
112 explicit DeleteWatcher( 113 explicit DeleteWatcher(
113 MessagePumpLibevent::FileDescriptorWatcher* controller) 114 MessagePumpIOSForIO::FileDescriptorWatcher* controller)
114 : BaseWatcher(controller) {} 115 : BaseWatcher(controller) {}
115 116
116 virtual ~DeleteWatcher() { 117 virtual ~DeleteWatcher() {
117 DCHECK(!controller_); 118 DCHECK(!controller_);
118 } 119 }
119 120
120 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE { 121 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE {
121 DCHECK(controller_); 122 DCHECK(controller_);
122 delete controller_; 123 delete controller_;
123 controller_ = NULL; 124 controller_ = NULL;
124 } 125 }
125 }; 126 };
126 127
127 TEST_F(MessagePumpLibeventTest, DeleteWatcher) { 128 TEST_F(MessagePumpIOSForIOTest, DeleteWatcher) {
128 scoped_refptr<MessagePumpLibevent> pump(new MessagePumpLibevent); 129 scoped_refptr<MessagePumpIOSForIO> pump(new MessagePumpIOSForIO);
129 MessagePumpLibevent::FileDescriptorWatcher* watcher = 130 MessagePumpIOSForIO::FileDescriptorWatcher* watcher =
130 new MessagePumpLibevent::FileDescriptorWatcher; 131 new MessagePumpIOSForIO::FileDescriptorWatcher;
131 DeleteWatcher delegate(watcher); 132 DeleteWatcher delegate(watcher);
132 pump->WatchFileDescriptor(pipefds_[1], 133 pump->WatchFileDescriptor(pipefds_[1],
133 false, MessagePumpLibevent::WATCH_READ_WRITE, watcher, &delegate); 134 false, MessagePumpIOSForIO::WATCH_READ_WRITE, watcher, &delegate);
134 135
135 // Spoof a libevent notification. 136 // Spoof a callback.
136 OnLibeventNotification(pump, watcher); 137 HandleFdIOEvent(watcher);
137 } 138 }
138 139
139 class StopWatcher : public BaseWatcher { 140 class StopWatcher : public BaseWatcher {
140 public: 141 public:
141 explicit StopWatcher( 142 StopWatcher(MessagePumpIOSForIO::FileDescriptorWatcher* controller,
142 MessagePumpLibevent::FileDescriptorWatcher* controller) 143 MessagePumpIOSForIO* pump,
143 : BaseWatcher(controller) {} 144 int fd_to_start_watching = -1)
145 : BaseWatcher(controller),
146 pump_(pump),
147 fd_to_start_watching_(fd_to_start_watching) {}
144 148
145 virtual ~StopWatcher() {} 149 virtual ~StopWatcher() {}
146 150
147 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE { 151 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE {
148 controller_->StopWatchingFileDescriptor(); 152 controller_->StopWatchingFileDescriptor();
153 if (fd_to_start_watching_ >= 0) {
154 pump_->WatchFileDescriptor(fd_to_start_watching_,
155 false, MessagePumpIOSForIO::WATCH_READ_WRITE, controller_, this);
156 }
149 } 157 }
158
159 private:
160 MessagePumpIOSForIO* pump_;
161 int fd_to_start_watching_;
150 }; 162 };
151 163
152 TEST_F(MessagePumpLibeventTest, StopWatcher) { 164 TEST_F(MessagePumpIOSForIOTest, StopWatcher) {
153 scoped_refptr<MessagePumpLibevent> pump(new MessagePumpLibevent); 165 scoped_refptr<MessagePumpIOSForIO> pump(new MessagePumpIOSForIO);
154 MessagePumpLibevent::FileDescriptorWatcher watcher; 166 MessagePumpIOSForIO::FileDescriptorWatcher watcher;
155 StopWatcher delegate(&watcher); 167 StopWatcher delegate(&watcher, pump);
156 pump->WatchFileDescriptor(pipefds_[1], 168 pump->WatchFileDescriptor(pipefds_[1],
157 false, MessagePumpLibevent::WATCH_READ_WRITE, &watcher, &delegate); 169 false, MessagePumpIOSForIO::WATCH_READ_WRITE, &watcher, &delegate);
158 170
159 // Spoof a libevent notification. 171 // Spoof a callback.
160 OnLibeventNotification(pump, &watcher); 172 HandleFdIOEvent(&watcher);
173 }
174
175 TEST_F(MessagePumpIOSForIOTest, StopWatcherAndWatchSomethingElse) {
176 scoped_refptr<MessagePumpIOSForIO> pump(new MessagePumpIOSForIO);
177 MessagePumpIOSForIO::FileDescriptorWatcher watcher;
178 StopWatcher delegate(&watcher, pump, alternate_pipefds_[1]);
179 pump->WatchFileDescriptor(pipefds_[1],
180 false, MessagePumpIOSForIO::WATCH_READ_WRITE, &watcher, &delegate);
181
182 // Spoof a callback.
183 HandleFdIOEvent(&watcher);
161 } 184 }
162 185
163 } // namespace 186 } // namespace
164 187
165 } // namespace base 188 } // namespace base
OLDNEW
« no previous file with comments | « base/message_pump_io_ios.cc ('k') | base/message_pump_libevent.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698