| Index: base/message_pump_libevent.cc
|
| ===================================================================
|
| --- base/message_pump_libevent.cc (revision 14186)
|
| +++ base/message_pump_libevent.cc (working copy)
|
| @@ -9,9 +9,28 @@
|
|
|
| #include "base/logging.h"
|
| #include "base/scoped_nsautorelease_pool.h"
|
| +#include "base/scoped_ptr.h"
|
| #include "base/time.h"
|
| #include "third_party/libevent/event.h"
|
|
|
| +// Lifecycle of struct event
|
| +// Libevent uses two main data structures:
|
| +// struct event_base (of which there is one per message pump), and
|
| +// struct event (of which there is roughly one per socket).
|
| +// The socket's struct event is created in
|
| +// MessagePumpLibevent::WatchFileDescriptor(),
|
| +// is owned by the FileDescriptorWatcher, and is destroyed in
|
| +// StopWatchingFileDescriptor().
|
| +// It is moved into and out of lists in struct event_base by
|
| +// the libevent functions event_add() and event_del().
|
| +//
|
| +// TODO(dkegel):
|
| +// At the moment bad things happen if a FileDescriptorWatcher
|
| +// is active after its MessagePumpLibevent has been destroyed.
|
| +// See MessageLoopTest.FileDescriptorWatcherOutlivesMessageLoop
|
| +// Not clear yet whether that situation occurs in practice,
|
| +// but if it does, we need to fix it.
|
| +
|
| namespace base {
|
|
|
| // Return 0 on success
|
| @@ -29,7 +48,7 @@
|
| }
|
|
|
| MessagePumpLibevent::FileDescriptorWatcher::~FileDescriptorWatcher() {
|
| - if (event_.get()) {
|
| + if (event_) {
|
| StopWatchingFileDescriptor();
|
| }
|
| }
|
| @@ -37,23 +56,27 @@
|
| void MessagePumpLibevent::FileDescriptorWatcher::Init(event *e,
|
| bool is_persistent) {
|
| DCHECK(e);
|
| - DCHECK(event_.get() == NULL);
|
| + DCHECK(event_ == NULL);
|
|
|
| is_persistent_ = is_persistent;
|
| - event_.reset(e);
|
| + event_ = e;
|
| }
|
|
|
| event *MessagePumpLibevent::FileDescriptorWatcher::ReleaseEvent() {
|
| - return event_.release();
|
| + struct event *e = event_;
|
| + event_ = NULL;
|
| + return e;
|
| }
|
|
|
| bool MessagePumpLibevent::FileDescriptorWatcher::StopWatchingFileDescriptor() {
|
| - if (event_.get() == NULL) {
|
| + event* e = ReleaseEvent();
|
| + if (e == NULL)
|
| return true;
|
| - }
|
|
|
| - // event_del() is a no-op of the event isn't active.
|
| - return (event_del(event_.get()) == 0);
|
| + // event_del() is a no-op if the event isn't active.
|
| + int rv = event_del(e);
|
| + delete e;
|
| + return (rv == 0);
|
| }
|
|
|
| // Called if a byte is received on the wakeup pipe.
|
| @@ -169,7 +192,7 @@
|
| return false;
|
| }
|
|
|
| - // Transfer ownership of e to controller.
|
| + // Transfer ownership of evt to controller.
|
| controller->Init(evt.release(), persistent);
|
| return true;
|
| }
|
|
|