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

Side by Side Diff: base/message_loop/message_pump_glib.cc

Issue 17078005: Move message_pump to base/message_loop. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 6 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/message_loop/message_pump_glib.h ('k') | base/message_loop/message_pump_glib_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/message_pump_glib.h" 5 #include "base/message_loop/message_pump_glib.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <math.h> 8 #include <math.h>
9 9
10 #include <glib.h> 10 #include <glib.h>
11 11
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/posix/eintr_wrapper.h" 13 #include "base/posix/eintr_wrapper.h"
14 #include "base/threading/platform_thread.h" 14 #include "base/threading/platform_thread.h"
15 15
16 namespace base {
17
16 namespace { 18 namespace {
17 19
18 // Return a timeout suitable for the glib loop, -1 to block forever, 20 // Return a timeout suitable for the glib loop, -1 to block forever,
19 // 0 to return right away, or a timeout in milliseconds from now. 21 // 0 to return right away, or a timeout in milliseconds from now.
20 int GetTimeIntervalMilliseconds(const base::TimeTicks& from) { 22 int GetTimeIntervalMilliseconds(const TimeTicks& from) {
21 if (from.is_null()) 23 if (from.is_null())
22 return -1; 24 return -1;
23 25
24 // Be careful here. TimeDelta has a precision of microseconds, but we want a 26 // Be careful here. TimeDelta has a precision of microseconds, but we want a
25 // value in milliseconds. If there are 5.5ms left, should the delay be 5 or 27 // value in milliseconds. If there are 5.5ms left, should the delay be 5 or
26 // 6? It should be 6 to avoid executing delayed work too early. 28 // 6? It should be 6 to avoid executing delayed work too early.
27 int delay = static_cast<int>( 29 int delay = static_cast<int>(
28 ceil((from - base::TimeTicks::Now()).InMillisecondsF())); 30 ceil((from - TimeTicks::Now()).InMillisecondsF()));
29 31
30 // If this value is negative, then we need to run delayed work soon. 32 // If this value is negative, then we need to run delayed work soon.
31 return delay < 0 ? 0 : delay; 33 return delay < 0 ? 0 : delay;
32 } 34 }
33 35
34 // A brief refresher on GLib: 36 // A brief refresher on GLib:
35 // GLib sources have four callbacks: Prepare, Check, Dispatch and Finalize. 37 // GLib sources have four callbacks: Prepare, Check, Dispatch and Finalize.
36 // On each iteration of the GLib pump, it calls each source's Prepare function. 38 // On each iteration of the GLib pump, it calls each source's Prepare function.
37 // This function should return TRUE if it wants GLib to call its Dispatch, and 39 // This function should return TRUE if it wants GLib to call its Dispatch, and
38 // FALSE otherwise. It can also set a timeout in this case for the next time 40 // FALSE otherwise. It can also set a timeout in this case for the next time
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 // after, from gtk_main_iteration. 76 // after, from gtk_main_iteration.
75 // 77 //
76 // For the GLib pump we try to follow the Windows UI pump model: 78 // For the GLib pump we try to follow the Windows UI pump model:
77 // - Whenever we receive a wakeup event or the timer for delayed work expires, 79 // - Whenever we receive a wakeup event or the timer for delayed work expires,
78 // we run DoWork and/or DoDelayedWork. That part will also run in the other 80 // we run DoWork and/or DoDelayedWork. That part will also run in the other
79 // event pumps. 81 // event pumps.
80 // - We also run DoWork, DoDelayedWork, and possibly DoIdleWork in the main 82 // - We also run DoWork, DoDelayedWork, and possibly DoIdleWork in the main
81 // loop, around event handling. 83 // loop, around event handling.
82 84
83 struct WorkSource : public GSource { 85 struct WorkSource : public GSource {
84 base::MessagePumpGlib* pump; 86 MessagePumpGlib* pump;
85 }; 87 };
86 88
87 gboolean WorkSourcePrepare(GSource* source, 89 gboolean WorkSourcePrepare(GSource* source,
88 gint* timeout_ms) { 90 gint* timeout_ms) {
89 *timeout_ms = static_cast<WorkSource*>(source)->pump->HandlePrepare(); 91 *timeout_ms = static_cast<WorkSource*>(source)->pump->HandlePrepare();
90 // We always return FALSE, so that our timeout is honored. If we were 92 // We always return FALSE, so that our timeout is honored. If we were
91 // to return TRUE, the timeout would be considered to be 0 and the poll 93 // to return TRUE, the timeout would be considered to be 0 and the poll
92 // would never block. Once the poll is finished, Check will be called. 94 // would never block. Once the poll is finished, Check will be called.
93 return FALSE; 95 return FALSE;
94 } 96 }
(...skipping 15 matching lines...) Expand all
110 // I wish these could be const, but g_source_new wants non-const. 112 // I wish these could be const, but g_source_new wants non-const.
111 GSourceFuncs WorkSourceFuncs = { 113 GSourceFuncs WorkSourceFuncs = {
112 WorkSourcePrepare, 114 WorkSourcePrepare,
113 WorkSourceCheck, 115 WorkSourceCheck,
114 WorkSourceDispatch, 116 WorkSourceDispatch,
115 NULL 117 NULL
116 }; 118 };
117 119
118 } // namespace 120 } // namespace
119 121
120
121 namespace base {
122
123 struct MessagePumpGlib::RunState { 122 struct MessagePumpGlib::RunState {
124 Delegate* delegate; 123 Delegate* delegate;
125 MessagePumpDispatcher* dispatcher; 124 MessagePumpDispatcher* dispatcher;
126 125
127 // Used to flag that the current Run() invocation should return ASAP. 126 // Used to flag that the current Run() invocation should return ASAP.
128 bool should_quit; 127 bool should_quit;
129 128
130 // Used to count how many Run() invocations are on the stack. 129 // Used to count how many Run() invocations are on the stack.
131 int run_depth; 130 int run_depth;
132 131
(...skipping 26 matching lines...) Expand all
159 // This is needed to allow Run calls inside Dispatch. 158 // This is needed to allow Run calls inside Dispatch.
160 g_source_set_can_recurse(work_source_, TRUE); 159 g_source_set_can_recurse(work_source_, TRUE);
161 g_source_attach(work_source_, context_); 160 g_source_attach(work_source_, context_);
162 } 161 }
163 162
164 void MessagePumpGlib::RunWithDispatcher(Delegate* delegate, 163 void MessagePumpGlib::RunWithDispatcher(Delegate* delegate,
165 MessagePumpDispatcher* dispatcher) { 164 MessagePumpDispatcher* dispatcher) {
166 #ifndef NDEBUG 165 #ifndef NDEBUG
167 // Make sure we only run this on one thread. X/GTK only has one message pump 166 // Make sure we only run this on one thread. X/GTK only has one message pump
168 // so we can only have one UI loop per process. 167 // so we can only have one UI loop per process.
169 static base::PlatformThreadId thread_id = base::PlatformThread::CurrentId(); 168 static PlatformThreadId thread_id = PlatformThread::CurrentId();
170 DCHECK(thread_id == base::PlatformThread::CurrentId()) << 169 DCHECK(thread_id == PlatformThread::CurrentId()) <<
171 "Running MessagePumpGlib on two different threads; " 170 "Running MessagePumpGlib on two different threads; "
172 "this is unsupported by GLib!"; 171 "this is unsupported by GLib!";
173 #endif 172 #endif
174 173
175 RunState state; 174 RunState state;
176 state.delegate = delegate; 175 state.delegate = delegate;
177 state.dispatcher = dispatcher; 176 state.dispatcher = dispatcher;
178 state.should_quit = false; 177 state.should_quit = false;
179 state.run_depth = state_ ? state_->run_depth + 1 : 1; 178 state.run_depth = state_ ? state_->run_depth + 1 : 1;
180 state.has_work = false; 179 state.has_work = false;
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 g_source_unref(work_source_); 325 g_source_unref(work_source_);
327 close(wakeup_pipe_read_); 326 close(wakeup_pipe_read_);
328 close(wakeup_pipe_write_); 327 close(wakeup_pipe_write_);
329 } 328 }
330 329
331 MessagePumpDispatcher* MessagePumpGlib::GetDispatcher() { 330 MessagePumpDispatcher* MessagePumpGlib::GetDispatcher() {
332 return state_ ? state_->dispatcher : NULL; 331 return state_ ? state_->dispatcher : NULL;
333 } 332 }
334 333
335 } // namespace base 334 } // namespace base
OLDNEW
« no previous file with comments | « base/message_loop/message_pump_glib.h ('k') | base/message_loop/message_pump_glib_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698