| 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 <fcntl.h> | 8 #include <fcntl.h> |
| 9 #include <unistd.h> | 9 #include <unistd.h> |
| 10 | 10 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 int flags = fcntl(fd, F_GETFL, 0); | 48 int flags = fcntl(fd, F_GETFL, 0); |
| 49 if (flags == -1) | 49 if (flags == -1) |
| 50 flags = 0; | 50 flags = 0; |
| 51 return fcntl(fd, F_SETFL, flags | O_NONBLOCK); | 51 return fcntl(fd, F_SETFL, flags | O_NONBLOCK); |
| 52 } | 52 } |
| 53 | 53 |
| 54 MessagePumpLibevent::FileDescriptorWatcher::FileDescriptorWatcher() | 54 MessagePumpLibevent::FileDescriptorWatcher::FileDescriptorWatcher() |
| 55 : event_(NULL), | 55 : event_(NULL), |
| 56 pump_(NULL), | 56 pump_(NULL), |
| 57 watcher_(NULL), | 57 watcher_(NULL), |
| 58 weak_factory_(this) { | 58 was_destroyed_(NULL) { |
| 59 } | 59 } |
| 60 | 60 |
| 61 MessagePumpLibevent::FileDescriptorWatcher::~FileDescriptorWatcher() { | 61 MessagePumpLibevent::FileDescriptorWatcher::~FileDescriptorWatcher() { |
| 62 if (event_) { | 62 if (event_) { |
| 63 StopWatchingFileDescriptor(); | 63 StopWatchingFileDescriptor(); |
| 64 } | 64 } |
| 65 if (was_destroyed_) { |
| 66 DCHECK(!*was_destroyed_); |
| 67 *was_destroyed_ = true; |
| 68 } |
| 65 } | 69 } |
| 66 | 70 |
| 67 bool MessagePumpLibevent::FileDescriptorWatcher::StopWatchingFileDescriptor() { | 71 bool MessagePumpLibevent::FileDescriptorWatcher::StopWatchingFileDescriptor() { |
| 68 event* e = ReleaseEvent(); | 72 event* e = ReleaseEvent(); |
| 69 if (e == NULL) | 73 if (e == NULL) |
| 70 return true; | 74 return true; |
| 71 | 75 |
| 72 // event_del() is a no-op if the event isn't active. | 76 // event_del() is a no-op if the event isn't active. |
| 73 int rv = event_del(e); | 77 int rv = event_del(e); |
| 74 delete e; | 78 delete e; |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 333 event_set(wakeup_event_, wakeup_pipe_out_, EV_READ | EV_PERSIST, | 337 event_set(wakeup_event_, wakeup_pipe_out_, EV_READ | EV_PERSIST, |
| 334 OnWakeup, this); | 338 OnWakeup, this); |
| 335 event_base_set(event_base_, wakeup_event_); | 339 event_base_set(event_base_, wakeup_event_); |
| 336 | 340 |
| 337 if (event_add(wakeup_event_, 0)) | 341 if (event_add(wakeup_event_, 0)) |
| 338 return false; | 342 return false; |
| 339 return true; | 343 return true; |
| 340 } | 344 } |
| 341 | 345 |
| 342 // static | 346 // static |
| 343 void MessagePumpLibevent::OnLibeventNotification(int fd, short flags, | 347 void MessagePumpLibevent::OnLibeventNotification(int fd, |
| 348 short flags, |
| 344 void* context) { | 349 void* context) { |
| 345 WeakPtr<FileDescriptorWatcher> controller = | 350 FileDescriptorWatcher* controller = |
| 346 static_cast<FileDescriptorWatcher*>(context)->weak_factory_.GetWeakPtr(); | 351 static_cast<FileDescriptorWatcher*>(context); |
| 347 DCHECK(controller.get()); | 352 DCHECK(controller); |
| 348 TRACE_EVENT1("toplevel", "MessagePumpLibevent::OnLibeventNotification", | 353 TRACE_EVENT1("toplevel", "MessagePumpLibevent::OnLibeventNotification", |
| 349 "fd", fd); | 354 "fd", fd); |
| 350 | 355 |
| 351 MessagePumpLibevent* pump = controller->pump(); | 356 MessagePumpLibevent* pump = controller->pump(); |
| 352 pump->processed_io_events_ = true; | 357 pump->processed_io_events_ = true; |
| 353 | 358 |
| 354 if (flags & EV_WRITE) { | 359 if ((flags & (EV_READ | EV_WRITE)) == (EV_READ | EV_WRITE)) { |
| 360 // Both callbacks will be called. It is necessary to check that |controller| |
| 361 // is not destroyed. |
| 362 bool controller_was_destroyed = false; |
| 363 controller->was_destroyed_ = &controller_was_destroyed; |
| 355 controller->OnFileCanWriteWithoutBlocking(fd, pump); | 364 controller->OnFileCanWriteWithoutBlocking(fd, pump); |
| 356 } | 365 if (!controller_was_destroyed) |
| 357 // Check |controller| in case it's been deleted in | 366 controller->OnFileCanReadWithoutBlocking(fd, pump); |
| 358 // controller->OnFileCanWriteWithoutBlocking(). | 367 if (!controller_was_destroyed) |
| 359 if (controller.get() && flags & EV_READ) { | 368 controller->was_destroyed_ = nullptr; |
| 369 } else if (flags & EV_WRITE) { |
| 370 controller->OnFileCanWriteWithoutBlocking(fd, pump); |
| 371 } else if (flags & EV_READ) { |
| 360 controller->OnFileCanReadWithoutBlocking(fd, pump); | 372 controller->OnFileCanReadWithoutBlocking(fd, pump); |
| 361 } | 373 } |
| 362 } | 374 } |
| 363 | 375 |
| 364 // Called if a byte is received on the wakeup pipe. | 376 // Called if a byte is received on the wakeup pipe. |
| 365 // static | 377 // static |
| 366 void MessagePumpLibevent::OnWakeup(int socket, short flags, void* context) { | 378 void MessagePumpLibevent::OnWakeup(int socket, short flags, void* context) { |
| 367 MessagePumpLibevent* that = static_cast<MessagePumpLibevent*>(context); | 379 MessagePumpLibevent* that = static_cast<MessagePumpLibevent*>(context); |
| 368 DCHECK(that->wakeup_pipe_out_ == socket); | 380 DCHECK(that->wakeup_pipe_out_ == socket); |
| 369 | 381 |
| 370 // Remove and discard the wakeup byte. | 382 // Remove and discard the wakeup byte. |
| 371 char buf; | 383 char buf; |
| 372 int nread = HANDLE_EINTR(read(socket, &buf, 1)); | 384 int nread = HANDLE_EINTR(read(socket, &buf, 1)); |
| 373 DCHECK_EQ(nread, 1); | 385 DCHECK_EQ(nread, 1); |
| 374 that->processed_io_events_ = true; | 386 that->processed_io_events_ = true; |
| 375 // Tell libevent to break out of inner loop. | 387 // Tell libevent to break out of inner loop. |
| 376 event_base_loopbreak(that->event_base_); | 388 event_base_loopbreak(that->event_base_); |
| 377 } | 389 } |
| 378 | 390 |
| 379 } // namespace base | 391 } // namespace base |
| OLD | NEW |