Home | History | Annotate | Download | only in gobject
      1 <?xml version='1.0' encoding="ISO-8859-1"?>
      2 <chapter id="chapter-signal">
      3   <title>The GObject messaging system</title>
      4 
      5   <sect1 id="closure">
      6     <title>Closures</title>
      7 
      8     <para>
      9       Closures are central to the concept of asynchronous signal delivery
     10       which is widely used throughout GTK+ and GNOME applications. A closure is an 
     11       abstraction, a generic representation of a callback. It is a small structure
     12       which contains three objects:
     13       <itemizedlist>
     14         <listitem><para>a function pointer (the callback itself) whose prototype looks like:
     15 <programlisting>
     16 return_type function_callback (... , gpointer user_data);
     17 </programlisting>
     18         </para></listitem>
     19         <listitem><para>
     20            the user_data pointer which is passed to the callback upon invocation of the closure
     21           </para></listitem>
     22         <listitem><para>
     23            a function pointer which represents the destructor of the closure: whenever the
     24            closure's refcount reaches zero, this function will be called before the closure
     25            structure is freed.
     26           </para></listitem>
     27       </itemizedlist>
     28     </para>
     29 
     30     <para>
     31       The <type><link linkend="GClosure">GClosure</link></type> structure represents the common functionality of all
     32       closure implementations: there exists a different Closure implementation for
     33       each separate runtime which wants to use the GObject type system.
     34       <footnote><para>
     35         In practice, closures sit at the boundary of language runtimes: if you are
     36         writing Python code and one of your Python callbacks receives a signal from
     37         a GTK+ widget, the C code in GTK+ needs to execute your Python
     38         code. The closure invoked by the GTK+ object invokes the Python callback:
     39         it behaves as a normal C object for GTK+ and as a normal Python object for
     40         Python code.
     41       </para></footnote>
     42       The GObject library provides a simple <type><link linkend="GCClosure">GCClosure</link></type> type which
     43       is a specific implementation of closures to be used with C/C++ callbacks.
     44     </para>
     45     <para>
     46       A <type><link linkend="GClosure">GClosure</link></type> provides simple services:
     47       <itemizedlist>
     48         <listitem><para>
     49           Invocation (<function><link linkend="g-closure-invoke">g_closure_invoke</link></function>): this is what closures 
     50           were created for: they hide the details of callback invocation from the
     51           callback invoker.</para>
     52         </listitem>
     53         <listitem><para>
     54           Notification: the closure notifies listeners of certain events such as
     55           closure invocation, closure invalidation and closure finalization. Listeners
     56           can be registered with <function><link linkend="g-closure-add-finalize-notifier">g_closure_add_finalize_notifier</link></function>
     57           (finalization notification), <function><link linkend="g-closure-add-invalidate-notifier">g_closure_add_invalidate_notifier</link></function> 
     58           (invalidation notification) and 
     59           <function><link linkend="g-closure-add-marshal-guards">g_closure_add_marshal_guards</link></function> (invocation notification).
     60           There exist symmetric deregistration functions for finalization and invalidation
     61           events (<function><link linkend="g-closure-remove-finalize-notifier">g_closure_remove_finalize_notifier</link></function> and
     62           <function><link linkend="g-closure-remove-invalidate-notifier">g_closure_remove_invalidate_notifier</link></function>) but not for the invocation 
     63           process.
     64           <footnote><para>
     65             Closures are reference counted and notify listeners of their destruction in a two-stage
     66             process: the invalidation notifiers are invoked before the finalization notifiers.
     67           </para></footnote></para>
     68         </listitem>
     69       </itemizedlist>
     70     </para>
     71 
     72     <sect2>
     73       <title>C Closures</title>
     74 
     75       <para>
     76         If you are using C or C++
     77         to connect a callback to a given event, you will either use simple <type><link linkend="GCClosure">GCClosure</link></type>s
     78         which have a pretty minimal API or the even simpler <function><link linkend="g-signal-connect">g_signal_connect</link></function> 
     79         functions (which will be presented a bit later :).
     80 <programlisting>
     81 GClosure *g_cclosure_new             (GCallback      callback_func,
     82                                       gpointer       user_data,
     83                                       GClosureNotify destroy_data);
     84 GClosure *g_cclosure_new_swap        (GCallback      callback_func,
     85                                       gpointer       user_data,
     86                                       GClosureNotify destroy_data);
     87 GClosure *g_signal_type_cclosure_new (GType          itype,
     88                                       guint          struct_offset);
     89 </programlisting>
     90       </para>
     91 
     92       <para>
     93         <function><link linkend="g-cclosure-new">g_cclosure_new</link></function> will create a new closure which can invoke the
     94         user-provided callback_func with the user-provided user_data as last parameter. When the closure
     95         is finalized (second stage of the destruction process), it will invoke the destroy_data function 
     96         if the user has supplied one.
     97       </para>
     98   
     99       <para>
    100         <function><link linkend="g-cclosure-new-swap">g_cclosure_new_swap</link></function> will create a new closure which can invoke the
    101         user-provided callback_func with the user-provided user_data as first parameter (instead of being the 
    102         last parameter as with <function><link linkend="g-cclosure-new">g_cclosure_new</link></function>). When the closure
    103         is finalized (second stage of the destruction process), it will invoke the destroy_data 
    104         function if the user has supplied one.
    105       </para>
    106     </sect2>
    107 
    108     <sect2>
    109       <title>Non-C closures (for the fearless)</title>
    110 
    111       <para>
    112         As was explained above, closures hide the details of callback invocation. In C,
    113         callback invocation is just like function invocation: it is a matter of creating
    114         the correct stack frame for the called function and executing a <emphasis>call</emphasis>
    115         assembly instruction.
    116       </para>
    117   
    118       <para>
    119         C closure marshallers transform the array of GValues which represent 
    120         the parameters to the target function into a C-style function parameter list, invoke
    121         the user-supplied C function with this new parameter list, get the return value of the
    122         function, transform it into a GValue and return this GValue to the marshaller caller.
    123       </para>
    124   
    125       <para>
    126         The following code implements a simple marshaller in C for a C function which takes an
    127         integer as first parameter and returns void.
    128 <programlisting>
    129 g_cclosure_marshal_VOID__INT (GClosure     *closure,
    130                               GValue       *return_value,
    131                               guint         n_param_values,
    132                               const GValue *param_values,
    133                               gpointer      invocation_hint,
    134                               gpointer      marshal_data)
    135 {
    136   typedef void (*GMarshalFunc_VOID__INT) (gpointer     data1,
    137                                           gint         arg_1,
    138                                           gpointer     data2);
    139   register GMarshalFunc_VOID__INT callback;
    140   register GCClosure *cc = (GCClosure*) closure;
    141   register gpointer data1, data2;
    142 
    143   g_return_if_fail (n_param_values == 2);
    144 
    145   data1 = g_value_peek_pointer (param_values + 0);
    146   data2 = closure->data;
    147 
    148   callback = (GMarshalFunc_VOID__INT) (marshal_data ? marshal_data : cc->callback);
    149 
    150   callback (data1,
    151             g_marshal_value_peek_int (param_values + 1),
    152             data2);
    153 }
    154 </programlisting>
    155       </para>
    156   
    157       <para>
    158         Of course, there exist other kinds of marshallers. For example, James Henstridge 
    159         wrote a generic Python marshaller which is used by all Python closures (a Python closure
    160         is used to have Python-based callback be invoked by the closure invocation process).
    161         This Python marshaller transforms the input GValue list representing the function 
    162         parameters into a Python tuple which is the equivalent structure in Python (you can
    163         look in <function>pyg_closure_marshal</function> in <filename>pygtype.c</filename>
    164         in the <emphasis>pygobject</emphasis> module in the GNOME Subversion server).
    165       </para>
    166 
    167     </sect2>
    168   </sect1>
    169 
    170   <sect1 id="signal">
    171     <title>Signals</title>
    172 
    173     <para>
    174       GObject's signals have nothing to do with standard UNIX signals: they connect 
    175       arbitrary application-specific events with any number of listeners.
    176       For example, in GTK+, every user event (keystroke or mouse move) is received
    177       from the X server and generates a GTK+ event under the form of a signal emission
    178       on a given object instance.
    179     </para>
    180 
    181     <para>
    182       Each signal is registered in the type system together with the type on which
    183       it can be emitted: users of the type are said to <emphasis>connect</emphasis>
    184       to the signal on a given type instance when they register a closure to be 
    185       invoked upon the signal emission. Users can also emit the signal by themselves 
    186       or stop the emission of the signal from within one of the closures connected 
    187       to the signal.
    188     </para>
    189 
    190     <para>
    191       When a signal is emitted on a given type instance, all the closures
    192       connected to this signal on this type instance will be invoked. All the closures
    193       connected to such a signal represent callbacks whose signature looks like:
    194 <programlisting>
    195 return_type function_callback (gpointer instance, ... , gpointer user_data);
    196 </programlisting>
    197     </para>
    198 
    199     <sect2 id="signal-registration">
    200       <title>Signal registration</title>
    201 
    202 	  <para>
    203 		To register a new signal on an existing type, we can use any of <function><link linkend="g-signal-newv">g_signal_newv</link></function>,
    204 		<function><link linkend="g-signal-new-valist">g_signal_new_valist</link></function> or <function><link linkend="g-signal-new">g_signal_new</link></function> functions:
    205 <programlisting>
    206 guint g_signal_newv (const gchar        *signal_name,
    207                      GType               itype,
    208                      GSignalFlags        signal_flags,
    209                      GClosure           *class_closure,
    210                      GSignalAccumulator  accumulator,
    211                      gpointer            accu_data,
    212                      GSignalCMarshaller  c_marshaller,
    213                      GType               return_type,
    214                      guint               n_params,
    215                      GType              *param_types);
    216 </programlisting>
    217 		The number of parameters to these functions is a bit intimidating but they are relatively
    218 		simple:
    219 		<itemizedlist>
    220 		  <listitem><para>
    221 			  signal_name: is a string which can be used to uniquely identify a given signal.
    222 			</para></listitem>
    223 		  <listitem><para>
    224 			  itype: is the instance type on which this signal can be emitted.
    225 			</para></listitem>
    226 		  <listitem><para>
    227 			  signal_flags: partly defines the order in which closures which were connected to the
    228 			  signal are invoked.
    229 			</para></listitem>
    230 		  <listitem><para>
    231 			  class_closure: this is the default closure for the signal: if it is not NULL upon
    232 			  the signal emission, it will be invoked upon this emission of the signal. The 
    233 			  moment where this closure is invoked compared to other closures connected to that 
    234 			  signal depends partly on the signal_flags.
    235 			</para></listitem>
    236 			<listitem><para>
    237 			  accumulator: this is a function pointer which is invoked after each closure
    238 			  has been invoked. If it returns FALSE, signal emission is stopped. If it returns
    239 			  TRUE, signal emission proceeds normally. It is also used to compute the return
    240 			  value of the signal based on the return value of all the invoked closures.
    241 			</para></listitem>
    242 		  <listitem><para>
    243 			  accumulator_data: this pointer will be passed down to each invocation of the
    244 			  accumulator during emission.
    245 			</para></listitem>
    246 		  <listitem><para>
    247 			  c_marshaller: this is the default C marshaller for any closure which is connected to
    248 			this signal.
    249 			</para></listitem>
    250 		  <listitem><para>
    251 			  return_type: this is the type of the return value of the signal.
    252 			</para></listitem>
    253 		  <listitem><para>
    254 			  n_params: this is the number of parameters this signal takes.
    255 			</para></listitem>
    256 		  <listitem><para>
    257 			  param_types: this is an array of GTypes which indicate the type of each parameter
    258 			  of the signal. The length of this array is indicated by n_params.
    259 			</para></listitem>
    260 		</itemizedlist>
    261       </para>
    262 
    263 	  <para>
    264 		As you can see from the above definition, a signal is basically a description
    265 		of the closures which can be connected to this signal and a description of the
    266 		order in which the closures connected to this signal will be invoked.
    267 	  </para>
    268 
    269 	</sect2>
    270 
    271 	<sect2 id="signal-connection">
    272 	  <title>Signal connection</title>
    273 
    274 	  <para>
    275 		If you want to connect to a signal with a closure, you have three possibilities:
    276 		<itemizedlist>
    277 		  <listitem><para>
    278 		  You can register a class closure at signal registration: this is a
    279 		  system-wide operation. i.e.: the class_closure will be invoked during each emission
    280 		  of a given signal on all the instances of the type which supports that signal.
    281 			</para></listitem>
    282 		  <listitem><para>
    283 		  You can use <function><link linkend="g-signal-override-class-closure">g_signal_override_class_closure</link></function> which
    284 		  overrides the class_closure of a given type. It is possible to call this function
    285 		  only on a derived type of the type on which the signal was registered.
    286 		  This function is of use only to language bindings.
    287 			</para></listitem>
    288 		  <listitem><para>
    289 		  You can register a closure with the <function><link linkend="g-signal-connect">g_signal_connect</link></function>
    290 		  family of functions. This is an instance-specific operation: the closure
    291 		  will be invoked only during emission of a given signal on a given instance.
    292 			</para></listitem>
    293 		</itemizedlist>
    294 		It is also possible to connect a different kind of callback on a given signal: 
    295 		emission hooks are invoked whenever a given signal is emitted whatever the instance on 
    296 		which it is emitted. Emission hooks are used for example to get all mouse_clicked
    297 		emissions in an application to be able to emit the small mouse click sound.
    298 		Emission hooks are connected with <function><link linkend="g-signal-add-emission-hook">g_signal_add_emission_hook</link></function>
    299 		and removed with <function><link linkend="g-signal-remove-emission-hook">g_signal_remove_emission_hook</link></function>.
    300 	  </para>
    301 
    302 	</sect2>
    303 
    304 	<sect2 id="signal-emission">
    305 	  <title>Signal emission</title>
    306 
    307 	  <para>
    308 		Signal emission is done through the use of the <function><link linkend="g-signal-emit">g_signal_emit</link></function> family 
    309 		of functions.
    310 <programlisting>
    311 void g_signal_emitv (const GValue *instance_and_params,
    312                      guint         signal_id,
    313                      GQuark        detail,
    314                      GValue       *return_value);
    315 </programlisting>
    316 		<itemizedlist>
    317 		  <listitem><para>
    318 			The instance_and_params array of GValues contains the list of input
    319 			parameters to the signal. The first element of the array is the 
    320 			instance pointer on which to invoke the signal. The following elements of
    321 			the array contain the list of parameters to the signal.
    322 			</para></listitem>
    323 		  <listitem><para>
    324 			signal_id identifies the signal to invoke.
    325 			</para></listitem>
    326 		  <listitem><para>
    327 			detail identifies the specific detail of the signal to invoke. A detail is a kind of 
    328 			magic token/argument which is passed around during signal emission and which is used
    329 			by closures connected to the signal to filter out unwanted signal emissions. In most 
    330 			cases, you can safely set this value to zero. See <xref linkend="signal-detail"/> for
    331 			more details about this parameter.
    332 			</para></listitem>
    333 		  <listitem><para>
    334 			return_value holds the return value of the last closure invoked during emission if
    335 			no accumulator was specified. If an accumulator was specified during signal creation,
    336 			this accumulator is used to calculate the return_value as a function of the return
    337 			values of all the closures invoked during emission. 
    338 			<footnote><para>
    339 			  James (again!!) gives a few non-trivial examples of accumulators:
    340 			  <quote>
    341 				For instance, you may have an accumulator that ignores NULL returns from 
    342 				closures, and only accumulates the non-NULL ones. Another accumulator may try
    343 				to return the list of values returned by the closures.
    344 			  </quote>
    345 			</para></footnote>
    346 			If no closure is invoked during
    347 			emission, the return_value is nonetheless initialized to zero/null.
    348 			</para></listitem>
    349 		  </itemizedlist>
    350 		</para>
    351 
    352 	  <para>
    353 		Internally, the GValue array is passed to the emission function proper, 
    354 		<function>signal_emit_unlocked_R</function> (implemented in <filename>gsignal.c</filename>).
    355 		Signal emission can be decomposed in 5 steps:
    356 		<itemizedlist>
    357 		  <listitem><para>
    358 			<emphasis>RUN_FIRST</emphasis>: if the G_SIGNAL_RUN_FIRST flag was used
    359 			during signal registration and if there exist a class_closure for this signal,
    360 			the class_closure is invoked. Jump to <emphasis>EMISSION_HOOK</emphasis> state.
    361 			</para></listitem>
    362 		  <listitem><para>
    363 			<emphasis>EMISSION_HOOK</emphasis>: if any emission hook was added to
    364 			the signal, they are invoked from first to last added. Accumulate return values
    365 			and jump to <emphasis>HANDLER_RUN_FIRST</emphasis> state. 
    366 			</para></listitem>
    367 		  <listitem><para>
    368 			<emphasis>HANDLER_RUN_FIRST</emphasis>: if any closure were connected
    369 			with the <function><link linkend="g-signal-connect">g_signal_connect</link></function> family of 
    370 			functions, and if they are not blocked (with the <function><link linkend="g-signal-handler-block">g_signal_handler_block</link></function>
    371 			family of functions) they are run here, from first to last connected.
    372 			Jump to <emphasis>RUN_LAST</emphasis> state.
    373 			</para></listitem>
    374 		  <listitem><para>
    375 			<emphasis>RUN_LAST</emphasis>: if the G_SIGNAL_RUN_LAST
    376 			flag was set during registration and if a class_closure
    377 			was set, it is invoked here. Jump to 
    378 			<emphasis>HANDLER_RUN_LAST</emphasis> state.
    379 			</para></listitem>
    380 		  <listitem><para>
    381 			<emphasis>HANDLER_RUN_LAST</emphasis>: if any closure were connected
    382 			with the <function>g_signal_connect_after</function> family of 
    383 			functions, if they were not invoked during HANDLER_RUN_FIRST and if they 
    384 			are not blocked, they are run here, from first to last connected.
    385 			Jump to  <emphasis>RUN_CLEANUP</emphasis> state.
    386 			</para></listitem>
    387 		  <listitem><para>
    388 			<emphasis>RUN_CLEANUP</emphasis>: if the G_SIGNAL_RUN_CLEANUP flag
    389 			was set during registration and if a class_closure was set,
    390 			it is invoked here. Signal emission is completed here.
    391 			</para></listitem>
    392 		</itemizedlist>      
    393 	  </para>
    394   
    395 	  <para>
    396 		If, at any point during emission (except in RUN_CLEANUP state), one of the 
    397 		closures or emission hook stops the signal emission with 
    398 		<function><link linkend="g-signal-stop">g_signal_stop</link></function>, emission jumps to CLEANUP state.
    399 	  </para>
    400   
    401 	  <para>
    402 		If, at any point during emission, one of the closures or emission hook 
    403 		emits the same signal on the same instance, emission is restarted from
    404 		the RUN_FIRST state.
    405 	  </para>
    406   
    407 	  <para>
    408 		The accumulator function is invoked in all states, after invocation
    409 		of each closure (except in EMISSION_HOOK and CLEANUP). It accumulates
    410 		the closure return value into the signal return value and returns TRUE or
    411 		FALSE. If, at any point, it does not return TRUE, emission jumps to CLEANUP state.
    412 	  </para>
    413 
    414 	  <para>
    415 		If no accumulator function was provided, the value returned by the last handler
    416 		run will be returned by <function><link linkend="g-signal-emit">g_signal_emit</link></function>.
    417 	  </para>
    418 
    419 	</sect2>
    420 
    421 
    422 	<sect2 id="signal-detail">
    423 	  <title>The <emphasis>detail</emphasis> argument</title>
    424 
    425 	  <para>All the functions related to signal emission or signal connection have a parameter
    426 		named the <emphasis>detail</emphasis>. Sometimes, this parameter is hidden by the API
    427 		but it is always there, under one form or another. 
    428 	  </para>
    429 
    430 	  <para>
    431 	    Of the three main connection functions,
    432 		only one has an explicit detail parameter as a <type><link linkend="GQuark">GQuark</link></type>
    433 		<footnote>
    434 		  <para>A GQuark is an integer which uniquely represents a string. It is possible to transform
    435 		   back and forth between the integer and string representations with the functions 
    436 		   <function><link linkend="g-quark-from-string">g_quark_from_string</link></function> and <function><link linkend="g-quark-to-string">g_quark_to_string</link></function>.
    437 		  </para>
    438 		</footnote>:
    439 <programlisting>
    440 gulong     g_signal_connect_closure_by_id          (gpointer          instance,
    441                            guint          signal_id,
    442                            GQuark          detail,
    443                            GClosure         *closure,
    444                            gboolean          after);
    445 </programlisting>
    446         The two other functions hide the detail parameter in the signal name identification:
    447 <programlisting>
    448 gulong     g_signal_connect_closure          (gpointer          instance,
    449                            const gchar       *detailed_signal,
    450                            GClosure         *closure,
    451                            gboolean          after);
    452 gulong     g_signal_connect_data              (gpointer          instance,
    453                            const gchar     *detailed_signal,
    454                            GCallback      c_handler,
    455                            gpointer          data,
    456                            GClosureNotify      destroy_data,
    457                            GConnectFlags      connect_flags);
    458 </programlisting>
    459 		Their detailed_signal parameter is a string which identifies the name of the signal
    460 		to connect to. However, the format of this string is structured to look like 
    461 		<emphasis>signal_name::detail_name</emphasis>. Connecting to the signal
    462 		named <emphasis>notify::cursor_position</emphasis> will actually connect to the signal
    463 		named <emphasis>notify</emphasis> with the <emphasis>cursor_position</emphasis> name.
    464 		Internally, the detail string is transformed to a GQuark if it is present.
    465 	  </para>
    466 
    467 	  <para>
    468 		Of the four main signal emission functions, three have an explicit detail parameter as a 
    469 		<type><link linkend="GQuark">GQuark</link></type> again:
    470 <programlisting>
    471 void                  g_signal_emitv        (const GValue       *instance_and_params,
    472                          guint               signal_id,
    473                          GQuark              detail,
    474                          GValue             *return_value);
    475 void                  g_signal_emit_valist  (gpointer            instance,
    476                          guint               signal_id,
    477                          GQuark              detail,
    478                          va_list             var_args);
    479 void                  g_signal_emit         (gpointer            instance,
    480                          guint               signal_id,
    481                          GQuark              detail,
    482                          ...);
    483 </programlisting>
    484         The fourth function hides it in its signal name parameter:
    485 <programlisting>
    486 void                  g_signal_emit_by_name (gpointer            instance,
    487                          const gchar        *detailed_signal,
    488                          ...);
    489 </programlisting>
    490         The format of the detailed_signal parameter is exactly the same as the format used by
    491         the <function><link linkend="g-signal-connect">g_signal_connect</link></function> functions: <emphasis>signal_name::detail_name</emphasis>.
    492 	  </para>
    493 
    494 	  <para>
    495         If a detail is provided by the user to the emission function, it is used during emission to match
    496         against the closures which also provide a detail.
    497         If the closures' detail does not match the detail provided by the user, they will not be invoked
    498         (even though they are connected to a signal which is being emitted).
    499 	  </para>
    500 
    501 	  <para>
    502 		This completely optional filtering mechanism is mainly used as an optimization for signals
    503 		which are often emitted for many different reasons: the clients can filter out which events they are
    504 		interested in before the closure's marshalling code runs. For example, this is used extensively
    505 		by the <emphasis>notify</emphasis> signal of GObject: whenever a property is modified on a GObject,
    506 		instead of just emitting the <emphasis>notify</emphasis> signal, GObject associates as a detail to this
    507 		signal emission the name of the property modified. This allows clients who wish to be notified of changes
    508 		to only one property to filter most events before receiving them.
    509 	  </para>
    510 
    511 	  <para>
    512 		As a simple rule, users can and should set the detail parameter to zero: this will disable completely
    513         this optional filtering.
    514 	  </para>
    515 
    516 	</sect2>
    517 
    518   </sect1>
    519 </chapter>
    520 
    521