|
1 <?xml version="1.0" encoding="utf-8"?> |
|
2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. --> |
|
3 <!-- This component and the accompanying materials are made available under the terms of the License |
|
4 "Eclipse Public License v1.0" which accompanies this distribution, |
|
5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". --> |
|
6 <!-- Initial Contributors: |
|
7 Nokia Corporation - initial contribution. |
|
8 Contributors: |
|
9 --> |
|
10 <!DOCTYPE concept |
|
11 PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd"> |
|
12 <concept id="GUID-7FD05006-09C1-4EF4-A2EB-AD98C2FA8866" xml:lang="en"><title>GLib |
|
13 Event Loop</title><shortdesc>The GLib event loop manages all the sources of an event available |
|
14 for GLib. These events can come from different kinds of sources like file |
|
15 descriptors (plain file descriptors, sockets, or pipes), time-outs, or any |
|
16 kind of source that can be added.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody> |
|
17 <p>To allow multiple independent sets of events to be handled in different |
|
18 threads, each source is associated with a <codeph>GMainContext</codeph>.</p> |
|
19 <p>Each event source is given a priority. The default priority is <codeph>G_PRIORITY_DEFAULT</codeph> and |
|
20 its value is 0. Values less than 0 denote higher priority and values greater |
|
21 than zero denote lower priority. The events from higher priority sources are |
|
22 processed earlier than events from lower priority sources.</p> |
|
23 <p>The <codeph>GMainLoop</codeph> data type represents an event loop. <codeph>GMainContext</codeph> is |
|
24 a parameter to <codeph>GMainLoop</codeph>. If <codeph>GMainContext</codeph> is |
|
25 passed as NULL, then a main loop with the default context is created. After |
|
26 the sources are added to <codeph>GMainContext</codeph> and a <codeph>GMainLoop</codeph> variable |
|
27 is created, <codeph>g_main_loop_run()</codeph> is called. This checks continuously |
|
28 for events from its sources and dispatches them. Finally when all the events |
|
29 have been processed, <codeph>g_main_loop_quit()</codeph> must be called to |
|
30 return from <codeph>g_main_loop_run()</codeph>.</p> |
|
31 <note>Sources are associated with <codeph>GMainContext</codeph> and not with <codeph>GMainLoop</codeph>. |
|
32 Events from sources will be checked and dispatched from all the <codeph>GMainLoop</codeph> the <codeph>GMainContext</codeph> is |
|
33 associated with.</note> |
|
34 <section id="GUID-FE1BB596-6331-4AB8-BC5A-C8ADE24ACE7B"> <title>Creating |
|
35 an event loop</title> <p>GLib provides ready-made functions for adding |
|
36 the following sources either to the default context or to a custom context:</p><ul> |
|
37 <li><p>time-outs</p></li> |
|
38 <li><p>I/O</p></li> |
|
39 <li><p>child watch</p></li> |
|
40 <li><p>idle source (events from idle sources are ready if none of the other |
|
41 sources with priority > G_PRIORITY_DEFAULT are ready) </p></li> |
|
42 </ul><p>The following example code demonstrates the way to add a time-out |
|
43 source to the default context. The program makes 10 calls to <codeph>timeout_callback()</codeph>, |
|
44 which at the 10th call, calls <codeph>g_main_loop_quit</codeph> to make the |
|
45 main loop return.</p><codeblock xml:space="preserve">#include <glib.h> |
|
46 gboolean timeout_callback(gpointer data) |
|
47 { |
|
48 static int i = 0; |
|
49 |
|
50 i++; |
|
51 g_print("timeout_callback called %d times\n", i); |
|
52 if (10 == i) |
|
53 { |
|
54 g_main_loop_quit( (GMainLoop*)data ); |
|
55 return FALSE; |
|
56 } |
|
57 |
|
58 return TRUE; |
|
59 } |
|
60 |
|
61 int main() |
|
62 { |
|
63 GMainLoop *loop; |
|
64 |
|
65 loop = g_main_loop_new ( NULL , FALSE ); |
|
66 |
|
67 // add source to default context |
|
68 g_timeout_add (100 , timeout_callback , loop); |
|
69 g_main_loop_run (loop); |
|
70 g_main_loop_unref(loop); |
|
71 |
|
72 return 0; |
|
73 } |
|
74 </codeblock><p>The following code demonstrates the method to add the time-out |
|
75 source to a different context than the default context:</p><codeblock xml:space="preserve">#include <glib.h> |
|
76 gboolean timeout_callback(gpointer data) |
|
77 { |
|
78 static int i = 0; |
|
79 |
|
80 i++; |
|
81 g_print("timeout_callback called %d times\n",i); |
|
82 |
|
83 if(10 == i) |
|
84 { |
|
85 g_main_loop_quit((GMainLoop*)data); |
|
86 return FALSE; |
|
87 } |
|
88 |
|
89 return TRUE; |
|
90 } |
|
91 |
|
92 int main() |
|
93 { |
|
94 GMainLoop *loop = NULL; |
|
95 GMainContext *context; |
|
96 GSource *source; |
|
97 int id; |
|
98 |
|
99 //create a new time-out source |
|
100 source = g_timeout_source_new(10); |
|
101 |
|
102 //create a context |
|
103 context = g_main_context_new(); |
|
104 |
|
105 //attach source to context |
|
106 id = g_source_attach(source,context); |
|
107 |
|
108 //create a main loop with context |
|
109 loop = g_main_loop_new(context,FALSE); |
|
110 |
|
111 //set the callback for this source |
|
112 g_source_set_callback (source,timeout_callback,loop,NULL); |
|
113 |
|
114 g_main_loop_run (loop); |
|
115 |
|
116 g_main_loop_unref (loop); |
|
117 |
|
118 return 0; |
|
119 } |
|
120 </codeblock><p>The same process can be used for other default sources like |
|
121 child watch, I/O, and idle source since they are GLib APIs that allow the |
|
122 creation of a source directly.</p> </section> |
|
123 <section id="GUID-76BB5D34-F4C9-4015-8A52-2CDAB37716A0"><title>Creating a |
|
124 new source</title><p>The previous section applies only to four types of sources |
|
125 ( time-outs, I/O, child watch, and idle source ), for which GLib provides |
|
126 ready-made functions. The program below demonstrates the creation of a new |
|
127 source.</p><codeblock xml:space="preserve">#include <glib.h> |
|
128 gboolean callback(gpointer data) |
|
129 { |
|
130 static int i = 0; |
|
131 i++; |
|
132 g_print ("timeout_callback called %d times\n",i); |
|
133 if (10 == i) |
|
134 { |
|
135 g_main_loop_quit((GMainLoop*)data); |
|
136 return FALSE; |
|
137 } |
|
138 |
|
139 return TRUE; |
|
140 } |
|
141 |
|
142 gboolean prepare(GSource *source,gint *timeout_) |
|
143 { |
|
144 *timeout_ = -1; |
|
145 return TRUE; |
|
146 } |
|
147 |
|
148 gboolean check(GSource *source) |
|
149 { |
|
150 return TRUE; |
|
151 } |
|
152 |
|
153 gboolean dispatch(GSource *source,GSourceFunc callback,gpointer user_data) |
|
154 { |
|
155 if (callback(user_data)) |
|
156 return TRUE; |
|
157 else |
|
158 return FALSE; |
|
159 } |
|
160 |
|
161 int main() |
|
162 { |
|
163 GMainLoop *loop = NULL; |
|
164 GMainContext *context; |
|
165 GSource *source; |
|
166 int id; |
|
167 |
|
168 //create a variable of type GSourceFuncs |
|
169 GSourceFuncs SourceFuncs = |
|
170 { |
|
171 prepare, |
|
172 check, |
|
173 dispatch, |
|
174 NULL |
|
175 }; |
|
176 |
|
177 //create a new source |
|
178 source = g_source_new (&SourceFuncs, sizeof(GSource)); |
|
179 |
|
180 //create a context |
|
181 context = g_main_context_new (); |
|
182 |
|
183 //attach source to context |
|
184 id = g_source_attach (source,context); |
|
185 |
|
186 //create a main loop with context |
|
187 loop = g_main_loop_new (context,FALSE); |
|
188 |
|
189 //set the callback for this source |
|
190 g_source_set_callback (source,callback,loop,NULL); |
|
191 |
|
192 g_main_loop_run (loop); |
|
193 g_main_loop_unref (loop); |
|
194 |
|
195 return 0; |
|
196 } |
|
197 </codeblock><p>The creation of a new source requires us to define at least |
|
198 3 functions:</p><ul> |
|
199 <li><p><b><codeph>prepare()</codeph></b>: Called before all the file descriptors |
|
200 are polled. If the source can determine that it is ready here (without waiting |
|
201 for the results of the poll() call), it should return TRUE. It can also return |
|
202 a time-out value which should be the maximum time-out (in milliseconds) which |
|
203 should be passed to the poll() call. The actual time-out used will be -1 if |
|
204 all sources returned -1, or it will be the minimum of all the timeout_values |
|
205 returned which were >= 0</p></li> |
|
206 <li><p><b><codeph>check()</codeph></b>: Called after all the file descriptors |
|
207 are polled. The source should return TRUE if it is ready to be dispatched.</p><note>Time |
|
208 may have passed since the previous prepare function was called, so the source |
|
209 should be checked again.</note></li> |
|
210 <li><p><b><codeph>dispatch()</codeph></b> Called to dispatch the event source |
|
211 after it has returned TRUE in either its prepare or check function. The dispatch |
|
212 function is passed in a callback function and data. The callback function |
|
213 may be NULL if the source was never connected to a callback using <codeph>g_source_set_callback()</codeph>. |
|
214 The dispatch function should call the callback function with <codeph>user_data</codeph> and |
|
215 the additional parameters that are needed for this type of event source.</p></li> |
|
216 </ul></section> |
|
217 <section id="GUID-675507D7-A769-48DA-8EE6-2AA271C0EC86"><title>Customizing |
|
218 the main loop iteration</title><p>Single iteration of <codeph>GMainContext</codeph> can |
|
219 be run in <codeph>g_main_context_iteration ()</codeph>. When a more detailed |
|
220 control of how the main loop runs is desired call the component function of <codeph>g_main_context |
|
221 iteration()</codeph> directly.</p><p>The component functions of <codeph>g_main_context |
|
222 iteration()</codeph> are listed below:</p><ul> |
|
223 <li><p><codeph>g_main_context_prepare()</codeph></p></li> |
|
224 <li><p><codeph>g_main_context_query()</codeph></p></li> |
|
225 <li><p><codeph>g_main_context_check()</codeph> </p></li> |
|
226 </ul></section> |
|
227 </conbody></concept> |