diff options
author | dsh@google.com <dsh@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-03 16:52:59 +0000 |
---|---|---|
committer | dsh@google.com <dsh@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-03 16:52:59 +0000 |
commit | 8fc3a4815737707de36239119a3d3c648b826e2f (patch) | |
tree | 212caac6e386552d01794b68fbae74722cea456f /base/message_pump_glib.h | |
parent | 748f1130a5fc046b5042390dd08b27df4b64c0cc (diff) | |
download | chromium_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.h | 100 |
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_ |