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

Side by Side Diff: message_loop/message_pump_libevent.cc

Issue 1921183002: Add a mechanism to extend a libevent based message pump. (Closed) Base URL: https://chromium.googlesource.com/external/github.com/domokit/base@master
Patch Set: added test case Created 4 years, 7 months 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 | « message_loop/message_pump_libevent.h ('k') | message_loop/message_pump_libevent_unittest.cc » ('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 (c) 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_loop/message_pump_libevent.h" 5 #include "base/message_loop/message_pump_libevent.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <unistd.h> 9 #include <unistd.h>
10 10
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 watcher_->OnFileCanWriteWithoutBlocking(fd); 112 watcher_->OnFileCanWriteWithoutBlocking(fd);
113 pump->DidProcessIOEvent(); 113 pump->DidProcessIOEvent();
114 } 114 }
115 115
116 MessagePumpLibevent::MessagePumpLibevent() 116 MessagePumpLibevent::MessagePumpLibevent()
117 : keep_running_(true), 117 : keep_running_(true),
118 in_run_(false), 118 in_run_(false),
119 processed_io_events_(false), 119 processed_io_events_(false),
120 event_base_(event_base_new()), 120 event_base_(event_base_new()),
121 wakeup_pipe_in_(-1), 121 wakeup_pipe_in_(-1),
122 wakeup_pipe_out_(-1) { 122 wakeup_pipe_out_(-1),
123 event_source_(nullptr) {
123 if (!Init()) 124 if (!Init())
124 NOTREACHED(); 125 NOTREACHED();
125 } 126 }
126 127
127 MessagePumpLibevent::~MessagePumpLibevent() { 128 MessagePumpLibevent::~MessagePumpLibevent() {
128 DCHECK(wakeup_event_); 129 DCHECK(wakeup_event_);
129 DCHECK(event_base_); 130 DCHECK(event_base_);
130 event_del(wakeup_event_); 131 event_del(wakeup_event_);
131 delete wakeup_event_; 132 delete wakeup_event_;
132 if (wakeup_pipe_in_ >= 0) { 133 if (wakeup_pipe_in_ >= 0) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 } 208 }
208 209
209 void MessagePumpLibevent::AddIOObserver(IOObserver *obs) { 210 void MessagePumpLibevent::AddIOObserver(IOObserver *obs) {
210 io_observers_.AddObserver(obs); 211 io_observers_.AddObserver(obs);
211 } 212 }
212 213
213 void MessagePumpLibevent::RemoveIOObserver(IOObserver *obs) { 214 void MessagePumpLibevent::RemoveIOObserver(IOObserver *obs) {
214 io_observers_.RemoveObserver(obs); 215 io_observers_.RemoveObserver(obs);
215 } 216 }
216 217
218 void MessagePumpLibevent::SetEventSource(EventSource* event_source) {
219 DCHECK(event_source);
220 DCHECK(!event_source_ || event_source_ == event_source);
221 event_source_ = event_source;
222 }
223
224 void MessagePumpLibevent::ClearEventSource() {
225 event_source_ = nullptr;
226 }
227
217 // Tell libevent to break out of inner loop. 228 // Tell libevent to break out of inner loop.
218 static void timer_callback(int fd, short events, void *context) 229 static void timer_callback(int fd, short events, void *context)
219 { 230 {
220 event_base_loopbreak((struct event_base *)context); 231 event_base_loopbreak((struct event_base *)context);
221 } 232 }
222 233
223 // Reentrant! 234 // Reentrant!
224 void MessagePumpLibevent::Run(Delegate* delegate) { 235 void MessagePumpLibevent::Run(Delegate* delegate) {
225 AutoReset<bool> auto_reset_keep_running(&keep_running_, true); 236 AutoReset<bool> auto_reset_keep_running(&keep_running_, true);
226 AutoReset<bool> auto_reset_in_run(&in_run_, true); 237 AutoReset<bool> auto_reset_in_run(&in_run_, true);
227 238
228 // event_base_loopexit() + EVLOOP_ONCE is leaky, see http://crbug.com/25641. 239 // event_base_loopexit() + EVLOOP_ONCE is leaky, see http://crbug.com/25641.
229 // Instead, make our own timer and reuse it on each call to event_base_loop(). 240 // Instead, make our own timer and reuse it on each call to event_base_loop().
230 scoped_ptr<event> timer_event(new event); 241 scoped_ptr<event> timer_event(new event);
231 242
232 for (;;) { 243 for (;;) {
233 #if defined(OS_MACOSX) 244 #if defined(OS_MACOSX)
234 mac::ScopedNSAutoreleasePool autorelease_pool; 245 mac::ScopedNSAutoreleasePool autorelease_pool;
235 #endif 246 #endif
236 247
237 bool did_work = delegate->DoWork(); 248 bool did_work = delegate->DoWork();
238 if (!keep_running_) 249 if (!keep_running_)
239 break; 250 break;
240 251
252 did_work |= PollEventSource();
253 if (!keep_running_)
254 break;
255
241 event_base_loop(event_base_, EVLOOP_NONBLOCK); 256 event_base_loop(event_base_, EVLOOP_NONBLOCK);
242 did_work |= processed_io_events_; 257 did_work |= processed_io_events_;
243 processed_io_events_ = false; 258 processed_io_events_ = false;
244 if (!keep_running_) 259 if (!keep_running_)
245 break; 260 break;
246 261
247 did_work |= delegate->DoDelayedWork(&delayed_work_time_); 262 did_work |= delegate->DoDelayedWork(&delayed_work_time_);
248 if (!keep_running_) 263 if (!keep_running_)
249 break; 264 break;
250 265
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 } 324 }
310 325
311 void MessagePumpLibevent::WillProcessIOEvent() { 326 void MessagePumpLibevent::WillProcessIOEvent() {
312 FOR_EACH_OBSERVER(IOObserver, io_observers_, WillProcessIOEvent()); 327 FOR_EACH_OBSERVER(IOObserver, io_observers_, WillProcessIOEvent());
313 } 328 }
314 329
315 void MessagePumpLibevent::DidProcessIOEvent() { 330 void MessagePumpLibevent::DidProcessIOEvent() {
316 FOR_EACH_OBSERVER(IOObserver, io_observers_, DidProcessIOEvent()); 331 FOR_EACH_OBSERVER(IOObserver, io_observers_, DidProcessIOEvent());
317 } 332 }
318 333
334 bool MessagePumpLibevent::PollEventSource() {
335 return event_source_ && event_source_->Poll();
336 }
337
319 bool MessagePumpLibevent::Init() { 338 bool MessagePumpLibevent::Init() {
320 int fds[2]; 339 int fds[2];
321 if (pipe(fds)) { 340 if (pipe(fds)) {
322 DLOG(ERROR) << "pipe() failed, errno: " << errno; 341 DLOG(ERROR) << "pipe() failed, errno: " << errno;
323 return false; 342 return false;
324 } 343 }
325 if (SetNonBlocking(fds[0])) { 344 if (SetNonBlocking(fds[0])) {
326 DLOG(ERROR) << "SetNonBlocking for pipe fd[0] failed, errno: " << errno; 345 DLOG(ERROR) << "SetNonBlocking for pipe fd[0] failed, errno: " << errno;
327 return false; 346 return false;
328 } 347 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 // Remove and discard the wakeup byte. 401 // Remove and discard the wakeup byte.
383 char buf; 402 char buf;
384 int nread = HANDLE_EINTR(read(socket, &buf, 1)); 403 int nread = HANDLE_EINTR(read(socket, &buf, 1));
385 DCHECK_EQ(nread, 1); 404 DCHECK_EQ(nread, 1);
386 that->processed_io_events_ = true; 405 that->processed_io_events_ = true;
387 // Tell libevent to break out of inner loop. 406 // Tell libevent to break out of inner loop.
388 event_base_loopbreak(that->event_base_); 407 event_base_loopbreak(that->event_base_);
389 } 408 }
390 409
391 } // namespace base 410 } // namespace base
OLDNEW
« no previous file with comments | « message_loop/message_pump_libevent.h ('k') | message_loop/message_pump_libevent_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698