| OLD | NEW |
| 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 <unistd.h> | 8 #include <unistd.h> |
| 9 | 9 |
| 10 #include <memory> | 10 #include <memory> |
| 11 | 11 |
| 12 #include "base/auto_reset.h" | 12 #include "base/auto_reset.h" |
| 13 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
| 14 #include "base/files/file_util.h" | 14 #include "base/files/file_util.h" |
| 15 #include "base/logging.h" | 15 #include "base/logging.h" |
| 16 #include "base/observer_list.h" | |
| 17 #include "base/posix/eintr_wrapper.h" | 16 #include "base/posix/eintr_wrapper.h" |
| 18 #include "base/third_party/libevent/event.h" | 17 #include "base/third_party/libevent/event.h" |
| 19 #include "base/time/time.h" | 18 #include "base/time/time.h" |
| 20 #include "base/trace_event/trace_event.h" | 19 #include "base/trace_event/trace_event.h" |
| 21 #include "build/build_config.h" | 20 #include "build/build_config.h" |
| 22 | 21 |
| 23 #if defined(OS_MACOSX) | 22 #if defined(OS_MACOSX) |
| 24 #include "base/mac/scoped_nsautorelease_pool.h" | 23 #include "base/mac/scoped_nsautorelease_pool.h" |
| 25 #endif | 24 #endif |
| 26 | 25 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 event_ = NULL; | 85 event_ = NULL; |
| 87 return e; | 86 return e; |
| 88 } | 87 } |
| 89 | 88 |
| 90 void MessagePumpLibevent::FileDescriptorWatcher::OnFileCanReadWithoutBlocking( | 89 void MessagePumpLibevent::FileDescriptorWatcher::OnFileCanReadWithoutBlocking( |
| 91 int fd, MessagePumpLibevent* pump) { | 90 int fd, MessagePumpLibevent* pump) { |
| 92 // Since OnFileCanWriteWithoutBlocking() gets called first, it can stop | 91 // Since OnFileCanWriteWithoutBlocking() gets called first, it can stop |
| 93 // watching the file descriptor. | 92 // watching the file descriptor. |
| 94 if (!watcher_) | 93 if (!watcher_) |
| 95 return; | 94 return; |
| 96 pump->WillProcessIOEvent(); | |
| 97 watcher_->OnFileCanReadWithoutBlocking(fd); | 95 watcher_->OnFileCanReadWithoutBlocking(fd); |
| 98 pump->DidProcessIOEvent(); | |
| 99 } | 96 } |
| 100 | 97 |
| 101 void MessagePumpLibevent::FileDescriptorWatcher::OnFileCanWriteWithoutBlocking( | 98 void MessagePumpLibevent::FileDescriptorWatcher::OnFileCanWriteWithoutBlocking( |
| 102 int fd, MessagePumpLibevent* pump) { | 99 int fd, MessagePumpLibevent* pump) { |
| 103 DCHECK(watcher_); | 100 DCHECK(watcher_); |
| 104 pump->WillProcessIOEvent(); | |
| 105 watcher_->OnFileCanWriteWithoutBlocking(fd); | 101 watcher_->OnFileCanWriteWithoutBlocking(fd); |
| 106 pump->DidProcessIOEvent(); | |
| 107 } | 102 } |
| 108 | 103 |
| 109 MessagePumpLibevent::MessagePumpLibevent() | 104 MessagePumpLibevent::MessagePumpLibevent() |
| 110 : keep_running_(true), | 105 : keep_running_(true), |
| 111 in_run_(false), | 106 in_run_(false), |
| 112 processed_io_events_(false), | 107 processed_io_events_(false), |
| 113 event_base_(event_base_new()), | 108 event_base_(event_base_new()), |
| 114 wakeup_pipe_in_(-1), | 109 wakeup_pipe_in_(-1), |
| 115 wakeup_pipe_out_(-1) { | 110 wakeup_pipe_out_(-1) { |
| 116 if (!Init()) | 111 if (!Init()) |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 | 187 |
| 193 // Transfer ownership of evt to controller. | 188 // Transfer ownership of evt to controller. |
| 194 controller->Init(evt.release()); | 189 controller->Init(evt.release()); |
| 195 | 190 |
| 196 controller->set_watcher(delegate); | 191 controller->set_watcher(delegate); |
| 197 controller->set_pump(this); | 192 controller->set_pump(this); |
| 198 | 193 |
| 199 return true; | 194 return true; |
| 200 } | 195 } |
| 201 | 196 |
| 202 void MessagePumpLibevent::AddIOObserver(IOObserver *obs) { | |
| 203 io_observers_.AddObserver(obs); | |
| 204 } | |
| 205 | |
| 206 void MessagePumpLibevent::RemoveIOObserver(IOObserver *obs) { | |
| 207 io_observers_.RemoveObserver(obs); | |
| 208 } | |
| 209 | |
| 210 // Tell libevent to break out of inner loop. | 197 // Tell libevent to break out of inner loop. |
| 211 static void timer_callback(int fd, short events, void *context) | 198 static void timer_callback(int fd, short events, void *context) |
| 212 { | 199 { |
| 213 event_base_loopbreak((struct event_base *)context); | 200 event_base_loopbreak((struct event_base *)context); |
| 214 } | 201 } |
| 215 | 202 |
| 216 // Reentrant! | 203 // Reentrant! |
| 217 void MessagePumpLibevent::Run(Delegate* delegate) { | 204 void MessagePumpLibevent::Run(Delegate* delegate) { |
| 218 AutoReset<bool> auto_reset_keep_running(&keep_running_, true); | 205 AutoReset<bool> auto_reset_keep_running(&keep_running_, true); |
| 219 AutoReset<bool> auto_reset_in_run(&in_run_, true); | 206 AutoReset<bool> auto_reset_in_run(&in_run_, true); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 } | 281 } |
| 295 | 282 |
| 296 void MessagePumpLibevent::ScheduleDelayedWork( | 283 void MessagePumpLibevent::ScheduleDelayedWork( |
| 297 const TimeTicks& delayed_work_time) { | 284 const TimeTicks& delayed_work_time) { |
| 298 // We know that we can't be blocked on Wait right now since this method can | 285 // We know that we can't be blocked on Wait right now since this method can |
| 299 // only be called on the same thread as Run, so we only need to update our | 286 // only be called on the same thread as Run, so we only need to update our |
| 300 // record of how long to sleep when we do sleep. | 287 // record of how long to sleep when we do sleep. |
| 301 delayed_work_time_ = delayed_work_time; | 288 delayed_work_time_ = delayed_work_time; |
| 302 } | 289 } |
| 303 | 290 |
| 304 void MessagePumpLibevent::WillProcessIOEvent() { | |
| 305 FOR_EACH_OBSERVER(IOObserver, io_observers_, WillProcessIOEvent()); | |
| 306 } | |
| 307 | |
| 308 void MessagePumpLibevent::DidProcessIOEvent() { | |
| 309 FOR_EACH_OBSERVER(IOObserver, io_observers_, DidProcessIOEvent()); | |
| 310 } | |
| 311 | |
| 312 bool MessagePumpLibevent::Init() { | 291 bool MessagePumpLibevent::Init() { |
| 313 int fds[2]; | 292 int fds[2]; |
| 314 if (pipe(fds)) { | 293 if (pipe(fds)) { |
| 315 DLOG(ERROR) << "pipe() failed, errno: " << errno; | 294 DLOG(ERROR) << "pipe() failed, errno: " << errno; |
| 316 return false; | 295 return false; |
| 317 } | 296 } |
| 318 if (!SetNonBlocking(fds[0])) { | 297 if (!SetNonBlocking(fds[0])) { |
| 319 DLOG(ERROR) << "SetNonBlocking for pipe fd[0] failed, errno: " << errno; | 298 DLOG(ERROR) << "SetNonBlocking for pipe fd[0] failed, errno: " << errno; |
| 320 return false; | 299 return false; |
| 321 } | 300 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 375 // Remove and discard the wakeup byte. | 354 // Remove and discard the wakeup byte. |
| 376 char buf; | 355 char buf; |
| 377 int nread = HANDLE_EINTR(read(socket, &buf, 1)); | 356 int nread = HANDLE_EINTR(read(socket, &buf, 1)); |
| 378 DCHECK_EQ(nread, 1); | 357 DCHECK_EQ(nread, 1); |
| 379 that->processed_io_events_ = true; | 358 that->processed_io_events_ = true; |
| 380 // Tell libevent to break out of inner loop. | 359 // Tell libevent to break out of inner loop. |
| 381 event_base_loopbreak(that->event_base_); | 360 event_base_loopbreak(that->event_base_); |
| 382 } | 361 } |
| 383 | 362 |
| 384 } // namespace base | 363 } // namespace base |
| OLD | NEW |