summaryrefslogtreecommitdiffstats
path: root/base/message_pump_glib.h
diff options
context:
space:
mode:
authordsh@google.com <dsh@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-10-03 16:52:59 +0000
committerdsh@google.com <dsh@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-10-03 16:52:59 +0000
commit8fc3a4815737707de36239119a3d3c648b826e2f (patch)
tree212caac6e386552d01794b68fbae74722cea456f /base/message_pump_glib.h
parent748f1130a5fc046b5042390dd08b27df4b64c0cc (diff)
downloadchromium_src-8fc3a4815737707de36239119a3d3c648b826e2f.zip
chromium_src-8fc3a4815737707de36239119a3d3c648b826e2f.tar.gz
chromium_src-8fc3a4815737707de36239119a3d3c648b826e2f.tar.bz2
Implement MessageLoopForUI using GLib. This gets some exercise from
base_unittest. BUG=1319 Review URL: http://codereview.chromium.org/4261 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@2834 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/message_pump_glib.h')
-rw-r--r--base/message_pump_glib.h100
1 files changed, 100 insertions, 0 deletions
diff --git a/base/message_pump_glib.h b/base/message_pump_glib.h
new file mode 100644
index 0000000..97daa8a
--- /dev/null
+++ b/base/message_pump_glib.h
@@ -0,0 +1,100 @@
+// Copyright (c) 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.
+
+#ifndef BASE_MESSAGE_PUMP_GLIB_H_
+#define BASE_MESSAGE_PUMP_GLIB_H_
+
+#include <glib.h>
+
+#include "base/message_pump.h"
+#include "base/time.h"
+
+namespace base {
+
+// This class implements a MessagePump needed for TYPE_UI MessageLoops on
+// OS_LINUX platforms using GLib.
+class MessagePumpForUI : public MessagePump {
+ public:
+ MessagePumpForUI();
+ ~MessagePumpForUI();
+
+ virtual void Run(Delegate* delegate);
+ virtual void Quit();
+ virtual void ScheduleWork();
+ virtual void ScheduleDelayedWork(const Time& delayed_work_time);
+
+ 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 {
+ // This is the delegate argument passed to Run.
+ Delegate* delegate;
+ // This tells us when to exit the event pump.
+ bool keep_running;
+ // This tells our work source when to dispatch DoWork and DoDelayedWork.
+ bool should_do_work;
+ // This tells our idle source when to dispatch DoIdleWork.
+ bool should_do_idle_work;
+ // Unlike the work source, which is shared by all calls to Run, each Run
+ // call gets its own idle source because we need to destroy it when we have
+ // no idle work, and we don't want to destroy someone else's source.
+ GSource* idle_source;
+ };
+
+ struct WorkSource : GSource {
+ MessagePumpForUI* self;
+ };
+
+ // The source with these callbacks remain in the main loop forever. They
+ // will dispatch DoWork and DoDelayedWork, and calculate when and how long
+ // to block when GLib calls poll internally.
+ static GSourceFuncs WorkSourceFuncs;
+ static gboolean WorkSourcePrepare(GSource* source, gint* timeout_ms);
+ static gboolean WorkSourceCheck(GSource* source);
+ static gboolean WorkSourceDispatch(GSource* source, GSourceFunc unused_func,
+ gpointer unused_data);
+
+ // The source that uses these callbacks is added as an idle source, which
+ // means GLib will call it when there is no other work to do. We continue
+ // doing work as long as DoIdleWork or the other work functions return true.
+ // Once no work remains, we remove the idle source so GLib will block instead
+ // of firing it. Then we re-add it when we wake up.
+ static GSourceFuncs IdleSourceFuncs;
+ static gboolean IdleSourcePrepare(GSource* source, gint* timeout_ms);
+ static gboolean IdleSourceCheck(GSource* source);
+ static gboolean IdleSourceDispatch(GSource* source, GSourceFunc unused_func,
+ gpointer unused_data);
+
+ // This adds a GLib source to the main loop.
+ GSource* AddSource(GSourceFuncs* funcs, gint priority,
+ GPollFD* optional_poll_fd);
+
+ 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.
+ Time delayed_work_time_;
+
+ // We use a pipe to schedule work in a thread-safe way that doesn't interfere
+ // with our state. When ScheduleWork is called, we write into the pipe which
+ // ensures poll will not sleep, since we use the read end as an event source.
+ // When we find data pending on the pipe, we clear it out and know we have
+ // been given new work.
+ int write_fd_work_scheduled_;
+ int read_fd_work_scheduled_;
+
+ // The work source. It is shared by all calls to Run and destroyed when
+ // the message pump is destroyed.
+ GSource* work_source_;
+
+ DISALLOW_COPY_AND_ASSIGN(MessagePumpForUI);
+};
+
+} // namespace base
+
+#endif // BASE_MESSAGE_PUMP_GLIB_H_