Revert 206507 "Move message_pump to base/message_loop."
> Move message_pump to base/message_loop.
>
> This also fixes some namespace usage inside the message pump files and updates all users of these files to use the new location.
>
> BUG=
> R=sky@chromium.org
>
> Review URL: https://codereview.chromium.org/17078005
TBR=brettw@chromium.org
Review URL: https://codereview.chromium.org/16897005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@206513 0039d316-1c4b-4281-b951-d872f2087c98
CrOS-Libchrome-Original-Commit: 9bf0b36044584756132943f37a06f2fcaef7e5fb
diff --git a/base/message_loop/message_loop.cc b/base/message_loop/message_loop.cc
index 4e0c5f6..0364a52 100644
--- a/base/message_loop/message_loop.cc
+++ b/base/message_loop/message_loop.cc
@@ -14,7 +14,7 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop_proxy_impl.h"
-#include "base/message_loop/message_pump_default.h"
+#include "base/message_pump_default.h"
#include "base/metrics/histogram.h"
#include "base/metrics/statistics_recorder.h"
#include "base/run_loop.h"
@@ -25,13 +25,13 @@
#include "base/tracked_objects.h"
#if defined(OS_MACOSX)
-#include "base/message_loop/message_pump_mac.h"
+#include "base/message_pump_mac.h"
#endif
#if defined(OS_POSIX) && !defined(OS_IOS)
-#include "base/message_loop/message_pump_libevent.h"
+#include "base/message_pump_libevent.h"
#endif
#if defined(OS_ANDROID)
-#include "base/message_loop/message_pump_android.h"
+#include "base/message_pump_android.h"
#endif
#if defined(TOOLKIT_GTK)
diff --git a/base/message_loop/message_loop.h b/base/message_loop/message_loop.h
index e765cef..d26b673 100644
--- a/base/message_loop/message_loop.h
+++ b/base/message_loop/message_loop.h
@@ -14,7 +14,7 @@
#include "base/location.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop_proxy.h"
-#include "base/message_loop/message_pump.h"
+#include "base/message_pump.h"
#include "base/observer_list.h"
#include "base/pending_task.h"
#include "base/sequenced_task_runner_helpers.h"
@@ -25,26 +25,25 @@
#if defined(OS_WIN)
// We need this to declare base::MessagePumpWin::Dispatcher, which we should
// really just eliminate.
-#include "base/message_loop/message_pump_win.h"
+#include "base/message_pump_win.h"
#elif defined(OS_IOS)
-#include "base/message_loop/message_pump_io_ios.h"
+#include "base/message_pump_io_ios.h"
#elif defined(OS_POSIX)
-#include "base/message_loop/message_pump_libevent.h"
+#include "base/message_pump_libevent.h"
#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
#if defined(USE_AURA) && defined(USE_X11) && !defined(OS_NACL)
-#include "base/message_loop/message_pump_aurax11.h"
+#include "base/message_pump_aurax11.h"
#elif defined(USE_OZONE) && !defined(OS_NACL)
-#include "base/message_loop/message_pump_ozone.h"
+#include "base/message_pump_ozone.h"
#else
-#include "base/message_loop/message_pump_gtk.h"
+#include "base/message_pump_gtk.h"
#endif
#endif
#endif
namespace base {
-
class HistogramBase;
class MessageLoopLockTest;
class RunLoop;
@@ -84,12 +83,12 @@
// Please be SURE your task is reentrant (nestable) and all global variables
// are stable and accessible before calling SetNestableTasksAllowed(true).
//
-class BASE_EXPORT MessageLoop : public MessagePump::Delegate {
+class BASE_EXPORT MessageLoop : public base::MessagePump::Delegate {
public:
#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
- typedef MessagePumpDispatcher Dispatcher;
- typedef MessagePumpObserver Observer;
+ typedef base::MessagePumpDispatcher Dispatcher;
+ typedef base::MessagePumpObserver Observer;
#endif
// A MessageLoop has a particular type, which indicates the set of
@@ -122,7 +121,7 @@
static void EnableHistogrammer(bool enable_histogrammer);
- typedef MessagePump* (MessagePumpFactory)();
+ typedef base::MessagePump* (MessagePumpFactory)();
// Uses the given base::MessagePumpForUIFactory to override the default
// MessagePump implementation for 'TYPE_UI'. Returns true if the factory
// was successfully registered.
@@ -175,22 +174,27 @@
//
// NOTE: These methods may be called on any thread. The Task will be invoked
// on the thread that executes MessageLoop::Run().
- void PostTask(const tracked_objects::Location& from_here,
- const Closure& task);
+ void PostTask(
+ const tracked_objects::Location& from_here,
+ const base::Closure& task);
- bool TryPostTask(const tracked_objects::Location& from_here,
- const Closure& task);
+ bool TryPostTask(
+ const tracked_objects::Location& from_here,
+ const base::Closure& task);
- void PostDelayedTask(const tracked_objects::Location& from_here,
- const Closure& task,
- TimeDelta delay);
+ void PostDelayedTask(
+ const tracked_objects::Location& from_here,
+ const base::Closure& task,
+ base::TimeDelta delay);
- void PostNonNestableTask(const tracked_objects::Location& from_here,
- const Closure& task);
+ void PostNonNestableTask(
+ const tracked_objects::Location& from_here,
+ const base::Closure& task);
- void PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
- const Closure& task,
- TimeDelta delay);
+ void PostNonNestableDelayedTask(
+ const tracked_objects::Location& from_here,
+ const base::Closure& task,
+ base::TimeDelta delay);
// A variant on PostTask that deletes the given object. This is useful
// if the object needs to live until the next run of the MessageLoop (for
@@ -260,12 +264,12 @@
void QuitNow();
// TODO(jbates) remove this. crbug.com/131220. See QuitWhenIdleClosure().
- static Closure QuitClosure() { return QuitWhenIdleClosure(); }
+ static base::Closure QuitClosure() { return QuitWhenIdleClosure(); }
// Deprecated: use RunLoop instead.
// Construct a Closure that will call QuitWhenIdle(). Useful to schedule an
// arbitrary MessageLoop to QuitWhenIdle.
- static Closure QuitWhenIdleClosure();
+ static base::Closure QuitWhenIdleClosure();
// Returns true if this loop is |type|. This allows subclasses (especially
// those in tests) to specialize how they are identified.
@@ -282,7 +286,7 @@
const std::string& thread_name() const { return thread_name_; }
// Gets the message loop proxy associated with this message loop.
- scoped_refptr<MessageLoopProxy> message_loop_proxy() {
+ scoped_refptr<base::MessageLoopProxy> message_loop_proxy() {
return message_loop_proxy_.get();
}
@@ -345,10 +349,10 @@
TaskObserver();
// This method is called before processing a task.
- virtual void WillProcessTask(const PendingTask& pending_task) = 0;
+ virtual void WillProcessTask(const base::PendingTask& pending_task) = 0;
// This method is called after processing a task.
- virtual void DidProcessTask(const PendingTask& pending_task) = 0;
+ virtual void DidProcessTask(const base::PendingTask& pending_task) = 0;
protected:
virtual ~TaskObserver();
@@ -393,20 +397,20 @@
protected:
#if defined(OS_WIN)
- MessagePumpWin* pump_win() {
- return static_cast<MessagePumpWin*>(pump_.get());
+ base::MessagePumpWin* pump_win() {
+ return static_cast<base::MessagePumpWin*>(pump_.get());
}
#elif defined(OS_POSIX) && !defined(OS_IOS)
- MessagePumpLibevent* pump_libevent() {
- return static_cast<MessagePumpLibevent*>(pump_.get());
+ base::MessagePumpLibevent* pump_libevent() {
+ return static_cast<base::MessagePumpLibevent*>(pump_.get());
}
#endif
- scoped_refptr<MessagePump> pump_;
+ scoped_refptr<base::MessagePump> pump_;
private:
- friend class RunLoop;
- friend class MessageLoopLockTest;
+ friend class base::RunLoop;
+ friend class base::MessageLoopLockTest;
// A function to encapsulate all the exception handling capability in the
// stacks around the running of a main message loop. It will run the message
@@ -427,14 +431,14 @@
bool ProcessNextDelayedNonNestableTask();
// Runs the specified PendingTask.
- void RunTask(const PendingTask& pending_task);
+ void RunTask(const base::PendingTask& pending_task);
// Calls RunTask or queues the pending_task on the deferred task list if it
// cannot be run right now. Returns true if the task was run.
- bool DeferOrRunPendingTask(const PendingTask& pending_task);
+ bool DeferOrRunPendingTask(const base::PendingTask& pending_task);
// Adds the pending task to delayed_work_queue_.
- void AddToDelayedWorkQueue(const PendingTask& pending_task);
+ void AddToDelayedWorkQueue(const base::PendingTask& pending_task);
// This function attempts to add pending task to our incoming_queue_.
// The append can only possibly fail when |use_try_lock| is true.
@@ -450,7 +454,7 @@
// function will reset the value of pending_task->task. This is needed to
// ensure that the posting call stack does not retain pending_task->task
// beyond this function call.
- bool AddToIncomingQueue(PendingTask* pending_task, bool use_try_lock);
+ bool AddToIncomingQueue(base::PendingTask* pending_task, bool use_try_lock);
// Load tasks from the incoming_queue_ into work_queue_ if the latter is
// empty. The former requires a lock to access, while the latter is directly
@@ -463,7 +467,7 @@
bool DeletePendingTasks();
// Calculates the time at which a PendingTask should run.
- TimeTicks CalculateDelayedRuntime(TimeDelta delay);
+ base::TimeTicks CalculateDelayedRuntime(base::TimeDelta delay);
// Start recording histogram info about events and action IF it was enabled
// and IF the statistics recorder can accept a registration of our histogram.
@@ -474,27 +478,27 @@
// If message_histogram_ is NULL, this is a no-op.
void HistogramEvent(int event);
- // MessagePump::Delegate methods:
+ // base::MessagePump::Delegate methods:
virtual bool DoWork() OVERRIDE;
- virtual bool DoDelayedWork(TimeTicks* next_delayed_work_time) OVERRIDE;
+ virtual bool DoDelayedWork(base::TimeTicks* next_delayed_work_time) OVERRIDE;
virtual bool DoIdleWork() OVERRIDE;
Type type_;
// A list of tasks that need to be processed by this instance. Note that
// this queue is only accessed (push/pop) by our current thread.
- TaskQueue work_queue_;
+ base::TaskQueue work_queue_;
// Contains delayed tasks, sorted by their 'delayed_run_time' property.
- DelayedTaskQueue delayed_work_queue_;
+ base::DelayedTaskQueue delayed_work_queue_;
// A recent snapshot of Time::Now(), used to check delayed_work_queue_.
- TimeTicks recent_time_;
+ base::TimeTicks recent_time_;
// A queue of non-nestable tasks that we had to defer because when it came
// time to execute them we were in a nested message loop. They will execute
// once we're out of nested message loops.
- TaskQueue deferred_non_nestable_work_queue_;
+ base::TaskQueue deferred_non_nestable_work_queue_;
ObserverList<DestructionObserver> destruction_observers_;
@@ -506,19 +510,19 @@
std::string thread_name_;
// A profiling histogram showing the counts of various messages and events.
- HistogramBase* message_histogram_;
+ base::HistogramBase* message_histogram_;
// An incoming queue of tasks that are acquired under a mutex for processing
// on this instance's thread. These tasks have not yet been sorted out into
// items for our work_queue_ vs delayed_work_queue_.
- TaskQueue incoming_queue_;
+ base::TaskQueue incoming_queue_;
// Protect access to incoming_queue_.
- mutable Lock incoming_queue_lock_;
+ mutable base::Lock incoming_queue_lock_;
- RunLoop* run_loop_;
+ base::RunLoop* run_loop_;
#if defined(OS_WIN)
- TimeTicks high_resolution_timer_expiration_;
+ base::TimeTicks high_resolution_timer_expiration_;
// Should be set to true before calling Windows APIs like TrackPopupMenu, etc
// which enter a modal message loop.
bool os_modal_loop_;
@@ -531,8 +535,8 @@
ObserverList<TaskObserver> task_observers_;
// The message loop proxy associated with this message loop, if one exists.
- scoped_refptr<MessageLoopProxy> message_loop_proxy_;
- scoped_ptr<ThreadTaskRunnerHandle> thread_task_runner_handle_;
+ scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
+ scoped_ptr<base::ThreadTaskRunnerHandle> thread_task_runner_handle_;
template <class T, class R> friend class base::subtle::DeleteHelperInternal;
template <class T, class R> friend class base::subtle::ReleaseHelperInternal;
@@ -557,7 +561,7 @@
class BASE_EXPORT MessageLoopForUI : public MessageLoop {
public:
#if defined(OS_WIN)
- typedef MessagePumpForUI::MessageFilter MessageFilter;
+ typedef base::MessagePumpForUI::MessageFilter MessageFilter;
#endif
MessageLoopForUI() : MessageLoop(TYPE_UI) {
@@ -603,15 +607,15 @@
protected:
#if defined(USE_AURA) && defined(USE_X11) && !defined(OS_NACL)
- friend class MessagePumpAuraX11;
+ friend class base::MessagePumpAuraX11;
#endif
#if defined(USE_OZONE) && !defined(OS_NACL)
- friend class MessagePumpOzone;
+ friend class base::MessagePumpOzone;
#endif
// TODO(rvargas): Make this platform independent.
- MessagePumpForUI* pump_ui() {
- return static_cast<MessagePumpForUI*>(pump_.get());
+ base::MessagePumpForUI* pump_ui() {
+ return static_cast<base::MessagePumpForUI*>(pump_.get());
}
#endif // !defined(OS_MACOSX)
};
@@ -632,30 +636,30 @@
class BASE_EXPORT MessageLoopForIO : public MessageLoop {
public:
#if defined(OS_WIN)
- typedef MessagePumpForIO::IOHandler IOHandler;
- typedef MessagePumpForIO::IOContext IOContext;
- typedef MessagePumpForIO::IOObserver IOObserver;
+ typedef base::MessagePumpForIO::IOHandler IOHandler;
+ typedef base::MessagePumpForIO::IOContext IOContext;
+ typedef base::MessagePumpForIO::IOObserver IOObserver;
#elif defined(OS_IOS)
- typedef MessagePumpIOSForIO::Watcher Watcher;
- typedef MessagePumpIOSForIO::FileDescriptorWatcher
+ typedef base::MessagePumpIOSForIO::Watcher Watcher;
+ typedef base::MessagePumpIOSForIO::FileDescriptorWatcher
FileDescriptorWatcher;
- typedef MessagePumpIOSForIO::IOObserver IOObserver;
+ typedef base::MessagePumpIOSForIO::IOObserver IOObserver;
enum Mode {
- WATCH_READ = MessagePumpIOSForIO::WATCH_READ,
- WATCH_WRITE = MessagePumpIOSForIO::WATCH_WRITE,
- WATCH_READ_WRITE = MessagePumpIOSForIO::WATCH_READ_WRITE
+ WATCH_READ = base::MessagePumpIOSForIO::WATCH_READ,
+ WATCH_WRITE = base::MessagePumpIOSForIO::WATCH_WRITE,
+ WATCH_READ_WRITE = base::MessagePumpIOSForIO::WATCH_READ_WRITE
};
#elif defined(OS_POSIX)
- typedef MessagePumpLibevent::Watcher Watcher;
- typedef MessagePumpLibevent::FileDescriptorWatcher
+ typedef base::MessagePumpLibevent::Watcher Watcher;
+ typedef base::MessagePumpLibevent::FileDescriptorWatcher
FileDescriptorWatcher;
- typedef MessagePumpLibevent::IOObserver IOObserver;
+ typedef base::MessagePumpLibevent::IOObserver IOObserver;
enum Mode {
- WATCH_READ = MessagePumpLibevent::WATCH_READ,
- WATCH_WRITE = MessagePumpLibevent::WATCH_WRITE,
- WATCH_READ_WRITE = MessagePumpLibevent::WATCH_READ_WRITE
+ WATCH_READ = base::MessagePumpLibevent::WATCH_READ,
+ WATCH_WRITE = base::MessagePumpLibevent::WATCH_WRITE,
+ WATCH_READ_WRITE = base::MessagePumpLibevent::WATCH_READ_WRITE
};
#endif
@@ -686,8 +690,8 @@
protected:
// TODO(rvargas): Make this platform independent.
- MessagePumpForIO* pump_io() {
- return static_cast<MessagePumpForIO*>(pump_.get());
+ base::MessagePumpForIO* pump_io() {
+ return static_cast<base::MessagePumpForIO*>(pump_.get());
}
#elif defined(OS_IOS)
@@ -699,8 +703,8 @@
Watcher *delegate);
private:
- MessagePumpIOSForIO* pump_io() {
- return static_cast<MessagePumpIOSForIO*>(pump_.get());
+ base::MessagePumpIOSForIO* pump_io() {
+ return static_cast<base::MessagePumpIOSForIO*>(pump_.get());
}
#elif defined(OS_POSIX)
@@ -712,8 +716,8 @@
Watcher* delegate);
private:
- MessagePumpLibevent* pump_io() {
- return static_cast<MessagePumpLibevent*>(pump_.get());
+ base::MessagePumpLibevent* pump_io() {
+ return static_cast<base::MessagePumpLibevent*>(pump_.get());
}
#endif // defined(OS_POSIX)
};
diff --git a/base/message_loop/message_loop_unittest.cc b/base/message_loop/message_loop_unittest.cc
index 504c8e3..0f85b14 100644
--- a/base/message_loop/message_loop_unittest.cc
+++ b/base/message_loop/message_loop_unittest.cc
@@ -9,7 +9,7 @@
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
-#include "base/message_loop/message_loop.h"
+#include "base/message_loop.h"
#include "base/pending_task.h"
#include "base/posix/eintr_wrapper.h"
#include "base/run_loop.h"
@@ -20,7 +20,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#if defined(OS_WIN)
-#include "base/message_loop/message_pump_win.h"
+#include "base/message_pump_win.h"
#include "base/win/scoped_handle.h"
#endif
@@ -29,8 +29,8 @@
class MessageLoopLockTest {
public:
static void LockWaitUnLock(MessageLoop* loop,
- WaitableEvent* caller_wait,
- WaitableEvent* caller_signal) {
+ base::WaitableEvent* caller_wait,
+ base::WaitableEvent* caller_signal) {
loop->incoming_queue_lock_.Acquire();
caller_wait->Signal();
@@ -121,7 +121,7 @@
thread.Start();
thread.message_loop()->PostTask(
FROM_HERE,
- Bind(&MessageLoopLockTest::LockWaitUnLock,
+ base::Bind(&MessageLoopLockTest::LockWaitUnLock,
MessageLoop::current(),
&wait,
&signal));
@@ -1419,7 +1419,7 @@
#if defined(OS_WIN)
-class DispatcherImpl : public MessageLoopForUI::Dispatcher {
+class DispatcherImpl : public base::MessageLoopForUI::Dispatcher {
public:
DispatcherImpl() : dispatch_count_(0) {}
diff --git a/base/message_loop/message_pump.cc b/base/message_loop/message_pump.cc
deleted file mode 100644
index 7ffc2b1..0000000
--- a/base/message_loop/message_pump.cc
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/message_loop/message_pump.h"
-
-namespace base {
-
-MessagePump::MessagePump() {
-}
-
-MessagePump::~MessagePump() {
-}
-
-} // namespace base
diff --git a/base/message_loop/message_pump.h b/base/message_loop/message_pump.h
deleted file mode 100644
index 5b72232..0000000
--- a/base/message_loop/message_pump.h
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_MESSAGE_LOOP_MESSAGE_PUMP_H_
-#define BASE_MESSAGE_LOOP_MESSAGE_PUMP_H_
-
-#include "base/base_export.h"
-#include "base/memory/ref_counted.h"
-
-namespace base {
-
-class TimeTicks;
-
-class BASE_EXPORT MessagePump : public RefCountedThreadSafe<MessagePump> {
- public:
- // Please see the comments above the Run method for an illustration of how
- // these delegate methods are used.
- class BASE_EXPORT Delegate {
- public:
- virtual ~Delegate() {}
-
- // Called from within Run in response to ScheduleWork or when the message
- // pump would otherwise call DoDelayedWork. Returns true to indicate that
- // work was done. DoDelayedWork will still be called if DoWork returns
- // true, but DoIdleWork will not.
- virtual bool DoWork() = 0;
-
- // Called from within Run in response to ScheduleDelayedWork or when the
- // message pump would otherwise sleep waiting for more work. Returns true
- // to indicate that delayed work was done. DoIdleWork will not be called
- // if DoDelayedWork returns true. Upon return |next_delayed_work_time|
- // indicates the time when DoDelayedWork should be called again. If
- // |next_delayed_work_time| is null (per Time::is_null), then the queue of
- // future delayed work (timer events) is currently empty, and no additional
- // calls to this function need to be scheduled.
- virtual bool DoDelayedWork(TimeTicks* next_delayed_work_time) = 0;
-
- // Called from within Run just before the message pump goes to sleep.
- // Returns true to indicate that idle work was done.
- virtual bool DoIdleWork() = 0;
- };
-
- MessagePump();
-
- // The Run method is called to enter the message pump's run loop.
- //
- // Within the method, the message pump is responsible for processing native
- // messages as well as for giving cycles to the delegate periodically. The
- // message pump should take care to mix delegate callbacks with native
- // message processing so neither type of event starves the other of cycles.
- //
- // The anatomy of a typical run loop:
- //
- // for (;;) {
- // bool did_work = DoInternalWork();
- // if (should_quit_)
- // break;
- //
- // did_work |= delegate_->DoWork();
- // if (should_quit_)
- // break;
- //
- // TimeTicks next_time;
- // did_work |= delegate_->DoDelayedWork(&next_time);
- // if (should_quit_)
- // break;
- //
- // if (did_work)
- // continue;
- //
- // did_work = delegate_->DoIdleWork();
- // if (should_quit_)
- // break;
- //
- // if (did_work)
- // continue;
- //
- // WaitForWork();
- // }
- //
- // Here, DoInternalWork is some private method of the message pump that is
- // responsible for dispatching the next UI message or notifying the next IO
- // completion (for example). WaitForWork is a private method that simply
- // blocks until there is more work of any type to do.
- //
- // Notice that the run loop cycles between calling DoInternalWork, DoWork,
- // and DoDelayedWork methods. This helps ensure that none of these work
- // queues starve the others. This is important for message pumps that are
- // used to drive animations, for example.
- //
- // Notice also that after each callout to foreign code, the run loop checks
- // to see if it should quit. The Quit method is responsible for setting this
- // flag. No further work is done once the quit flag is set.
- //
- // NOTE: Care must be taken to handle Run being called again from within any
- // of the callouts to foreign code. Native message pumps may also need to
- // deal with other native message pumps being run outside their control
- // (e.g., the MessageBox API on Windows pumps UI messages!). To be specific,
- // the callouts (DoWork and DoDelayedWork) MUST still be provided even in
- // nested sub-loops that are "seemingly" outside the control of this message
- // pump. DoWork in particular must never be starved for time slices unless
- // it returns false (meaning it has run out of things to do).
- //
- virtual void Run(Delegate* delegate) = 0;
-
- // Quit immediately from the most recently entered run loop. This method may
- // only be used on the thread that called Run.
- virtual void Quit() = 0;
-
- // Schedule a DoWork callback to happen reasonably soon. Does nothing if a
- // DoWork callback is already scheduled. This method may be called from any
- // thread. Once this call is made, DoWork should not be "starved" at least
- // until it returns a value of false.
- virtual void ScheduleWork() = 0;
-
- // Schedule a DoDelayedWork callback to happen at the specified time,
- // cancelling any pending DoDelayedWork callback. This method may only be
- // used on the thread that called Run.
- virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time) = 0;
-
- protected:
- virtual ~MessagePump();
- friend class RefCountedThreadSafe<MessagePump>;
-};
-
-} // namespace base
-
-#endif // BASE_MESSAGE_LOOP_MESSAGE_PUMP_H_
diff --git a/base/message_loop/message_pump_android.cc b/base/message_loop/message_pump_android.cc
deleted file mode 100644
index 7374d9c..0000000
--- a/base/message_loop/message_pump_android.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/message_loop/message_pump_android.h"
-
-#include <jni.h>
-
-#include "base/android/jni_android.h"
-#include "base/android/scoped_java_ref.h"
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "base/run_loop.h"
-#include "base/time.h"
-#include "jni/SystemMessageHandler_jni.h"
-
-using base::android::ScopedJavaLocalRef;
-
-namespace {
-
-LazyInstance<android::ScopedJavaGlobalRef<jobject> >
- g_system_message_handler_obj = LAZY_INSTANCE_INITIALIZER;
-
-} // namespace
-
-// ----------------------------------------------------------------------------
-// Native JNI methods called by Java.
-// ----------------------------------------------------------------------------
-// This method can not move to anonymous namespace as it has been declared as
-// 'static' in system_message_handler_jni.h.
-static jboolean DoRunLoopOnce(JNIEnv* env, jobject obj, jint native_delegate) {
- base::MessagePump::Delegate* delegate =
- reinterpret_cast<base::MessagePump::Delegate*>(native_delegate);
- DCHECK(delegate);
- // This is based on MessagePumpForUI::DoRunLoop() from desktop.
- // Note however that our system queue is handled in the java side.
- // In desktop we inspect and process a single system message and then
- // we call DoWork() / DoDelayedWork().
- // On Android, the java message queue may contain messages for other handlers
- // that will be processed before calling here again.
- bool more_work_is_plausible = delegate->DoWork();
-
- // This is the time when we need to do delayed work.
- base::TimeTicks delayed_work_time;
- more_work_is_plausible |= delegate->DoDelayedWork(&delayed_work_time);
-
- // This is a major difference between android and other platforms: since we
- // can't inspect it and process just one single message, instead we'll yeld
- // the callstack, and post a message to call us back soon.
- if (more_work_is_plausible)
- return true;
-
- more_work_is_plausible = delegate->DoIdleWork();
- if (!more_work_is_plausible && !delayed_work_time.is_null()) {
- // We only set the timer here as returning true would post a message.
- jlong millis =
- (delayed_work_time - base::TimeTicks::Now()).InMillisecondsRoundedUp();
- Java_SystemMessageHandler_setDelayedTimer(env, obj, millis);
- }
- return more_work_is_plausible;
-}
-
-namespace base {
-
-MessagePumpForUI::MessagePumpForUI()
- : run_loop_(NULL) {
-}
-
-MessagePumpForUI::~MessagePumpForUI() {
-}
-
-void MessagePumpForUI::Run(Delegate* delegate) {
- NOTREACHED() << "UnitTests should rely on MessagePumpForUIStub in"
- " test_stub_android.h";
-}
-
-void MessagePumpForUI::Start(Delegate* delegate) {
- run_loop_ = new RunLoop();
- // Since the RunLoop was just created above, BeforeRun should be guaranteed to
- // return true (it only returns false if the RunLoop has been Quit already).
- if (!run_loop_->BeforeRun())
- NOTREACHED();
-
- DCHECK(g_system_message_handler_obj.Get().is_null());
-
- JNIEnv* env = base::android::AttachCurrentThread();
- DCHECK(env);
-
- g_system_message_handler_obj.Get().Reset(
- Java_SystemMessageHandler_create(env, reinterpret_cast<jint>(delegate)));
-}
-
-void MessagePumpForUI::Quit() {
- if (!g_system_message_handler_obj.Get().is_null()) {
- JNIEnv* env = base::android::AttachCurrentThread();
- DCHECK(env);
-
- Java_SystemMessageHandler_removeTimer(env,
- g_system_message_handler_obj.Get().obj());
- g_system_message_handler_obj.Get().Reset();
- }
-
- if (run_loop_) {
- run_loop_->AfterRun();
- delete run_loop_;
- run_loop_ = NULL;
- }
-}
-
-void MessagePumpForUI::ScheduleWork() {
- DCHECK(!g_system_message_handler_obj.Get().is_null());
-
- JNIEnv* env = base::android::AttachCurrentThread();
- DCHECK(env);
-
- Java_SystemMessageHandler_setTimer(env,
- g_system_message_handler_obj.Get().obj());
-}
-
-void MessagePumpForUI::ScheduleDelayedWork(const TimeTicks& delayed_work_time) {
- DCHECK(!g_system_message_handler_obj.Get().is_null());
-
- JNIEnv* env = base::android::AttachCurrentThread();
- DCHECK(env);
-
- jlong millis =
- (delayed_work_time - TimeTicks::Now()).InMillisecondsRoundedUp();
- // Note that we're truncating to milliseconds as required by the java side,
- // even though delayed_work_time is microseconds resolution.
- Java_SystemMessageHandler_setDelayedTimer(env,
- g_system_message_handler_obj.Get().obj(), millis);
-}
-
-// static
-bool MessagePumpForUI::RegisterBindings(JNIEnv* env) {
- return RegisterNativesImpl(env);
-}
-
-} // namespace base
diff --git a/base/message_loop/message_pump_android.h b/base/message_loop/message_pump_android.h
deleted file mode 100644
index fd934a7..0000000
--- a/base/message_loop/message_pump_android.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_MESSAGE_LOOP_MESSAGE_PUMP_ANDROID_H_
-#define BASE_MESSAGE_LOOP_MESSAGE_PUMP_ANDROID_H_
-
-#include <jni.h>
-
-#include "base/base_export.h"
-#include "base/compiler_specific.h"
-#include "base/message_loop/message_pump.h"
-
-namespace base {
-
-class RunLoop;
-class TimeTicks;
-
-// This class implements a MessagePump needed for TYPE_UI MessageLoops on
-// OS_ANDROID platform.
-class BASE_EXPORT MessagePumpForUI : public MessagePump {
- public:
- MessagePumpForUI();
-
- virtual void Run(Delegate* delegate) OVERRIDE;
- virtual void Quit() OVERRIDE;
- virtual void ScheduleWork() OVERRIDE;
- virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time) OVERRIDE;
-
- virtual void Start(Delegate* delegate);
-
- static bool RegisterBindings(JNIEnv* env);
-
- protected:
- virtual ~MessagePumpForUI();
-
- private:
- RunLoop* run_loop_;
-
- DISALLOW_COPY_AND_ASSIGN(MessagePumpForUI);
-};
-
-} // namespace base
-
-#endif // BASE_MESSAGE_LOOP_MESSAGE_PUMP_ANDROID_H_
diff --git a/base/message_loop/message_pump_aurax11.cc b/base/message_loop/message_pump_aurax11.cc
deleted file mode 100644
index 70cae64..0000000
--- a/base/message_loop/message_pump_aurax11.cc
+++ /dev/null
@@ -1,307 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/message_loop/message_pump_aurax11.h"
-
-#include <glib.h>
-#include <X11/X.h>
-#include <X11/extensions/XInput2.h>
-#include <X11/XKBlib.h>
-
-#include "base/basictypes.h"
-#include "base/message_loop.h"
-
-namespace base {
-
-namespace {
-
-gboolean XSourcePrepare(GSource* source, gint* timeout_ms) {
- if (XPending(MessagePumpAuraX11::GetDefaultXDisplay()))
- *timeout_ms = 0;
- else
- *timeout_ms = -1;
- return FALSE;
-}
-
-gboolean XSourceCheck(GSource* source) {
- return XPending(MessagePumpAuraX11::GetDefaultXDisplay());
-}
-
-gboolean XSourceDispatch(GSource* source,
- GSourceFunc unused_func,
- gpointer data) {
- MessagePumpAuraX11* pump = static_cast<MessagePumpAuraX11*>(data);
- return pump->DispatchXEvents();
-}
-
-GSourceFuncs XSourceFuncs = {
- XSourcePrepare,
- XSourceCheck,
- XSourceDispatch,
- NULL
-};
-
-// The connection is essentially a global that's accessed through a static
-// method and destroyed whenever ~MessagePumpAuraX11() is called. We do this
-// for historical reasons so user code can call
-// MessagePumpForUI::GetDefaultXDisplay() where MessagePumpForUI is a typedef
-// to whatever type in the current build.
-//
-// TODO(erg): This can be changed to something more sane like
-// MessagePumpAuraX11::Current()->display() once MessagePumpGtk goes away.
-Display* g_xdisplay = NULL;
-int g_xinput_opcode = -1;
-
-bool InitializeXInput2Internal() {
- Display* display = MessagePumpAuraX11::GetDefaultXDisplay();
- if (!display)
- return false;
-
- int event, err;
-
- int xiopcode;
- if (!XQueryExtension(display, "XInputExtension", &xiopcode, &event, &err)) {
- DVLOG(1) << "X Input extension not available.";
- return false;
- }
- g_xinput_opcode = xiopcode;
-
-#if defined(USE_XI2_MT)
- // USE_XI2_MT also defines the required XI2 minor minimum version.
- int major = 2, minor = USE_XI2_MT;
-#else
- int major = 2, minor = 0;
-#endif
- if (XIQueryVersion(display, &major, &minor) == BadRequest) {
- DVLOG(1) << "XInput2 not supported in the server.";
- return false;
- }
-#if defined(USE_XI2_MT)
- if (major < 2 || (major == 2 && minor < USE_XI2_MT)) {
- DVLOG(1) << "XI version on server is " << major << "." << minor << ". "
- << "But 2." << USE_XI2_MT << " is required.";
- return false;
- }
-#endif
-
- return true;
-}
-
-Window FindEventTarget(const NativeEvent& xev) {
- Window target = xev->xany.window;
- if (xev->type == GenericEvent &&
- static_cast<XIEvent*>(xev->xcookie.data)->extension == g_xinput_opcode) {
- target = static_cast<XIDeviceEvent*>(xev->xcookie.data)->event;
- }
- return target;
-}
-
-bool InitializeXInput2() {
- static bool xinput2_supported = InitializeXInput2Internal();
- return xinput2_supported;
-}
-
-bool InitializeXkb() {
- Display* display = MessagePumpAuraX11::GetDefaultXDisplay();
- if (!display)
- return false;
-
- int opcode, event, error;
- int major = XkbMajorVersion;
- int minor = XkbMinorVersion;
- if (!XkbQueryExtension(display, &opcode, &event, &error, &major, &minor)) {
- DVLOG(1) << "Xkb extension not available.";
- return false;
- }
-
- // Ask the server not to send KeyRelease event when the user holds down a key.
- // crbug.com/138092
- Bool supported_return;
- if (!XkbSetDetectableAutoRepeat(display, True, &supported_return)) {
- DVLOG(1) << "XKB not supported in the server.";
- return false;
- }
-
- return true;
-}
-
-} // namespace
-
-MessagePumpAuraX11::MessagePumpAuraX11() : MessagePumpGlib(),
- x_source_(NULL) {
- InitializeXInput2();
- InitializeXkb();
- InitXSource();
-
- // Can't put this in the initializer list because g_xdisplay may not exist
- // until after InitXSource().
- x_root_window_ = DefaultRootWindow(g_xdisplay);
-}
-
-// static
-Display* MessagePumpAuraX11::GetDefaultXDisplay() {
- if (!g_xdisplay)
- g_xdisplay = XOpenDisplay(NULL);
- return g_xdisplay;
-}
-
-// static
-bool MessagePumpAuraX11::HasXInput2() {
- return InitializeXInput2();
-}
-
-// static
-MessagePumpAuraX11* MessagePumpAuraX11::Current() {
- MessageLoopForUI* loop = MessageLoopForUI::current();
- return static_cast<MessagePumpAuraX11*>(loop->pump_ui());
-}
-
-void MessagePumpAuraX11::AddDispatcherForWindow(
- MessagePumpDispatcher* dispatcher,
- unsigned long xid) {
- dispatchers_.insert(std::make_pair(xid, dispatcher));
-}
-
-void MessagePumpAuraX11::RemoveDispatcherForWindow(unsigned long xid) {
- dispatchers_.erase(xid);
-}
-
-void MessagePumpAuraX11::AddDispatcherForRootWindow(
- MessagePumpDispatcher* dispatcher) {
- root_window_dispatchers_.AddObserver(dispatcher);
-}
-
-void MessagePumpAuraX11::RemoveDispatcherForRootWindow(
- MessagePumpDispatcher* dispatcher) {
- root_window_dispatchers_.RemoveObserver(dispatcher);
-}
-
-bool MessagePumpAuraX11::DispatchXEvents() {
- Display* display = GetDefaultXDisplay();
- DCHECK(display);
- MessagePumpDispatcher* dispatcher =
- GetDispatcher() ? GetDispatcher() : this;
-
- // In the general case, we want to handle all pending events before running
- // the tasks. This is what happens in the message_pump_glib case.
- while (XPending(display)) {
- XEvent xev;
- XNextEvent(display, &xev);
- if (dispatcher && ProcessXEvent(dispatcher, &xev))
- return TRUE;
- }
- return TRUE;
-}
-
-void MessagePumpAuraX11::BlockUntilWindowMapped(unsigned long xid) {
- XEvent event;
-
- Display* display = GetDefaultXDisplay();
- DCHECK(display);
-
- MessagePumpDispatcher* dispatcher =
- GetDispatcher() ? GetDispatcher() : this;
-
- do {
- // Block until there's a message of |event_mask| type on |w|. Then remove
- // it from the queue and stuff it in |event|.
- XWindowEvent(display, xid, StructureNotifyMask, &event);
- ProcessXEvent(dispatcher, &event);
- } while (event.type != MapNotify);
-}
-
-MessagePumpAuraX11::~MessagePumpAuraX11() {
- g_source_destroy(x_source_);
- g_source_unref(x_source_);
- XCloseDisplay(g_xdisplay);
- g_xdisplay = NULL;
-}
-
-void MessagePumpAuraX11::InitXSource() {
- // CHECKs are to help track down crbug.com/113106.
- CHECK(!x_source_);
- Display* display = GetDefaultXDisplay();
- CHECK(display) << "Unable to get connection to X server";
- x_poll_.reset(new GPollFD());
- CHECK(x_poll_.get());
- x_poll_->fd = ConnectionNumber(display);
- x_poll_->events = G_IO_IN;
-
- x_source_ = g_source_new(&XSourceFuncs, sizeof(GSource));
- g_source_add_poll(x_source_, x_poll_.get());
- g_source_set_can_recurse(x_source_, TRUE);
- g_source_set_callback(x_source_, NULL, this, NULL);
- g_source_attach(x_source_, g_main_context_default());
-}
-
-bool MessagePumpAuraX11::ProcessXEvent(MessagePumpDispatcher* dispatcher,
- XEvent* xev) {
- bool should_quit = false;
-
- bool have_cookie = false;
- if (xev->type == GenericEvent &&
- XGetEventData(xev->xgeneric.display, &xev->xcookie)) {
- have_cookie = true;
- }
-
- if (!WillProcessXEvent(xev)) {
- if (!dispatcher->Dispatch(xev)) {
- should_quit = true;
- Quit();
- }
- DidProcessXEvent(xev);
- }
-
- if (have_cookie) {
- XFreeEventData(xev->xgeneric.display, &xev->xcookie);
- }
-
- return should_quit;
-}
-
-bool MessagePumpAuraX11::WillProcessXEvent(XEvent* xevent) {
- if (!observers().might_have_observers())
- return false;
- ObserverListBase<MessagePumpObserver>::Iterator it(observers());
- MessagePumpObserver* obs;
- while ((obs = it.GetNext()) != NULL) {
- if (obs->WillProcessEvent(xevent))
- return true;
- }
- return false;
-}
-
-void MessagePumpAuraX11::DidProcessXEvent(XEvent* xevent) {
- FOR_EACH_OBSERVER(MessagePumpObserver, observers(), DidProcessEvent(xevent));
-}
-
-MessagePumpDispatcher* MessagePumpAuraX11::GetDispatcherForXEvent(
- const NativeEvent& xev) const {
- ::Window x_window = FindEventTarget(xev);
- DispatchersMap::const_iterator it = dispatchers_.find(x_window);
- return it != dispatchers_.end() ? it->second : NULL;
-}
-
-bool MessagePumpAuraX11::Dispatch(const NativeEvent& xev) {
- // MappingNotify events (meaning that the keyboard or pointer buttons have
- // been remapped) aren't associated with a window; send them to all
- // dispatchers.
- if (xev->type == MappingNotify) {
- for (DispatchersMap::const_iterator it = dispatchers_.begin();
- it != dispatchers_.end(); ++it) {
- it->second->Dispatch(xev);
- }
- return true;
- }
-
- if (FindEventTarget(xev) == x_root_window_) {
- FOR_EACH_OBSERVER(MessagePumpDispatcher, root_window_dispatchers_,
- Dispatch(xev));
- return true;
- }
- MessagePumpDispatcher* dispatcher = GetDispatcherForXEvent(xev);
- return dispatcher ? dispatcher->Dispatch(xev) : true;
-}
-
-} // namespace base
diff --git a/base/message_loop/message_pump_aurax11.h b/base/message_loop/message_pump_aurax11.h
deleted file mode 100644
index cec6934..0000000
--- a/base/message_loop/message_pump_aurax11.h
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_MESSAGE_LOOP_MESSAGE_PUMP_AURAX11_H
-#define BASE_MESSAGE_LOOP_MESSAGE_PUMP_AURAX11_H
-
-#include <bitset>
-#include <map>
-
-#include "base/memory/scoped_ptr.h"
-#include "base/message_loop/message_pump.h"
-#include "base/message_loop/message_pump_dispatcher.h"
-#include "base/message_loop/message_pump_glib.h"
-#include "base/message_loop/message_pump_observer.h"
-#include "base/observer_list.h"
-
-// It would be nice to include the X11 headers here so that we use Window
-// instead of its typedef of unsigned long, but we can't because everything in
-// chrome includes us through base/message_loop.h, and X11's crappy #define
-// heavy headers muck up half of chrome.
-
-typedef struct _GPollFD GPollFD;
-typedef struct _GSource GSource;
-typedef struct _XDisplay Display;
-
-namespace base {
-
-// This class implements a message-pump for dispatching X events.
-//
-// If there's a current dispatcher given through RunWithDispatcher(), that
-// dispatcher receives events. Otherwise, we route to messages to dispatchers
-// who have subscribed to messages from a specific X11 window.
-class BASE_EXPORT MessagePumpAuraX11 : public MessagePumpGlib,
- public MessagePumpDispatcher {
- public:
- MessagePumpAuraX11();
-
- // Returns default X Display.
- static Display* GetDefaultXDisplay();
-
- // Returns true if the system supports XINPUT2.
- static bool HasXInput2();
-
- // Returns the UI message pump.
- static MessagePumpAuraX11* Current();
-
- // Adds/Removes |dispatcher| for the |xid|. This will route all messages from
- // the window |xid| to |dispatcher.
- void AddDispatcherForWindow(MessagePumpDispatcher* dispatcher,
- unsigned long xid);
- void RemoveDispatcherForWindow(unsigned long xid);
-
- // Adds/Removes |dispatcher| to receive all events sent to the X root
- // window. A root window can have multiple dispatchers, and events on root
- // windows will be dispatched to all.
- void AddDispatcherForRootWindow(MessagePumpDispatcher* dispatcher);
- void RemoveDispatcherForRootWindow(MessagePumpDispatcher* dispatcher);
-
- // Internal function. Called by the glib source dispatch function. Processes
- // all available X events.
- bool DispatchXEvents();
-
- // Blocks on the X11 event queue until we receive notification from the
- // xserver that |w| has been mapped; StructureNotifyMask events on |w| are
- // pulled out from the queue and dispatched out of order.
- //
- // For those that know X11, this is really a wrapper around XWindowEvent
- // which still makes sure the preempted event is dispatched instead of
- // dropped on the floor. This method exists because mapping a window is
- // asynchronous (and we receive an XEvent when mapped), while there are also
- // functions which require a mapped window.
- void BlockUntilWindowMapped(unsigned long xid);
-
- protected:
- virtual ~MessagePumpAuraX11();
-
- private:
- typedef std::map<unsigned long, MessagePumpDispatcher*> DispatchersMap;
-
- // Initializes the glib event source for X.
- void InitXSource();
-
- // Dispatches the XEvent and returns true if we should exit the current loop
- // of message processing.
- bool ProcessXEvent(MessagePumpDispatcher* dispatcher, XEvent* event);
-
- // Sends the event to the observers. If an observer returns true, then it does
- // not send the event to any other observers and returns true. Returns false
- // if no observer returns true.
- bool WillProcessXEvent(XEvent* xevent);
- void DidProcessXEvent(XEvent* xevent);
-
- // Returns the Dispatcher based on the event's target window.
- MessagePumpDispatcher* GetDispatcherForXEvent(const NativeEvent& xev) const;
-
- // Overridden from MessagePumpDispatcher:
- virtual bool Dispatch(const NativeEvent& event) OVERRIDE;
-
- // The event source for X events.
- GSource* x_source_;
-
- // The poll attached to |x_source_|.
- scoped_ptr<GPollFD> x_poll_;
-
- DispatchersMap dispatchers_;
-
- // Dispatch calls can cause addition of new dispatchers as we iterate
- // through them. Use ObserverList to ensure the iterator remains valid across
- // additions.
- ObserverList<MessagePumpDispatcher> root_window_dispatchers_;
-
- unsigned long x_root_window_;
-
- DISALLOW_COPY_AND_ASSIGN(MessagePumpAuraX11);
-};
-
-typedef MessagePumpAuraX11 MessagePumpForUI;
-
-} // namespace base
-
-#endif // BASE_MESSAGE_LOOP_MESSAGE_PUMP_AURAX11_H
diff --git a/base/message_loop/message_pump_default.cc b/base/message_loop/message_pump_default.cc
deleted file mode 100644
index b36ff21..0000000
--- a/base/message_loop/message_pump_default.cc
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/message_loop/message_pump_default.h"
-
-#include "base/logging.h"
-#include "base/threading/thread_restrictions.h"
-
-#if defined(OS_MACOSX)
-#include "base/mac/scoped_nsautorelease_pool.h"
-#endif
-
-namespace base {
-
-MessagePumpDefault::MessagePumpDefault()
- : keep_running_(true),
- event_(false, false) {
-}
-
-void MessagePumpDefault::Run(Delegate* delegate) {
- DCHECK(keep_running_) << "Quit must have been called outside of Run!";
-
- for (;;) {
-#if defined(OS_MACOSX)
- mac::ScopedNSAutoreleasePool autorelease_pool;
-#endif
-
- bool did_work = delegate->DoWork();
- if (!keep_running_)
- break;
-
- did_work |= delegate->DoDelayedWork(&delayed_work_time_);
- if (!keep_running_)
- break;
-
- if (did_work)
- continue;
-
- did_work = delegate->DoIdleWork();
- if (!keep_running_)
- break;
-
- if (did_work)
- continue;
-
- ThreadRestrictions::ScopedAllowWait allow_wait;
- if (delayed_work_time_.is_null()) {
- event_.Wait();
- } else {
- TimeDelta delay = delayed_work_time_ - TimeTicks::Now();
- if (delay > TimeDelta()) {
- event_.TimedWait(delay);
- } else {
- // It looks like delayed_work_time_ indicates a time in the past, so we
- // need to call DoDelayedWork now.
- delayed_work_time_ = TimeTicks();
- }
- }
- // Since event_ is auto-reset, we don't need to do anything special here
- // other than service each delegate method.
- }
-
- keep_running_ = true;
-}
-
-void MessagePumpDefault::Quit() {
- keep_running_ = false;
-}
-
-void MessagePumpDefault::ScheduleWork() {
- // Since this can be called on any thread, we need to ensure that our Run
- // loop wakes up.
- event_.Signal();
-}
-
-void MessagePumpDefault::ScheduleDelayedWork(
- const TimeTicks& delayed_work_time) {
- // We know that we can't be blocked on Wait right now since this method can
- // only be called on the same thread as Run, so we only need to update our
- // record of how long to sleep when we do sleep.
- delayed_work_time_ = delayed_work_time;
-}
-
-} // namespace base
diff --git a/base/message_loop/message_pump_default.h b/base/message_loop/message_pump_default.h
deleted file mode 100644
index dd65973..0000000
--- a/base/message_loop/message_pump_default.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_MESSAGE_LOOP_MESSAGE_PUMP_DEFAULT_H_
-#define BASE_MESSAGE_LOOP_MESSAGE_PUMP_DEFAULT_H_
-
-#include "base/message_loop/message_pump.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/time.h"
-
-namespace base {
-
-class MessagePumpDefault : public MessagePump {
- public:
- MessagePumpDefault();
-
- // MessagePump methods:
- virtual void Run(Delegate* delegate) OVERRIDE;
- virtual void Quit() OVERRIDE;
- virtual void ScheduleWork() OVERRIDE;
- virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time) OVERRIDE;
-
- protected:
- virtual ~MessagePumpDefault() {}
-
- private:
- // This flag is set to false when Run should return.
- bool keep_running_;
-
- // Used to sleep until there is more work to do.
- WaitableEvent event_;
-
- // The time at which we should call DoDelayedWork.
- TimeTicks delayed_work_time_;
-
- DISALLOW_COPY_AND_ASSIGN(MessagePumpDefault);
-};
-
-} // namespace base
-
-#endif // BASE__MESSAGE_LOOPMESSAGE_PUMP_DEFAULT_H_
diff --git a/base/message_loop/message_pump_dispatcher.h b/base/message_loop/message_pump_dispatcher.h
deleted file mode 100644
index e49fa4f..0000000
--- a/base/message_loop/message_pump_dispatcher.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_MESSAGE_LOOP_MESSAGE_PUMP_DISPATCHER_H
-#define BASE_MESSAGE_LOOP_MESSAGE_PUMP_DISPATCHER_H
-
-#include "base/base_export.h"
-#include "base/event_types.h"
-
-namespace base {
-
-// Dispatcher is used during a nested invocation of Run to dispatch events when
-// |RunLoop(dispatcher).Run()| is used. If |RunLoop().Run()| is invoked,
-// MessageLoop does not dispatch events (or invoke TranslateMessage), rather
-// every message is passed to Dispatcher's Dispatch method for dispatch. It is
-// up to the Dispatcher whether or not to dispatch the event.
-//
-// The nested loop is exited by either posting a quit, or returning false
-// from Dispatch.
-class BASE_EXPORT MessagePumpDispatcher {
- public:
- virtual ~MessagePumpDispatcher() {}
-
- // Dispatches the event. If true is returned processing continues as
- // normal. If false is returned, the nested loop exits immediately.
- virtual bool Dispatch(const NativeEvent& event) = 0;
-};
-
-} // namespace base
-
-#endif // BASE_MESSAGE_LOOP_MESSAGE_PUMP_DISPATCHER_H
diff --git a/base/message_loop/message_pump_glib.cc b/base/message_loop/message_pump_glib.cc
deleted file mode 100644
index de012fd..0000000
--- a/base/message_loop/message_pump_glib.cc
+++ /dev/null
@@ -1,334 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/message_loop/message_pump_glib.h"
-
-#include <fcntl.h>
-#include <math.h>
-
-#include <glib.h>
-
-#include "base/logging.h"
-#include "base/posix/eintr_wrapper.h"
-#include "base/threading/platform_thread.h"
-
-namespace base {
-
-namespace {
-
-// Return a timeout suitable for the glib loop, -1 to block forever,
-// 0 to return right away, or a timeout in milliseconds from now.
-int GetTimeIntervalMilliseconds(const TimeTicks& from) {
- if (from.is_null())
- return -1;
-
- // Be careful here. TimeDelta has a precision of microseconds, but we want a
- // value in milliseconds. If there are 5.5ms left, should the delay be 5 or
- // 6? It should be 6 to avoid executing delayed work too early.
- int delay = static_cast<int>(
- ceil((from - TimeTicks::Now()).InMillisecondsF()));
-
- // If this value is negative, then we need to run delayed work soon.
- return delay < 0 ? 0 : delay;
-}
-
-// A brief refresher on GLib:
-// GLib sources have four callbacks: Prepare, Check, Dispatch and Finalize.
-// On each iteration of the GLib pump, it calls each source's Prepare function.
-// This function should return TRUE if it wants GLib to call its Dispatch, and
-// FALSE otherwise. It can also set a timeout in this case for the next time
-// Prepare should be called again (it may be called sooner).
-// After the Prepare calls, GLib does a poll to check for events from the
-// system. File descriptors can be attached to the sources. The poll may block
-// if none of the Prepare calls returned TRUE. It will block indefinitely, or
-// by the minimum time returned by a source in Prepare.
-// After the poll, GLib calls Check for each source that returned FALSE
-// from Prepare. The return value of Check has the same meaning as for Prepare,
-// making Check a second chance to tell GLib we are ready for Dispatch.
-// Finally, GLib calls Dispatch for each source that is ready. If Dispatch
-// returns FALSE, GLib will destroy the source. Dispatch calls may be recursive
-// (i.e., you can call Run from them), but Prepare and Check cannot.
-// Finalize is called when the source is destroyed.
-// NOTE: It is common for subsytems to want to process pending events while
-// doing intensive work, for example the flash plugin. They usually use the
-// following pattern (recommended by the GTK docs):
-// while (gtk_events_pending()) {
-// gtk_main_iteration();
-// }
-//
-// gtk_events_pending just calls g_main_context_pending, which does the
-// following:
-// - Call prepare on all the sources.
-// - Do the poll with a timeout of 0 (not blocking).
-// - Call check on all the sources.
-// - *Does not* call dispatch on the sources.
-// - Return true if any of prepare() or check() returned true.
-//
-// gtk_main_iteration just calls g_main_context_iteration, which does the whole
-// thing, respecting the timeout for the poll (and block, although it is
-// expected not to if gtk_events_pending returned true), and call dispatch.
-//
-// Thus it is important to only return true from prepare or check if we
-// actually have events or work to do. We also need to make sure we keep
-// internal state consistent so that if prepare/check return true when called
-// from gtk_events_pending, they will still return true when called right
-// after, from gtk_main_iteration.
-//
-// For the GLib pump we try to follow the Windows UI pump model:
-// - Whenever we receive a wakeup event or the timer for delayed work expires,
-// we run DoWork and/or DoDelayedWork. That part will also run in the other
-// event pumps.
-// - We also run DoWork, DoDelayedWork, and possibly DoIdleWork in the main
-// loop, around event handling.
-
-struct WorkSource : public GSource {
- MessagePumpGlib* pump;
-};
-
-gboolean WorkSourcePrepare(GSource* source,
- gint* timeout_ms) {
- *timeout_ms = static_cast<WorkSource*>(source)->pump->HandlePrepare();
- // We always return FALSE, so that our timeout is honored. If we were
- // to return TRUE, the timeout would be considered to be 0 and the poll
- // would never block. Once the poll is finished, Check will be called.
- return FALSE;
-}
-
-gboolean WorkSourceCheck(GSource* source) {
- // Only return TRUE if Dispatch should be called.
- return static_cast<WorkSource*>(source)->pump->HandleCheck();
-}
-
-gboolean WorkSourceDispatch(GSource* source,
- GSourceFunc unused_func,
- gpointer unused_data) {
-
- static_cast<WorkSource*>(source)->pump->HandleDispatch();
- // Always return TRUE so our source stays registered.
- return TRUE;
-}
-
-// I wish these could be const, but g_source_new wants non-const.
-GSourceFuncs WorkSourceFuncs = {
- WorkSourcePrepare,
- WorkSourceCheck,
- WorkSourceDispatch,
- NULL
-};
-
-} // namespace
-
-struct MessagePumpGlib::RunState {
- Delegate* delegate;
- MessagePumpDispatcher* dispatcher;
-
- // Used to flag that the current Run() invocation should return ASAP.
- bool should_quit;
-
- // Used to count how many Run() invocations are on the stack.
- int run_depth;
-
- // This keeps the state of whether the pump got signaled that there was new
- // work to be done. Since we eat the message on the wake up pipe as soon as
- // we get it, we keep that state here to stay consistent.
- bool has_work;
-};
-
-MessagePumpGlib::MessagePumpGlib()
- : state_(NULL),
- context_(g_main_context_default()),
- wakeup_gpollfd_(new GPollFD) {
- // Create our wakeup pipe, which is used to flag when work was scheduled.
- int fds[2];
- int ret = pipe(fds);
- DCHECK_EQ(ret, 0);
- (void)ret; // Prevent warning in release mode.
-
- wakeup_pipe_read_ = fds[0];
- wakeup_pipe_write_ = fds[1];
- wakeup_gpollfd_->fd = wakeup_pipe_read_;
- wakeup_gpollfd_->events = G_IO_IN;
-
- work_source_ = g_source_new(&WorkSourceFuncs, sizeof(WorkSource));
- static_cast<WorkSource*>(work_source_)->pump = this;
- g_source_add_poll(work_source_, wakeup_gpollfd_.get());
- // Use a low priority so that we let other events in the queue go first.
- g_source_set_priority(work_source_, G_PRIORITY_DEFAULT_IDLE);
- // This is needed to allow Run calls inside Dispatch.
- g_source_set_can_recurse(work_source_, TRUE);
- g_source_attach(work_source_, context_);
-}
-
-void MessagePumpGlib::RunWithDispatcher(Delegate* delegate,
- MessagePumpDispatcher* dispatcher) {
-#ifndef NDEBUG
- // Make sure we only run this on one thread. X/GTK only has one message pump
- // so we can only have one UI loop per process.
- static PlatformThreadId thread_id = PlatformThread::CurrentId();
- DCHECK(thread_id == PlatformThread::CurrentId()) <<
- "Running MessagePumpGlib on two different threads; "
- "this is unsupported by GLib!";
-#endif
-
- RunState state;
- state.delegate = delegate;
- state.dispatcher = dispatcher;
- state.should_quit = false;
- state.run_depth = state_ ? state_->run_depth + 1 : 1;
- state.has_work = false;
-
- RunState* previous_state = state_;
- state_ = &state;
-
- // We really only do a single task for each iteration of the loop. If we
- // have done something, assume there is likely something more to do. This
- // will mean that we don't block on the message pump until there was nothing
- // more to do. We also set this to true to make sure not to block on the
- // first iteration of the loop, so RunUntilIdle() works correctly.
- bool more_work_is_plausible = true;
-
- // We run our own loop instead of using g_main_loop_quit in one of the
- // callbacks. This is so we only quit our own loops, and we don't quit
- // nested loops run by others. TODO(deanm): Is this what we want?
- for (;;) {
- // Don't block if we think we have more work to do.
- bool block = !more_work_is_plausible;
-
- more_work_is_plausible = g_main_context_iteration(context_, block);
- if (state_->should_quit)
- break;
-
- more_work_is_plausible |= state_->delegate->DoWork();
- if (state_->should_quit)
- break;
-
- more_work_is_plausible |=
- state_->delegate->DoDelayedWork(&delayed_work_time_);
- if (state_->should_quit)
- break;
-
- if (more_work_is_plausible)
- continue;
-
- more_work_is_plausible = state_->delegate->DoIdleWork();
- if (state_->should_quit)
- break;
- }
-
- state_ = previous_state;
-}
-
-// Return the timeout we want passed to poll.
-int MessagePumpGlib::HandlePrepare() {
- // We know we have work, but we haven't called HandleDispatch yet. Don't let
- // the pump block so that we can do some processing.
- if (state_ && // state_ may be null during tests.
- state_->has_work)
- return 0;
-
- // We don't think we have work to do, but make sure not to block
- // longer than the next time we need to run delayed work.
- return GetTimeIntervalMilliseconds(delayed_work_time_);
-}
-
-bool MessagePumpGlib::HandleCheck() {
- if (!state_) // state_ may be null during tests.
- return false;
-
- // We usually have a single message on the wakeup pipe, since we are only
- // signaled when the queue went from empty to non-empty, but there can be
- // two messages if a task posted a task, hence we read at most two bytes.
- // The glib poll will tell us whether there was data, so this read
- // shouldn't block.
- if (wakeup_gpollfd_->revents & G_IO_IN) {
- char msg[2];
- const int num_bytes = HANDLE_EINTR(read(wakeup_pipe_read_, msg, 2));
- if (num_bytes < 1) {
- NOTREACHED() << "Error reading from the wakeup pipe.";
- }
- DCHECK((num_bytes == 1 && msg[0] == '!') ||
- (num_bytes == 2 && msg[0] == '!' && msg[1] == '!'));
- // Since we ate the message, we need to record that we have more work,
- // because HandleCheck() may be called without HandleDispatch being called
- // afterwards.
- state_->has_work = true;
- }
-
- if (state_->has_work)
- return true;
-
- if (GetTimeIntervalMilliseconds(delayed_work_time_) == 0) {
- // The timer has expired. That condition will stay true until we process
- // that delayed work, so we don't need to record this differently.
- return true;
- }
-
- return false;
-}
-
-void MessagePumpGlib::HandleDispatch() {
- state_->has_work = false;
- if (state_->delegate->DoWork()) {
- // NOTE: on Windows at this point we would call ScheduleWork (see
- // MessagePumpGlib::HandleWorkMessage in message_pump_win.cc). But here,
- // instead of posting a message on the wakeup pipe, we can avoid the
- // syscalls and just signal that we have more work.
- state_->has_work = true;
- }
-
- if (state_->should_quit)
- return;
-
- state_->delegate->DoDelayedWork(&delayed_work_time_);
-}
-
-void MessagePumpGlib::AddObserver(MessagePumpObserver* observer) {
- observers_.AddObserver(observer);
-}
-
-void MessagePumpGlib::RemoveObserver(MessagePumpObserver* observer) {
- observers_.RemoveObserver(observer);
-}
-
-void MessagePumpGlib::Run(Delegate* delegate) {
- RunWithDispatcher(delegate, NULL);
-}
-
-void MessagePumpGlib::Quit() {
- if (state_) {
- state_->should_quit = true;
- } else {
- NOTREACHED() << "Quit called outside Run!";
- }
-}
-
-void MessagePumpGlib::ScheduleWork() {
- // This can be called on any thread, so we don't want to touch any state
- // variables as we would then need locks all over. This ensures that if
- // we are sleeping in a poll that we will wake up.
- char msg = '!';
- if (HANDLE_EINTR(write(wakeup_pipe_write_, &msg, 1)) != 1) {
- NOTREACHED() << "Could not write to the UI message loop wakeup pipe!";
- }
-}
-
-void MessagePumpGlib::ScheduleDelayedWork(const TimeTicks& delayed_work_time) {
- // We need to wake up the loop in case the poll timeout needs to be
- // adjusted. This will cause us to try to do work, but that's ok.
- delayed_work_time_ = delayed_work_time;
- ScheduleWork();
-}
-
-MessagePumpGlib::~MessagePumpGlib() {
- g_source_destroy(work_source_);
- g_source_unref(work_source_);
- close(wakeup_pipe_read_);
- close(wakeup_pipe_write_);
-}
-
-MessagePumpDispatcher* MessagePumpGlib::GetDispatcher() {
- return state_ ? state_->dispatcher : NULL;
-}
-
-} // namespace base
diff --git a/base/message_loop/message_pump_glib.h b/base/message_loop/message_pump_glib.h
deleted file mode 100644
index e45591b..0000000
--- a/base/message_loop/message_pump_glib.h
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_MESSAGE_LOOP_MESSAGE_PUMP_GLIB_H_
-#define BASE_MESSAGE_LOOP_MESSAGE_PUMP_GLIB_H_
-
-#include "base/base_export.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/message_loop/message_pump.h"
-#include "base/observer_list.h"
-#include "base/time.h"
-
-typedef struct _GMainContext GMainContext;
-typedef struct _GPollFD GPollFD;
-typedef struct _GSource GSource;
-
-namespace base {
-
-// MessagePumpObserver is notified prior to an event being dispatched. As
-// Observers are notified of every change, they have to be FAST! The platform
-// specific implementation of the class is in message_pump_gtk/message_pump_x.
-class MessagePumpObserver;
-
-// MessagePumpDispatcher is used during a nested invocation of Run to dispatch
-// events. If Run is invoked with a non-NULL MessagePumpDispatcher, MessageLoop
-// does not dispatch events (or invoke gtk_main_do_event), rather every event is
-// passed to Dispatcher's Dispatch method for dispatch. It is up to the
-// Dispatcher to dispatch, or not, the event. The platform specific
-// implementation of the class is in message_pump_gtk/message_pump_x.
-class MessagePumpDispatcher;
-
-// This class implements a base MessagePump needed for TYPE_UI MessageLoops on
-// platforms using GLib.
-class BASE_EXPORT MessagePumpGlib : public MessagePump {
- public:
- MessagePumpGlib();
-
- // Like MessagePump::Run, but events are routed through dispatcher.
- virtual void RunWithDispatcher(Delegate* delegate,
- MessagePumpDispatcher* dispatcher);
-
- // Internal methods used for processing the pump callbacks. They are
- // public for simplicity but should not be used directly. HandlePrepare
- // is called during the prepare step of glib, and returns a timeout that
- // will be passed to the poll. HandleCheck is called after the poll
- // has completed, and returns whether or not HandleDispatch should be called.
- // HandleDispatch is called if HandleCheck returned true.
- int HandlePrepare();
- bool HandleCheck();
- void HandleDispatch();
-
- // Adds an Observer, which will start receiving notifications immediately.
- void AddObserver(MessagePumpObserver* observer);
-
- // Removes an Observer. It is safe to call this method while an Observer is
- // receiving a notification callback.
- void RemoveObserver(MessagePumpObserver* observer);
-
- // Overridden from MessagePump:
- virtual void Run(Delegate* delegate) OVERRIDE;
- virtual void Quit() OVERRIDE;
- virtual void ScheduleWork() OVERRIDE;
- virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time) OVERRIDE;
-
- protected:
- virtual ~MessagePumpGlib();
-
- // Returns the dispatcher for the current run state (|state_->dispatcher|).
- MessagePumpDispatcher* GetDispatcher();
-
- ObserverList<MessagePumpObserver>& observers() { return observers_; }
-
- private:
- // We may make recursive calls to Run, so we save state that needs to be
- // separate between them in this structure type.
- struct RunState;
-
- RunState* state_;
-
- // This is a GLib structure that we can add event sources to. We use the
- // default GLib context, which is the one to which all GTK events are
- // dispatched.
- GMainContext* context_;
-
- // This is the time when we need to do delayed work.
- TimeTicks delayed_work_time_;
-
- // The work source. It is shared by all calls to Run and destroyed when
- // the message pump is destroyed.
- GSource* work_source_;
-
- // We use a wakeup pipe to make sure we'll get out of the glib polling phase
- // when another thread has scheduled us to do some work. There is a glib
- // mechanism g_main_context_wakeup, but this won't guarantee that our event's
- // Dispatch() will be called.
- int wakeup_pipe_read_;
- int wakeup_pipe_write_;
- // Use a scoped_ptr to avoid needing the definition of GPollFD in the header.
- scoped_ptr<GPollFD> wakeup_gpollfd_;
-
- // List of observers.
- ObserverList<MessagePumpObserver> observers_;
-
- DISALLOW_COPY_AND_ASSIGN(MessagePumpGlib);
-};
-
-} // namespace base
-
-#endif // BASE_MESSAGE_LOOP_MESSAGE_PUMP_GLIB_H_
diff --git a/base/message_loop/message_pump_glib_unittest.cc b/base/message_loop/message_pump_glib_unittest.cc
deleted file mode 100644
index cb30bb0..0000000
--- a/base/message_loop/message_pump_glib_unittest.cc
+++ /dev/null
@@ -1,580 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/message_loop/message_pump_glib.h"
-
-#include <glib.h>
-#include <math.h>
-
-#include <algorithm>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/callback.h"
-#include "base/memory/ref_counted.h"
-#include "base/message_loop.h"
-#include "base/run_loop.h"
-#include "base/threading/thread.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-#if defined(TOOLKIT_GTK)
-#include <gtk/gtk.h>
-#endif
-
-namespace base {
-namespace {
-
-// This class injects dummy "events" into the GLib loop. When "handled" these
-// events can run tasks. This is intended to mock gtk events (the corresponding
-// GLib source runs at the same priority).
-class EventInjector {
- public:
- EventInjector() : processed_events_(0) {
- source_ = static_cast<Source*>(g_source_new(&SourceFuncs, sizeof(Source)));
- source_->injector = this;
- g_source_attach(source_, NULL);
- g_source_set_can_recurse(source_, TRUE);
- }
-
- ~EventInjector() {
- g_source_destroy(source_);
- g_source_unref(source_);
- }
-
- int HandlePrepare() {
- // If the queue is empty, block.
- if (events_.empty())
- return -1;
- TimeDelta delta = events_[0].time - Time::NowFromSystemTime();
- return std::max(0, static_cast<int>(ceil(delta.InMillisecondsF())));
- }
-
- bool HandleCheck() {
- if (events_.empty())
- return false;
- return events_[0].time <= Time::NowFromSystemTime();
- }
-
- void HandleDispatch() {
- if (events_.empty())
- return;
- Event event = events_[0];
- events_.erase(events_.begin());
- ++processed_events_;
- if (!event.callback.is_null())
- event.callback.Run();
- else if (!event.task.is_null())
- event.task.Run();
- }
-
- // Adds an event to the queue. When "handled", executes |callback|.
- // delay_ms is relative to the last event if any, or to Now() otherwise.
- void AddEvent(int delay_ms, const Closure& callback) {
- AddEventHelper(delay_ms, callback, Closure());
- }
-
- void AddDummyEvent(int delay_ms) {
- AddEventHelper(delay_ms, Closure(), Closure());
- }
-
- void AddEventAsTask(int delay_ms, const Closure& task) {
- AddEventHelper(delay_ms, Closure(), task);
- }
-
- void Reset() {
- processed_events_ = 0;
- events_.clear();
- }
-
- int processed_events() const { return processed_events_; }
-
- private:
- struct Event {
- Time time;
- Closure callback;
- Closure task;
- };
-
- struct Source : public GSource {
- EventInjector* injector;
- };
-
- void AddEventHelper(
- int delay_ms, const Closure& callback, const Closure& task) {
- Time last_time;
- if (!events_.empty())
- last_time = (events_.end()-1)->time;
- else
- last_time = Time::NowFromSystemTime();
-
- Time future = last_time + TimeDelta::FromMilliseconds(delay_ms);
- EventInjector::Event event = {future, callback, task};
- events_.push_back(event);
- }
-
- static gboolean Prepare(GSource* source, gint* timeout_ms) {
- *timeout_ms = static_cast<Source*>(source)->injector->HandlePrepare();
- return FALSE;
- }
-
- static gboolean Check(GSource* source) {
- return static_cast<Source*>(source)->injector->HandleCheck();
- }
-
- static gboolean Dispatch(GSource* source,
- GSourceFunc unused_func,
- gpointer unused_data) {
- static_cast<Source*>(source)->injector->HandleDispatch();
- return TRUE;
- }
-
- Source* source_;
- std::vector<Event> events_;
- int processed_events_;
- static GSourceFuncs SourceFuncs;
- DISALLOW_COPY_AND_ASSIGN(EventInjector);
-};
-
-GSourceFuncs EventInjector::SourceFuncs = {
- EventInjector::Prepare,
- EventInjector::Check,
- EventInjector::Dispatch,
- NULL
-};
-
-void IncrementInt(int *value) {
- ++*value;
-}
-
-// Checks how many events have been processed by the injector.
-void ExpectProcessedEvents(EventInjector* injector, int count) {
- EXPECT_EQ(injector->processed_events(), count);
-}
-
-// Posts a task on the current message loop.
-void PostMessageLoopTask(const tracked_objects::Location& from_here,
- const Closure& task) {
- MessageLoop::current()->PostTask(from_here, task);
-}
-
-// Test fixture.
-class MessagePumpGLibTest : public testing::Test {
- public:
- MessagePumpGLibTest() : loop_(NULL), injector_(NULL) { }
-
- // Overridden from testing::Test:
- virtual void SetUp() OVERRIDE {
- loop_ = new MessageLoop(MessageLoop::TYPE_UI);
- injector_ = new EventInjector();
- }
- virtual void TearDown() OVERRIDE {
- delete injector_;
- injector_ = NULL;
- delete loop_;
- loop_ = NULL;
- }
-
- MessageLoop* loop() const { return loop_; }
- EventInjector* injector() const { return injector_; }
-
- private:
- MessageLoop* loop_;
- EventInjector* injector_;
- DISALLOW_COPY_AND_ASSIGN(MessagePumpGLibTest);
-};
-
-} // namespace
-
-TEST_F(MessagePumpGLibTest, TestQuit) {
- // Checks that Quit works and that the basic infrastructure is working.
-
- // Quit from a task
- RunLoop().RunUntilIdle();
- EXPECT_EQ(0, injector()->processed_events());
-
- injector()->Reset();
- // Quit from an event
- injector()->AddEvent(0, MessageLoop::QuitWhenIdleClosure());
- loop()->Run();
- EXPECT_EQ(1, injector()->processed_events());
-}
-
-TEST_F(MessagePumpGLibTest, TestEventTaskInterleave) {
- // Checks that tasks posted by events are executed before the next event if
- // the posted task queue is empty.
- // MessageLoop doesn't make strong guarantees that it is the case, but the
- // current implementation ensures it and the tests below rely on it.
- // If changes cause this test to fail, it is reasonable to change it, but
- // TestWorkWhileWaitingForEvents and TestEventsWhileWaitingForWork have to be
- // changed accordingly, otherwise they can become flaky.
- injector()->AddEventAsTask(0, Bind(&DoNothing));
- Closure check_task =
- Bind(&ExpectProcessedEvents, Unretained(injector()), 2);
- Closure posted_task =
- Bind(&PostMessageLoopTask, FROM_HERE, check_task);
- injector()->AddEventAsTask(0, posted_task);
- injector()->AddEventAsTask(0, Bind(&DoNothing));
- injector()->AddEvent(0, MessageLoop::QuitWhenIdleClosure());
- loop()->Run();
- EXPECT_EQ(4, injector()->processed_events());
-
- injector()->Reset();
- injector()->AddEventAsTask(0, Bind(&DoNothing));
- check_task =
- Bind(&ExpectProcessedEvents, Unretained(injector()), 2);
- posted_task = Bind(&PostMessageLoopTask, FROM_HERE, check_task);
- injector()->AddEventAsTask(0, posted_task);
- injector()->AddEventAsTask(10, Bind(&DoNothing));
- injector()->AddEvent(0, MessageLoop::QuitWhenIdleClosure());
- loop()->Run();
- EXPECT_EQ(4, injector()->processed_events());
-}
-
-TEST_F(MessagePumpGLibTest, TestWorkWhileWaitingForEvents) {
- int task_count = 0;
- // Tests that we process tasks while waiting for new events.
- // The event queue is empty at first.
- for (int i = 0; i < 10; ++i) {
- loop()->PostTask(FROM_HERE, Bind(&IncrementInt, &task_count));
- }
- // After all the previous tasks have executed, enqueue an event that will
- // quit.
- loop()->PostTask(
- FROM_HERE,
- Bind(&EventInjector::AddEvent, Unretained(injector()), 0,
- MessageLoop::QuitWhenIdleClosure()));
- loop()->Run();
- ASSERT_EQ(10, task_count);
- EXPECT_EQ(1, injector()->processed_events());
-
- // Tests that we process delayed tasks while waiting for new events.
- injector()->Reset();
- task_count = 0;
- for (int i = 0; i < 10; ++i) {
- loop()->PostDelayedTask(
- FROM_HERE,
- Bind(&IncrementInt, &task_count),
- TimeDelta::FromMilliseconds(10*i));
- }
- // After all the previous tasks have executed, enqueue an event that will
- // quit.
- // This relies on the fact that delayed tasks are executed in delay order.
- // That is verified in message_loop_unittest.cc.
- loop()->PostDelayedTask(
- FROM_HERE,
- Bind(&EventInjector::AddEvent, Unretained(injector()), 10,
- MessageLoop::QuitWhenIdleClosure()),
- TimeDelta::FromMilliseconds(150));
- loop()->Run();
- ASSERT_EQ(10, task_count);
- EXPECT_EQ(1, injector()->processed_events());
-}
-
-TEST_F(MessagePumpGLibTest, TestEventsWhileWaitingForWork) {
- // Tests that we process events while waiting for work.
- // The event queue is empty at first.
- for (int i = 0; i < 10; ++i) {
- injector()->AddDummyEvent(0);
- }
- // After all the events have been processed, post a task that will check that
- // the events have been processed (note: the task executes after the event
- // that posted it has been handled, so we expect 11 at that point).
- Closure check_task =
- Bind(&ExpectProcessedEvents, Unretained(injector()), 11);
- Closure posted_task =
- Bind(&PostMessageLoopTask, FROM_HERE, check_task);
- injector()->AddEventAsTask(10, posted_task);
-
- // And then quit (relies on the condition tested by TestEventTaskInterleave).
- injector()->AddEvent(10, MessageLoop::QuitWhenIdleClosure());
- loop()->Run();
-
- EXPECT_EQ(12, injector()->processed_events());
-}
-
-namespace {
-
-// This class is a helper for the concurrent events / posted tasks test below.
-// It will quit the main loop once enough tasks and events have been processed,
-// while making sure there is always work to do and events in the queue.
-class ConcurrentHelper : public RefCounted<ConcurrentHelper> {
- public:
- explicit ConcurrentHelper(EventInjector* injector)
- : injector_(injector),
- event_count_(kStartingEventCount),
- task_count_(kStartingTaskCount) {
- }
-
- void FromTask() {
- if (task_count_ > 0) {
- --task_count_;
- }
- if (task_count_ == 0 && event_count_ == 0) {
- MessageLoop::current()->QuitWhenIdle();
- } else {
- MessageLoop::current()->PostTask(
- FROM_HERE, Bind(&ConcurrentHelper::FromTask, this));
- }
- }
-
- void FromEvent() {
- if (event_count_ > 0) {
- --event_count_;
- }
- if (task_count_ == 0 && event_count_ == 0) {
- MessageLoop::current()->QuitWhenIdle();
- } else {
- injector_->AddEventAsTask(
- 0, Bind(&ConcurrentHelper::FromEvent, this));
- }
- }
-
- int event_count() const { return event_count_; }
- int task_count() const { return task_count_; }
-
- private:
- friend class RefCounted<ConcurrentHelper>;
-
- ~ConcurrentHelper() {}
-
- static const int kStartingEventCount = 20;
- static const int kStartingTaskCount = 20;
-
- EventInjector* injector_;
- int event_count_;
- int task_count_;
-};
-
-} // namespace
-
-TEST_F(MessagePumpGLibTest, TestConcurrentEventPostedTask) {
- // Tests that posted tasks don't starve events, nor the opposite.
- // We use the helper class above. We keep both event and posted task queues
- // full, the helper verifies that both tasks and events get processed.
- // If that is not the case, either event_count_ or task_count_ will not get
- // to 0, and MessageLoop::QuitWhenIdle() will never be called.
- scoped_refptr<ConcurrentHelper> helper = new ConcurrentHelper(injector());
-
- // Add 2 events to the queue to make sure it is always full (when we remove
- // the event before processing it).
- injector()->AddEventAsTask(
- 0, Bind(&ConcurrentHelper::FromEvent, helper.get()));
- injector()->AddEventAsTask(
- 0, Bind(&ConcurrentHelper::FromEvent, helper.get()));
-
- // Similarly post 2 tasks.
- loop()->PostTask(
- FROM_HERE, Bind(&ConcurrentHelper::FromTask, helper.get()));
- loop()->PostTask(
- FROM_HERE, Bind(&ConcurrentHelper::FromTask, helper.get()));
-
- loop()->Run();
- EXPECT_EQ(0, helper->event_count());
- EXPECT_EQ(0, helper->task_count());
-}
-
-namespace {
-
-void AddEventsAndDrainGLib(EventInjector* injector) {
- // Add a couple of dummy events
- injector->AddDummyEvent(0);
- injector->AddDummyEvent(0);
- // Then add an event that will quit the main loop.
- injector->AddEvent(0, MessageLoop::QuitWhenIdleClosure());
-
- // Post a couple of dummy tasks
- MessageLoop::current()->PostTask(FROM_HERE, Bind(&DoNothing));
- MessageLoop::current()->PostTask(FROM_HERE, Bind(&DoNothing));
-
- // Drain the events
- while (g_main_context_pending(NULL)) {
- g_main_context_iteration(NULL, FALSE);
- }
-}
-
-} // namespace
-
-TEST_F(MessagePumpGLibTest, TestDrainingGLib) {
- // Tests that draining events using GLib works.
- loop()->PostTask(
- FROM_HERE,
- Bind(&AddEventsAndDrainGLib, Unretained(injector())));
- loop()->Run();
-
- EXPECT_EQ(3, injector()->processed_events());
-}
-
-
-namespace {
-
-#if defined(TOOLKIT_GTK)
-void AddEventsAndDrainGtk(EventInjector* injector) {
- // Add a couple of dummy events
- injector->AddDummyEvent(0);
- injector->AddDummyEvent(0);
- // Then add an event that will quit the main loop.
- injector->AddEvent(0, MessageLoop::QuitWhenIdleClosure());
-
- // Post a couple of dummy tasks
- MessageLoop::current()->PostTask(FROM_HERE, Bind(&DoNothing));
- MessageLoop::current()->PostTask(FROM_HERE, Bind(&DoNothing));
-
- // Drain the events
- while (gtk_events_pending()) {
- gtk_main_iteration();
- }
-}
-#endif
-
-} // namespace
-
-#if defined(TOOLKIT_GTK)
-TEST_F(MessagePumpGLibTest, TestDrainingGtk) {
- // Tests that draining events using Gtk works.
- loop()->PostTask(
- FROM_HERE,
- Bind(&AddEventsAndDrainGtk, Unretained(injector())));
- loop()->Run();
-
- EXPECT_EQ(3, injector()->processed_events());
-}
-#endif
-
-namespace {
-
-// Helper class that lets us run the GLib message loop.
-class GLibLoopRunner : public RefCounted<GLibLoopRunner> {
- public:
- GLibLoopRunner() : quit_(false) { }
-
- void RunGLib() {
- while (!quit_) {
- g_main_context_iteration(NULL, TRUE);
- }
- }
-
- void RunLoop() {
-#if defined(TOOLKIT_GTK)
- while (!quit_) {
- gtk_main_iteration();
- }
-#else
- while (!quit_) {
- g_main_context_iteration(NULL, TRUE);
- }
-#endif
- }
-
- void Quit() {
- quit_ = true;
- }
-
- void Reset() {
- quit_ = false;
- }
-
- private:
- friend class RefCounted<GLibLoopRunner>;
-
- ~GLibLoopRunner() {}
-
- bool quit_;
-};
-
-void TestGLibLoopInternal(EventInjector* injector) {
- // Allow tasks to be processed from 'native' event loops.
- MessageLoop::current()->SetNestableTasksAllowed(true);
- scoped_refptr<GLibLoopRunner> runner = new GLibLoopRunner();
-
- int task_count = 0;
- // Add a couple of dummy events
- injector->AddDummyEvent(0);
- injector->AddDummyEvent(0);
- // Post a couple of dummy tasks
- MessageLoop::current()->PostTask(
- FROM_HERE, Bind(&IncrementInt, &task_count));
- MessageLoop::current()->PostTask(
- FROM_HERE, Bind(&IncrementInt, &task_count));
- // Delayed events
- injector->AddDummyEvent(10);
- injector->AddDummyEvent(10);
- // Delayed work
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- Bind(&IncrementInt, &task_count),
- TimeDelta::FromMilliseconds(30));
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- Bind(&GLibLoopRunner::Quit, runner.get()),
- TimeDelta::FromMilliseconds(40));
-
- // Run a nested, straight GLib message loop.
- runner->RunGLib();
-
- ASSERT_EQ(3, task_count);
- EXPECT_EQ(4, injector->processed_events());
- MessageLoop::current()->QuitWhenIdle();
-}
-
-void TestGtkLoopInternal(EventInjector* injector) {
- // Allow tasks to be processed from 'native' event loops.
- MessageLoop::current()->SetNestableTasksAllowed(true);
- scoped_refptr<GLibLoopRunner> runner = new GLibLoopRunner();
-
- int task_count = 0;
- // Add a couple of dummy events
- injector->AddDummyEvent(0);
- injector->AddDummyEvent(0);
- // Post a couple of dummy tasks
- MessageLoop::current()->PostTask(
- FROM_HERE, Bind(&IncrementInt, &task_count));
- MessageLoop::current()->PostTask(
- FROM_HERE, Bind(&IncrementInt, &task_count));
- // Delayed events
- injector->AddDummyEvent(10);
- injector->AddDummyEvent(10);
- // Delayed work
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- Bind(&IncrementInt, &task_count),
- TimeDelta::FromMilliseconds(30));
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- Bind(&GLibLoopRunner::Quit, runner.get()),
- TimeDelta::FromMilliseconds(40));
-
- // Run a nested, straight Gtk message loop.
- runner->RunLoop();
-
- ASSERT_EQ(3, task_count);
- EXPECT_EQ(4, injector->processed_events());
- MessageLoop::current()->QuitWhenIdle();
-}
-
-} // namespace
-
-TEST_F(MessagePumpGLibTest, TestGLibLoop) {
- // Tests that events and posted tasks are correctly executed if the message
- // loop is not run by MessageLoop::Run() but by a straight GLib loop.
- // Note that in this case we don't make strong guarantees about niceness
- // between events and posted tasks.
- loop()->PostTask(
- FROM_HERE,
- Bind(&TestGLibLoopInternal, Unretained(injector())));
- loop()->Run();
-}
-
-TEST_F(MessagePumpGLibTest, TestGtkLoop) {
- // Tests that events and posted tasks are correctly executed if the message
- // loop is not run by MessageLoop::Run() but by a straight Gtk loop.
- // Note that in this case we don't make strong guarantees about niceness
- // between events and posted tasks.
- loop()->PostTask(
- FROM_HERE,
- Bind(&TestGtkLoopInternal, Unretained(injector())));
- loop()->Run();
-}
-
-} // namespace base
diff --git a/base/message_loop/message_pump_gtk.cc b/base/message_loop/message_pump_gtk.cc
deleted file mode 100644
index 8fa8cf2..0000000
--- a/base/message_loop/message_pump_gtk.cc
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/message_loop/message_pump_gtk.h"
-
-#include <gtk/gtk.h>
-#include <gdk/gdkx.h>
-
-#include "base/debug/trace_event.h"
-#include "base/profiler/scoped_profile.h"
-
-namespace base {
-
-namespace {
-
-const char* EventToTypeString(const GdkEvent* event) {
- switch (event->type) {
- case GDK_NOTHING: return "GDK_NOTHING";
- case GDK_DELETE: return "GDK_DELETE";
- case GDK_DESTROY: return "GDK_DESTROY";
- case GDK_EXPOSE: return "GDK_EXPOSE";
- case GDK_MOTION_NOTIFY: return "GDK_MOTION_NOTIFY";
- case GDK_BUTTON_PRESS: return "GDK_BUTTON_PRESS";
- case GDK_2BUTTON_PRESS: return "GDK_2BUTTON_PRESS";
- case GDK_3BUTTON_PRESS: return "GDK_3BUTTON_PRESS";
- case GDK_BUTTON_RELEASE: return "GDK_BUTTON_RELEASE";
- case GDK_KEY_PRESS: return "GDK_KEY_PRESS";
- case GDK_KEY_RELEASE: return "GDK_KEY_RELEASE";
- case GDK_ENTER_NOTIFY: return "GDK_ENTER_NOTIFY";
- case GDK_LEAVE_NOTIFY: return "GDK_LEAVE_NOTIFY";
- case GDK_FOCUS_CHANGE: return "GDK_FOCUS_CHANGE";
- case GDK_CONFIGURE: return "GDK_CONFIGURE";
- case GDK_MAP: return "GDK_MAP";
- case GDK_UNMAP: return "GDK_UNMAP";
- case GDK_PROPERTY_NOTIFY: return "GDK_PROPERTY_NOTIFY";
- case GDK_SELECTION_CLEAR: return "GDK_SELECTION_CLEAR";
- case GDK_SELECTION_REQUEST: return "GDK_SELECTION_REQUEST";
- case GDK_SELECTION_NOTIFY: return "GDK_SELECTION_NOTIFY";
- case GDK_PROXIMITY_IN: return "GDK_PROXIMITY_IN";
- case GDK_PROXIMITY_OUT: return "GDK_PROXIMITY_OUT";
- case GDK_DRAG_ENTER: return "GDK_DRAG_ENTER";
- case GDK_DRAG_LEAVE: return "GDK_DRAG_LEAVE";
- case GDK_DRAG_MOTION: return "GDK_DRAG_MOTION";
- case GDK_DRAG_STATUS: return "GDK_DRAG_STATUS";
- case GDK_DROP_START: return "GDK_DROP_START";
- case GDK_DROP_FINISHED: return "GDK_DROP_FINISHED";
- case GDK_CLIENT_EVENT: return "GDK_CLIENT_EVENT";
- case GDK_VISIBILITY_NOTIFY: return "GDK_VISIBILITY_NOTIFY";
- case GDK_NO_EXPOSE: return "GDK_NO_EXPOSE";
- case GDK_SCROLL: return "GDK_SCROLL";
- case GDK_WINDOW_STATE: return "GDK_WINDOW_STATE";
- case GDK_SETTING: return "GDK_SETTING";
- case GDK_OWNER_CHANGE: return "GDK_OWNER_CHANGE";
- case GDK_GRAB_BROKEN: return "GDK_GRAB_BROKEN";
- case GDK_DAMAGE: return "GDK_DAMAGE";
- default:
- return "Unknown Gdk Event";
- }
-}
-
-} // namespace
-
-MessagePumpGtk::MessagePumpGtk() : MessagePumpGlib() {
- gdk_event_handler_set(&EventDispatcher, this, NULL);
-}
-
-void MessagePumpGtk::DispatchEvents(GdkEvent* event) {
- UNSHIPPED_TRACE_EVENT1("task", "MessagePumpGtk::DispatchEvents",
- "type", EventToTypeString(event));
-
- WillProcessEvent(event);
-
- MessagePumpDispatcher* dispatcher = GetDispatcher();
- if (!dispatcher)
- gtk_main_do_event(event);
- else if (!dispatcher->Dispatch(event))
- Quit();
-
- DidProcessEvent(event);
-}
-
-// static
-Display* MessagePumpGtk::GetDefaultXDisplay() {
- static GdkDisplay* display = gdk_display_get_default();
- if (!display) {
- // GTK / GDK has not been initialized, which is a decision we wish to
- // support, for example for the GPU process.
- static Display* xdisplay = XOpenDisplay(NULL);
- return xdisplay;
- }
- return GDK_DISPLAY_XDISPLAY(display);
-}
-
-MessagePumpGtk::~MessagePumpGtk() {
- gdk_event_handler_set(reinterpret_cast<GdkEventFunc>(gtk_main_do_event),
- this, NULL);
-}
-
-void MessagePumpGtk::WillProcessEvent(GdkEvent* event) {
- FOR_EACH_OBSERVER(MessagePumpObserver, observers(), WillProcessEvent(event));
-}
-
-void MessagePumpGtk::DidProcessEvent(GdkEvent* event) {
- FOR_EACH_OBSERVER(MessagePumpObserver, observers(), DidProcessEvent(event));
-}
-
-// static
-void MessagePumpGtk::EventDispatcher(GdkEvent* event, gpointer data) {
- MessagePumpGtk* message_pump = reinterpret_cast<MessagePumpGtk*>(data);
- message_pump->DispatchEvents(event);
-}
-
-} // namespace base
diff --git a/base/message_loop/message_pump_gtk.h b/base/message_loop/message_pump_gtk.h
deleted file mode 100644
index e22e04f..0000000
--- a/base/message_loop/message_pump_gtk.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_MESSAGE_LOOP_MESSAGE_PUMP_GTK_H_
-#define BASE_MESSAGE_LOOP_MESSAGE_PUMP_GTK_H_
-
-#include "base/message_loop/message_pump_glib.h"
-
-typedef union _GdkEvent GdkEvent;
-typedef struct _XDisplay Display;
-
-namespace base {
-
-// The documentation for this class is in message_pump_glib.h
-class MessagePumpObserver {
- public:
- // This method is called before processing a message.
- virtual void WillProcessEvent(GdkEvent* event) = 0;
-
- // This method is called after processing a message.
- virtual void DidProcessEvent(GdkEvent* event) = 0;
-
- protected:
- virtual ~MessagePumpObserver() {}
-};
-
-// The documentation for this class is in message_pump_glib.h
-//
-// The nested loop is exited by either posting a quit, or returning false
-// from Dispatch.
-class MessagePumpDispatcher {
- public:
- // Dispatches the event. If true is returned processing continues as
- // normal. If false is returned, the nested loop exits immediately.
- virtual bool Dispatch(GdkEvent* event) = 0;
-
- protected:
- virtual ~MessagePumpDispatcher() {}
-};
-
-// This class implements a message-pump for dispatching GTK events.
-class BASE_EXPORT MessagePumpGtk : public MessagePumpGlib {
- public:
- MessagePumpGtk();
-
- // Dispatch an available GdkEvent. Essentially this allows a subclass to do
- // some task before/after calling the default handler (EventDispatcher).
- void DispatchEvents(GdkEvent* event);
-
- // Returns default X Display.
- static Display* GetDefaultXDisplay();
-
- protected:
- virtual ~MessagePumpGtk();
-
- private:
- // Invoked from EventDispatcher. Notifies all observers we're about to
- // process an event.
- void WillProcessEvent(GdkEvent* event);
-
- // Invoked from EventDispatcher. Notifies all observers we processed an
- // event.
- void DidProcessEvent(GdkEvent* event);
-
- // Callback prior to gdk dispatching an event.
- static void EventDispatcher(GdkEvent* event, void* data);
-
- DISALLOW_COPY_AND_ASSIGN(MessagePumpGtk);
-};
-
-typedef MessagePumpGtk MessagePumpForUI;
-
-} // namespace base
-
-#endif // BASE_MESSAGE_LOOP_MESSAGE_PUMP_GTK_H_
diff --git a/base/message_loop/message_pump_libevent.cc b/base/message_loop/message_pump_libevent.cc
deleted file mode 100644
index 8de0db2..0000000
--- a/base/message_loop/message_pump_libevent.cc
+++ /dev/null
@@ -1,375 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/message_loop/message_pump_libevent.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include "base/auto_reset.h"
-#include "base/compiler_specific.h"
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/observer_list.h"
-#include "base/posix/eintr_wrapper.h"
-#include "base/time.h"
-#include "third_party/libevent/event.h"
-
-#if defined(OS_MACOSX)
-#include "base/mac/scoped_nsautorelease_pool.h"
-#endif
-
-// 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
-// Too small a function to bother putting in a library?
-static int SetNonBlocking(int fd) {
- int flags = fcntl(fd, F_GETFL, 0);
- if (flags == -1)
- flags = 0;
- return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
-}
-
-MessagePumpLibevent::FileDescriptorWatcher::FileDescriptorWatcher()
- : event_(NULL),
- pump_(NULL),
- watcher_(NULL),
- weak_factory_(this) {
-}
-
-MessagePumpLibevent::FileDescriptorWatcher::~FileDescriptorWatcher() {
- if (event_) {
- StopWatchingFileDescriptor();
- }
-}
-
-bool MessagePumpLibevent::FileDescriptorWatcher::StopWatchingFileDescriptor() {
- event* e = ReleaseEvent();
- if (e == NULL)
- return true;
-
- // event_del() is a no-op if the event isn't active.
- int rv = event_del(e);
- delete e;
- pump_ = NULL;
- watcher_ = NULL;
- return (rv == 0);
-}
-
-void MessagePumpLibevent::FileDescriptorWatcher::Init(event *e) {
- DCHECK(e);
- DCHECK(!event_);
-
- event_ = e;
-}
-
-event *MessagePumpLibevent::FileDescriptorWatcher::ReleaseEvent() {
- struct event *e = event_;
- event_ = NULL;
- return e;
-}
-
-void MessagePumpLibevent::FileDescriptorWatcher::OnFileCanReadWithoutBlocking(
- int fd, MessagePumpLibevent* pump) {
- // Since OnFileCanWriteWithoutBlocking() gets called first, it can stop
- // watching the file descriptor.
- if (!watcher_)
- return;
- pump->WillProcessIOEvent();
- watcher_->OnFileCanReadWithoutBlocking(fd);
- pump->DidProcessIOEvent();
-}
-
-void MessagePumpLibevent::FileDescriptorWatcher::OnFileCanWriteWithoutBlocking(
- int fd, MessagePumpLibevent* pump) {
- DCHECK(watcher_);
- pump->WillProcessIOEvent();
- watcher_->OnFileCanWriteWithoutBlocking(fd);
- pump->DidProcessIOEvent();
-}
-
-MessagePumpLibevent::MessagePumpLibevent()
- : keep_running_(true),
- in_run_(false),
- processed_io_events_(false),
- event_base_(event_base_new()),
- wakeup_pipe_in_(-1),
- wakeup_pipe_out_(-1) {
- if (!Init())
- NOTREACHED();
-}
-
-MessagePumpLibevent::~MessagePumpLibevent() {
- DCHECK(wakeup_event_);
- DCHECK(event_base_);
- event_del(wakeup_event_);
- delete wakeup_event_;
- if (wakeup_pipe_in_ >= 0) {
- if (HANDLE_EINTR(close(wakeup_pipe_in_)) < 0)
- DPLOG(ERROR) << "close";
- }
- if (wakeup_pipe_out_ >= 0) {
- if (HANDLE_EINTR(close(wakeup_pipe_out_)) < 0)
- DPLOG(ERROR) << "close";
- }
- event_base_free(event_base_);
-}
-
-bool MessagePumpLibevent::WatchFileDescriptor(int fd,
- bool persistent,
- int mode,
- FileDescriptorWatcher *controller,
- Watcher *delegate) {
- DCHECK_GE(fd, 0);
- DCHECK(controller);
- DCHECK(delegate);
- DCHECK(mode == WATCH_READ || mode == WATCH_WRITE || mode == WATCH_READ_WRITE);
- // WatchFileDescriptor should be called on the pump thread. It is not
- // threadsafe, and your watcher may never be registered.
- DCHECK(watch_file_descriptor_caller_checker_.CalledOnValidThread());
-
- int event_mask = persistent ? EV_PERSIST : 0;
- if (mode & WATCH_READ) {
- event_mask |= EV_READ;
- }
- if (mode & WATCH_WRITE) {
- event_mask |= EV_WRITE;
- }
-
- scoped_ptr<event> evt(controller->ReleaseEvent());
- if (evt.get() == NULL) {
- // Ownership is transferred to the controller.
- evt.reset(new event);
- } else {
- // Make sure we don't pick up any funky internal libevent masks.
- int old_interest_mask = evt.get()->ev_events &
- (EV_READ | EV_WRITE | EV_PERSIST);
-
- // Combine old/new event masks.
- event_mask |= old_interest_mask;
-
- // Must disarm the event before we can reuse it.
- event_del(evt.get());
-
- // It's illegal to use this function to listen on 2 separate fds with the
- // same |controller|.
- if (EVENT_FD(evt.get()) != fd) {
- NOTREACHED() << "FDs don't match" << EVENT_FD(evt.get()) << "!=" << fd;
- return false;
- }
- }
-
- // Set current interest mask and message pump for this event.
- event_set(evt.get(), fd, event_mask, OnLibeventNotification, controller);
-
- // Tell libevent which message pump this socket will belong to when we add it.
- if (event_base_set(event_base_, evt.get())) {
- return false;
- }
-
- // Add this socket to the list of monitored sockets.
- if (event_add(evt.get(), NULL)) {
- return false;
- }
-
- // Transfer ownership of evt to controller.
- controller->Init(evt.release());
-
- controller->set_watcher(delegate);
- controller->set_pump(this);
-
- return true;
-}
-
-void MessagePumpLibevent::AddIOObserver(IOObserver *obs) {
- io_observers_.AddObserver(obs);
-}
-
-void MessagePumpLibevent::RemoveIOObserver(IOObserver *obs) {
- io_observers_.RemoveObserver(obs);
-}
-
-// Tell libevent to break out of inner loop.
-static void timer_callback(int fd, short events, void *context)
-{
- event_base_loopbreak((struct event_base *)context);
-}
-
-// Reentrant!
-void MessagePumpLibevent::Run(Delegate* delegate) {
- DCHECK(keep_running_) << "Quit must have been called outside of Run!";
- AutoReset<bool> auto_reset_in_run(&in_run_, true);
-
- // event_base_loopexit() + EVLOOP_ONCE is leaky, see http://crbug.com/25641.
- // Instead, make our own timer and reuse it on each call to event_base_loop().
- scoped_ptr<event> timer_event(new event);
-
- for (;;) {
-#if defined(OS_MACOSX)
- mac::ScopedNSAutoreleasePool autorelease_pool;
-#endif
-
- bool did_work = delegate->DoWork();
- if (!keep_running_)
- break;
-
- event_base_loop(event_base_, EVLOOP_NONBLOCK);
- did_work |= processed_io_events_;
- processed_io_events_ = false;
- if (!keep_running_)
- break;
-
- did_work |= delegate->DoDelayedWork(&delayed_work_time_);
- if (!keep_running_)
- break;
-
- if (did_work)
- continue;
-
- did_work = delegate->DoIdleWork();
- if (!keep_running_)
- break;
-
- if (did_work)
- continue;
-
- // EVLOOP_ONCE tells libevent to only block once,
- // but to service all pending events when it wakes up.
- if (delayed_work_time_.is_null()) {
- event_base_loop(event_base_, EVLOOP_ONCE);
- } else {
- TimeDelta delay = delayed_work_time_ - TimeTicks::Now();
- if (delay > TimeDelta()) {
- struct timeval poll_tv;
- poll_tv.tv_sec = delay.InSeconds();
- poll_tv.tv_usec = delay.InMicroseconds() % Time::kMicrosecondsPerSecond;
- event_set(timer_event.get(), -1, 0, timer_callback, event_base_);
- event_base_set(event_base_, timer_event.get());
- event_add(timer_event.get(), &poll_tv);
- event_base_loop(event_base_, EVLOOP_ONCE);
- event_del(timer_event.get());
- } else {
- // It looks like delayed_work_time_ indicates a time in the past, so we
- // need to call DoDelayedWork now.
- delayed_work_time_ = TimeTicks();
- }
- }
- }
-
- keep_running_ = true;
-}
-
-void MessagePumpLibevent::Quit() {
- DCHECK(in_run_);
- // Tell both libevent and Run that they should break out of their loops.
- keep_running_ = false;
- ScheduleWork();
-}
-
-void MessagePumpLibevent::ScheduleWork() {
- // Tell libevent (in a threadsafe way) that it should break out of its loop.
- char buf = 0;
- int nwrite = HANDLE_EINTR(write(wakeup_pipe_in_, &buf, 1));
- DCHECK(nwrite == 1 || errno == EAGAIN)
- << "[nwrite:" << nwrite << "] [errno:" << errno << "]";
-}
-
-void MessagePumpLibevent::ScheduleDelayedWork(
- const TimeTicks& delayed_work_time) {
- // We know that we can't be blocked on Wait right now since this method can
- // only be called on the same thread as Run, so we only need to update our
- // record of how long to sleep when we do sleep.
- delayed_work_time_ = delayed_work_time;
-}
-
-void MessagePumpLibevent::WillProcessIOEvent() {
- FOR_EACH_OBSERVER(IOObserver, io_observers_, WillProcessIOEvent());
-}
-
-void MessagePumpLibevent::DidProcessIOEvent() {
- FOR_EACH_OBSERVER(IOObserver, io_observers_, DidProcessIOEvent());
-}
-
-bool MessagePumpLibevent::Init() {
- int fds[2];
- if (pipe(fds)) {
- DLOG(ERROR) << "pipe() failed, errno: " << errno;
- return false;
- }
- if (SetNonBlocking(fds[0])) {
- DLOG(ERROR) << "SetNonBlocking for pipe fd[0] failed, errno: " << errno;
- return false;
- }
- if (SetNonBlocking(fds[1])) {
- DLOG(ERROR) << "SetNonBlocking for pipe fd[1] failed, errno: " << errno;
- return false;
- }
- wakeup_pipe_out_ = fds[0];
- wakeup_pipe_in_ = fds[1];
-
- wakeup_event_ = new event;
- event_set(wakeup_event_, wakeup_pipe_out_, EV_READ | EV_PERSIST,
- OnWakeup, this);
- event_base_set(event_base_, wakeup_event_);
-
- if (event_add(wakeup_event_, 0))
- return false;
- return true;
-}
-
-// static
-void MessagePumpLibevent::OnLibeventNotification(int fd, short flags,
- void* context) {
- WeakPtr<FileDescriptorWatcher> controller =
- static_cast<FileDescriptorWatcher*>(context)->weak_factory_.GetWeakPtr();
- DCHECK(controller.get());
-
- MessagePumpLibevent* pump = controller->pump();
- pump->processed_io_events_ = true;
-
- if (flags & EV_WRITE) {
- controller->OnFileCanWriteWithoutBlocking(fd, pump);
- }
- // Check |controller| in case it's been deleted in
- // controller->OnFileCanWriteWithoutBlocking().
- if (controller.get() && flags & EV_READ) {
- controller->OnFileCanReadWithoutBlocking(fd, pump);
- }
-}
-
-// Called if a byte is received on the wakeup pipe.
-// static
-void MessagePumpLibevent::OnWakeup(int socket, short flags, void* context) {
- MessagePumpLibevent* that = static_cast<MessagePumpLibevent*>(context);
- DCHECK(that->wakeup_pipe_out_ == socket);
-
- // Remove and discard the wakeup byte.
- char buf;
- int nread = HANDLE_EINTR(read(socket, &buf, 1));
- DCHECK_EQ(nread, 1);
- that->processed_io_events_ = true;
- // Tell libevent to break out of inner loop.
- event_base_loopbreak(that->event_base_);
-}
-
-} // namespace base
diff --git a/base/message_loop/message_pump_libevent.h b/base/message_loop/message_pump_libevent.h
deleted file mode 100644
index a54ef88..0000000
--- a/base/message_loop/message_pump_libevent.h
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_MESSAGE_LOOP_MESSAGE_PUMP_LIBEVENT_H_
-#define BASE_MESSAGE_LOOP_MESSAGE_PUMP_LIBEVENT_H_
-
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "base/memory/weak_ptr.h"
-#include "base/message_loop/message_pump.h"
-#include "base/observer_list.h"
-#include "base/threading/thread_checker.h"
-#include "base/time.h"
-
-// Declare structs we need from libevent.h rather than including it
-struct event_base;
-struct event;
-
-namespace base {
-
-// Class to monitor sockets and issue callbacks when sockets are ready for I/O
-// TODO(dkegel): add support for background file IO somehow
-class BASE_EXPORT MessagePumpLibevent : public MessagePump {
- public:
- class IOObserver {
- public:
- IOObserver() {}
-
- // An IOObserver is an object that receives IO notifications from the
- // MessagePump.
- //
- // NOTE: An IOObserver implementation should be extremely fast!
- virtual void WillProcessIOEvent() = 0;
- virtual void DidProcessIOEvent() = 0;
-
- protected:
- virtual ~IOObserver() {}
- };
-
- // Used with WatchFileDescriptor to asynchronously monitor the I/O readiness
- // of a file descriptor.
- class Watcher {
- public:
- // Called from MessageLoop::Run when an FD can be read from/written to
- // without blocking
- virtual void OnFileCanReadWithoutBlocking(int fd) = 0;
- virtual void OnFileCanWriteWithoutBlocking(int fd) = 0;
-
- protected:
- virtual ~Watcher() {}
- };
-
- // Object returned by WatchFileDescriptor to manage further watching.
- class FileDescriptorWatcher {
- public:
- FileDescriptorWatcher();
- ~FileDescriptorWatcher(); // Implicitly calls StopWatchingFileDescriptor.
-
- // NOTE: These methods aren't called StartWatching()/StopWatching() to
- // avoid confusion with the win32 ObjectWatcher class.
-
- // Stop watching the FD, always safe to call. No-op if there's nothing
- // to do.
- bool StopWatchingFileDescriptor();
-
- private:
- friend class MessagePumpLibevent;
- friend class MessagePumpLibeventTest;
-
- // Called by MessagePumpLibevent, ownership of |e| is transferred to this
- // object.
- void Init(event* e);
-
- // Used by MessagePumpLibevent to take ownership of event_.
- event* ReleaseEvent();
-
- void set_pump(MessagePumpLibevent* pump) { pump_ = pump; }
- MessagePumpLibevent* pump() const { return pump_; }
-
- void set_watcher(Watcher* watcher) { watcher_ = watcher; }
-
- void OnFileCanReadWithoutBlocking(int fd, MessagePumpLibevent* pump);
- void OnFileCanWriteWithoutBlocking(int fd, MessagePumpLibevent* pump);
-
- event* event_;
- MessagePumpLibevent* pump_;
- Watcher* watcher_;
- WeakPtrFactory<FileDescriptorWatcher> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(FileDescriptorWatcher);
- };
-
- enum Mode {
- WATCH_READ = 1 << 0,
- WATCH_WRITE = 1 << 1,
- WATCH_READ_WRITE = WATCH_READ | WATCH_WRITE
- };
-
- MessagePumpLibevent();
-
- // Have the current thread's message loop watch for a a situation in which
- // reading/writing to the FD can be performed without blocking.
- // Callers must provide a preallocated FileDescriptorWatcher object which
- // can later be used to manage the lifetime of this event.
- // If a FileDescriptorWatcher is passed in which is already attached to
- // an event, then the effect is cumulative i.e. after the call |controller|
- // will watch both the previous event and the new one.
- // If an error occurs while calling this method in a cumulative fashion, the
- // event previously attached to |controller| is aborted.
- // Returns true on success.
- // Must be called on the same thread the message_pump is running on.
- // TODO(dkegel): switch to edge-triggered readiness notification
- bool WatchFileDescriptor(int fd,
- bool persistent,
- int mode,
- FileDescriptorWatcher *controller,
- Watcher *delegate);
-
- void AddIOObserver(IOObserver* obs);
- void RemoveIOObserver(IOObserver* obs);
-
- // MessagePump methods:
- virtual void Run(Delegate* delegate) OVERRIDE;
- virtual void Quit() OVERRIDE;
- virtual void ScheduleWork() OVERRIDE;
- virtual void ScheduleDelayedWork(const TimeTicks& delayed_work_time) OVERRIDE;
-
- protected:
- virtual ~MessagePumpLibevent();
-
- private:
- friend class MessagePumpLibeventTest;
-
- void WillProcessIOEvent();
- void DidProcessIOEvent();
-
- // Risky part of constructor. Returns true on success.
- bool Init();
-
- // Called by libevent to tell us a registered FD can be read/written to.
- static void OnLibeventNotification(int fd, short flags,
- void* context);
-
- // Unix pipe used to implement ScheduleWork()
- // ... callback; called by libevent inside Run() when pipe is ready to read
- static void OnWakeup(int socket, short flags, void* context);
-
- // This flag is set to false when Run should return.
- bool keep_running_;
-
- // This flag is set when inside Run.
- bool in_run_;
-
- // This flag is set if libevent has processed I/O events.
- bool processed_io_events_;
-
- // The time at which we should call DoDelayedWork.
- TimeTicks delayed_work_time_;
-
- // Libevent dispatcher. Watches all sockets registered with it, and sends
- // readiness callbacks when a socket is ready for I/O.
- event_base* event_base_;
-
- // ... write end; ScheduleWork() writes a single byte to it
- int wakeup_pipe_in_;
- // ... read end; OnWakeup reads it and then breaks Run() out of its sleep
- int wakeup_pipe_out_;
- // ... libevent wrapper for read end
- event* wakeup_event_;
-
- ObserverList<IOObserver> io_observers_;
- ThreadChecker watch_file_descriptor_caller_checker_;
- DISALLOW_COPY_AND_ASSIGN(MessagePumpLibevent);
-};
-
-} // namespace base
-
-#endif // BASE_MESSAGE_LOOP_MESSAGE_PUMP_LIBEVENT_H_
diff --git a/base/message_loop/message_pump_libevent_unittest.cc b/base/message_loop/message_pump_libevent_unittest.cc
deleted file mode 100644
index 657ac7d..0000000
--- a/base/message_loop/message_pump_libevent_unittest.cc
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/message_loop/message_pump_libevent.h"
-
-#include <unistd.h>
-
-#include "base/message_loop/message_loop.h"
-#include "base/posix/eintr_wrapper.h"
-#include "base/threading/thread.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/libevent/event.h"
-
-namespace base {
-
-class MessagePumpLibeventTest : public testing::Test {
- protected:
- MessagePumpLibeventTest()
- : ui_loop_(MessageLoop::TYPE_UI),
- io_thread_("MessagePumpLibeventTestIOThread") {}
- virtual ~MessagePumpLibeventTest() {}
-
- virtual void SetUp() OVERRIDE {
- Thread::Options options(MessageLoop::TYPE_IO, 0);
- ASSERT_TRUE(io_thread_.StartWithOptions(options));
- ASSERT_EQ(MessageLoop::TYPE_IO, io_thread_.message_loop()->type());
- int ret = pipe(pipefds_);
- ASSERT_EQ(0, ret);
- }
-
- virtual void TearDown() OVERRIDE {
- if (HANDLE_EINTR(close(pipefds_[0])) < 0)
- PLOG(ERROR) << "close";
- if (HANDLE_EINTR(close(pipefds_[1])) < 0)
- PLOG(ERROR) << "close";
- }
-
- MessageLoop* ui_loop() { return &ui_loop_; }
- MessageLoopForIO* io_loop() const {
- return static_cast<MessageLoopForIO*>(io_thread_.message_loop());
- }
-
- void OnLibeventNotification(
- MessagePumpLibevent* pump,
- MessagePumpLibevent::FileDescriptorWatcher* controller) {
- pump->OnLibeventNotification(0, EV_WRITE | EV_READ, controller);
- }
-
- int pipefds_[2];
-
- private:
- MessageLoop ui_loop_;
- Thread io_thread_;
-};
-
-namespace {
-
-// Concrete implementation of MessagePumpLibevent::Watcher that does
-// nothing useful.
-class StupidWatcher : public MessagePumpLibevent::Watcher {
- public:
- virtual ~StupidWatcher() {}
-
- // base:MessagePumpLibevent::Watcher interface
- virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE {}
- virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {}
-};
-
-#if GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
-
-// Test to make sure that we catch calling WatchFileDescriptor off of the
-// wrong thread.
-TEST_F(MessagePumpLibeventTest, TestWatchingFromBadThread) {
- MessagePumpLibevent::FileDescriptorWatcher watcher;
- StupidWatcher delegate;
-
- ASSERT_DEATH(io_loop()->WatchFileDescriptor(
- STDOUT_FILENO, false, MessageLoopForIO::WATCH_READ, &watcher, &delegate),
- "Check failed: "
- "watch_file_descriptor_caller_checker_.CalledOnValidThread()");
-}
-
-#endif // GTEST_HAS_DEATH_TEST && !defined(NDEBUG)
-
-class BaseWatcher : public MessagePumpLibevent::Watcher {
- public:
- explicit BaseWatcher(MessagePumpLibevent::FileDescriptorWatcher* controller)
- : controller_(controller) {
- DCHECK(controller_);
- }
- virtual ~BaseWatcher() {}
-
- // base:MessagePumpLibevent::Watcher interface
- virtual void OnFileCanReadWithoutBlocking(int /* fd */) OVERRIDE {
- NOTREACHED();
- }
-
- virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE {
- NOTREACHED();
- }
-
- protected:
- MessagePumpLibevent::FileDescriptorWatcher* controller_;
-};
-
-class DeleteWatcher : public BaseWatcher {
- public:
- explicit DeleteWatcher(
- MessagePumpLibevent::FileDescriptorWatcher* controller)
- : BaseWatcher(controller) {}
-
- virtual ~DeleteWatcher() {
- DCHECK(!controller_);
- }
-
- virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE {
- DCHECK(controller_);
- delete controller_;
- controller_ = NULL;
- }
-};
-
-TEST_F(MessagePumpLibeventTest, DeleteWatcher) {
- scoped_refptr<MessagePumpLibevent> pump(new MessagePumpLibevent);
- MessagePumpLibevent::FileDescriptorWatcher* watcher =
- new MessagePumpLibevent::FileDescriptorWatcher;
- DeleteWatcher delegate(watcher);
- pump->WatchFileDescriptor(pipefds_[1],
- false, MessagePumpLibevent::WATCH_READ_WRITE, watcher, &delegate);
-
- // Spoof a libevent notification.
- OnLibeventNotification(pump.get(), watcher);
-}
-
-class StopWatcher : public BaseWatcher {
- public:
- explicit StopWatcher(
- MessagePumpLibevent::FileDescriptorWatcher* controller)
- : BaseWatcher(controller) {}
-
- virtual ~StopWatcher() {}
-
- virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE {
- controller_->StopWatchingFileDescriptor();
- }
-};
-
-TEST_F(MessagePumpLibeventTest, StopWatcher) {
- scoped_refptr<MessagePumpLibevent> pump(new MessagePumpLibevent);
- MessagePumpLibevent::FileDescriptorWatcher watcher;
- StopWatcher delegate(&watcher);
- pump->WatchFileDescriptor(pipefds_[1],
- false, MessagePumpLibevent::WATCH_READ_WRITE, &watcher, &delegate);
-
- // Spoof a libevent notification.
- OnLibeventNotification(pump.get(), &watcher);
-}
-
-} // namespace
-
-} // namespace base
diff --git a/base/message_loop/message_pump_observer.h b/base/message_loop/message_pump_observer.h
deleted file mode 100644
index cb46fa3..0000000
--- a/base/message_loop/message_pump_observer.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_MESSAGE_LOOP_MESSAGE_PUMP_OBSERVER_H
-#define BASE_MESSAGE_LOOP_MESSAGE_PUMP_OBSERVER_H
-
-#include "base/base_export.h"
-#include "base/event_types.h"
-
-namespace base {
-
-enum EventStatus {
- EVENT_CONTINUE, // The event should be dispatched as normal.
-#if defined(USE_X11)
- EVENT_HANDLED // The event should not be processed any farther.
-#endif
-};
-
-// A MessagePumpObserver is an object that receives global
-// notifications from the UI MessageLoop with MessagePumpWin or
-// MessagePumpAuraX11.
-//
-// NOTE: An Observer implementation should be extremely fast!
-//
-// For use with MessagePumpAuraX11, please see message_pump_glib.h for more
-// info about how this is invoked in this environment.
-class BASE_EXPORT MessagePumpObserver {
- public:
- // This method is called before processing a NativeEvent. If the
- // method returns EVENT_HANDLED, it indicates the event has already
- // been handled, so the event is not processed any farther. If the
- // method returns EVENT_CONTINUE, the event dispatching proceeds as
- // normal.
- virtual EventStatus WillProcessEvent(const NativeEvent& event) = 0;
-
- // This method is called after processing a message. This method
- // will not be called if WillProcessEvent returns EVENT_HANDLED.
- virtual void DidProcessEvent(const NativeEvent& event) = 0;
-
- protected:
- virtual ~MessagePumpObserver() {}
-};
-
-} // namespace base
-
-#endif // BASE_MESSAGE_LOOP_MESSAGE_PUMP_OBSERVER_H
diff --git a/base/message_loop/message_pump_ozone.cc b/base/message_loop/message_pump_ozone.cc
deleted file mode 100644
index 5c0bf83..0000000
--- a/base/message_loop/message_pump_ozone.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/message_loop/message_pump_ozone.h"
-
-#include "base/logging.h"
-#include "base/message_loop.h"
-
-namespace base {
-
-MessagePumpOzone::MessagePumpOzone()
- : MessagePumpLibevent() {
-}
-
-MessagePumpOzone::~MessagePumpOzone() {
-}
-
-void MessagePumpOzone::AddObserver(MessagePumpObserver* /* observer */) {
- NOTIMPLEMENTED();
-}
-
-void MessagePumpOzone::RemoveObserver(MessagePumpObserver* /* observer */) {
- NOTIMPLEMENTED();
-}
-
-// static
-MessagePumpOzone* MessagePumpOzone::Current() {
- MessageLoopForUI* loop = MessageLoopForUI::current();
- return static_cast<MessagePumpOzone*>(loop->pump_ui());
-}
-
-void MessagePumpOzone::AddDispatcherForRootWindow(
- MessagePumpDispatcher* dispatcher) {
- // Only one root window is supported.
- DCHECK(dispatcher_.size() == 0);
- dispatcher_.insert(dispatcher_.begin(),dispatcher);
-}
-
-void MessagePumpOzone::RemoveDispatcherForRootWindow(
- MessagePumpDispatcher* dispatcher) {
- DCHECK(dispatcher_.size() == 1);
- dispatcher_.pop_back();
-}
-
-bool MessagePumpOzone::Dispatch(const NativeEvent& dev) {
- if (dispatcher_.size() > 0)
- return dispatcher_[0]->Dispatch(dev);
- else
- return true;
-}
-
-// This code assumes that the caller tracks the lifetime of the |dispatcher|.
-void MessagePumpOzone::RunWithDispatcher(
- Delegate* delegate, MessagePumpDispatcher* dispatcher) {
- dispatcher_.push_back(dispatcher);
- Run(delegate);
- dispatcher_.pop_back();
-}
-
-} // namespace base
diff --git a/base/message_loop/message_pump_ozone.h b/base/message_loop/message_pump_ozone.h
deleted file mode 100644
index de75ab4..0000000
--- a/base/message_loop/message_pump_ozone.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_MESSAGE_LOOP_MESSAGE_PUMP_OZONE_H_
-#define BASE_MESSAGE_LOOP_MESSAGE_PUMP_OZONE_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/scoped_vector.h"
-#include "base/message_loop/message_pump_dispatcher.h"
-#include "base/message_loop/message_pump_libevent.h"
-#include "base/message_loop/message_pump_observer.h"
-#include "base/observer_list.h"
-
-namespace base {
-
-// This class implements a message-pump for processing events from input devices
-// Refer to MessagePump for further documentation.
-class BASE_EXPORT MessagePumpOzone : public MessagePumpLibevent,
- public MessagePumpDispatcher {
- public:
- MessagePumpOzone();
-
- // Returns the UI message pump.
- static MessagePumpOzone* Current();
-
- // Add/Remove the root window dispatcher.
- void AddDispatcherForRootWindow(MessagePumpDispatcher* dispatcher);
- void RemoveDispatcherForRootWindow(MessagePumpDispatcher* dispatcher);
-
- void RunWithDispatcher(Delegate* delegate, MessagePumpDispatcher* dispatcher);
-
- // Add / remove an Observer, which will start receiving notifications
- // immediately.
- void AddObserver(MessagePumpObserver* observer);
- void RemoveObserver(MessagePumpObserver* observer);
-
- // Overridden from MessagePumpDispatcher.
- virtual bool Dispatch(const NativeEvent& event) OVERRIDE;
-
- private:
- virtual ~MessagePumpOzone();
- std::vector<MessagePumpDispatcher*> dispatcher_;
-
- DISALLOW_COPY_AND_ASSIGN(MessagePumpOzone);
-};
-
-typedef MessagePumpOzone MessagePumpForUI;
-
-} // namespace base
-
-#endif // BASE_MESSAGE_LOOP_MESSAGE_PUMP_OZONE_H_