Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2402)

Unified Diff: base/message_pump_glib.cc

Issue 99126: Mutual exclusion between gconf and the glib main loop. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/message_pump_glib.h ('k') | chrome/app/chrome_dll_main.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/message_pump_glib.cc
===================================================================
--- base/message_pump_glib.cc (revision 14449)
+++ base/message_pump_glib.cc (working copy)
@@ -4,12 +4,14 @@
#include "base/message_pump_glib.h"
+#include <errno.h>
#include <fcntl.h>
#include <math.h>
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/platform_thread.h"
+#include "base/scoped_ptr.h"
namespace {
@@ -90,6 +92,9 @@
namespace base {
+// static
+Lock MessagePumpForUI::glib_main_loop_lock_;
+
MessagePumpForUI::MessagePumpForUI()
: state_(NULL),
context_(g_main_context_default()) {
@@ -118,6 +123,45 @@
close(wakeup_pipe_write_);
}
+// Runs a glib main loop iteration. Grabs glib_main_loop_lock_ while
+// calling glib functions, but releases it while polling.
+static void GMainIterate(GMainContext* context) {
+ AutoLock locked(MessagePumpForUI::glib_main_loop_lock_);
+ int fds_array_size = 50;
+ scoped_array<GPollFD> fds(new GPollFD[fds_array_size]);
+
+ // We use the lower-level component functions and do the poll
+ // ourselves so that we can release glib_main_loop_lock_ while
+ // polling, otherwise waiters might starve.
+
+ // I'll assume no other thread will g_main_context_acquire the
+ // context away from this thread. We cannot g_main_context_wait as
+ // we can't get to the condition and mutex in the context (which is
+ // externally opaque).
+
+ gint max_priority, timeout;
+ g_main_context_prepare(context, &max_priority);
+ int number_of_fds = g_main_context_query(context, max_priority, &timeout,
+ fds.get(), fds_array_size);
+ // We could reallocate instead, then we'd want to cache the array size...
+ CHECK(number_of_fds <= fds_array_size);
+ GPollFunc poll_func = g_main_context_get_poll_func(context);
+
+ {
+ // Release the lock while polling
+ AutoUnlock locked(MessagePumpForUI::glib_main_loop_lock_);
+
+ if ((*poll_func) (fds.get(), number_of_fds, timeout) < 0) {
+ if (errno != EINTR)
+ LOG(ERROR) << "g_main_loop poll error: " << strerror(errno);
+ // Just carry on.
+ }
+ }
+
+ g_main_context_check(context, max_priority, fds.get(), number_of_fds);
+ g_main_context_dispatch(context);
+}
+
void MessagePumpForUI::Run(Delegate* delegate) {
#ifndef NDEBUG
// Make sure we only run this on one thread. GTK only has one message pump
@@ -146,7 +190,7 @@
// 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?
while (!state_->should_quit)
- g_main_context_iteration(context_, true);
+ GMainIterate(context_);
state_ = previous_state;
}
« no previous file with comments | « base/message_pump_glib.h ('k') | chrome/app/chrome_dll_main.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698