Symbian3/PDK/Source/GUID-7FD05006-09C1-4EF4-A2EB-AD98C2FA8866.dita
changeset 1 25a17d01db0c
child 3 46218c8b8afa
equal deleted inserted replaced
0:89d6a7a84779 1:25a17d01db0c
       
     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 &gt; 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 &lt;glib.h&gt;
       
    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 &lt;glib.h&gt;
       
    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 &lt;glib.h&gt;
       
   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 (&amp;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 &gt;= 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>