# The GObject messaging system

## Closures

Closures are central to the concept of asynchronous signal delivery which is widely used throughout GTK+ and GNOME applications. A closure is an abstraction, a generic representation of a callback. It is a small structure which contains three objects:

- a function pointer (the callback itself) whose prototype looks like:

      return_type function_callback (... , gpointer user_data);

- the user_data pointer which is passed to the callback upon invocation of the closure

- a function pointer which represents the destructor of the closure: whenever the closure's refcount reaches zero, this function will be called before the closure structure is freed.

The GClosure structure represents the common functionality of all closure implementations: there exists a different Closure implementation for each separate runtime which wants to use the GObject type system. In practice, closures sit at the boundary of language runtimes: if you are writing Python code and one of your Python callbacks receives a signal from a GTK+ widget, the C code in GTK+ needs to execute your Python code. The closure invoked by the GTK+ object invokes the Python callback: it behaves as a normal C object for GTK+ and as a normal Python object for Python code. The GObject library provides a simple GCClosure type which is a specific implementation of closures to be used with C/C++ callbacks.

A GClosure provides simple services:

- Invocation (`g_closure_invoke`): this is what closures were created for: they hide the details of callback invocation from the callback invoker.

- Notification: the closure notifies listeners of certain events such as closure invocation, closure invalidation and closure finalization. Listeners can be registered with `g_closure_add_finalize_notifier` (finalization notification), `g_closure_add_invalidate_notifier` (invalidation notification) and `g_closure_add_marshal_guards` (invocation notification). There exist symmetric deregistration functions for finalization and invalidation events (`g_closure_remove_finalize_notifier` and `g_closure_remove_invalidate_notifier`) but not for the invocation process. Closures are reference counted and notify listeners of their destruction in a two-stage process: the invalidation notifiers are invoked before the finalization notifiers.

### C Closures

If you are using C or C++ to connect a callback to a given event, you will either use simple GCClosures which have a pretty minimal API or the even simpler `g_signal_connect` functions (which will be presented a bit later :).

    GClosure *g_cclosure_new             (GCallback      callback_func,
                                          gpointer       user_data,
                                          GClosureNotify destroy_data);
    GClosure *g_cclosure_new_swap        (GCallback      callback_func,
                                          gpointer       user_data,
                                          GClosureNotify destroy_data);
    GClosure *g_signal_type_cclosure_new (GType          itype,
                                          guint          struct_offset);

`g_cclosure_new` will create a new closure which can invoke the user-provided callback_func with the user-provided user_data as last parameter. When the closure is finalized (second stage of the destruction process), it will invoke the destroy_data function if the user has supplied one.

`g_cclosure_new_swap` will create a new closure which can invoke the user-provided callback_func with the user-provided user_data as first parameter (instead of being the last parameter as with `g_cclosure_new`). When the closure is finalized (second stage of the destruction process), it will invoke the destroy_data function if the user has supplied one.

### Non-C closures (for the fearless)

As was explained above, closures hide the details of callback invocation. In C, callback invocation is just like function invocation: it is a matter of creating the correct stack frame for the called function and executing a call assembly instruction.

C closure marshallers transform the array of GValues which represent the parameters to the target function into a C-style function parameter list, invoke the user-supplied C function with this new parameter list, get the return value of the function, transform it into a GValue and return this GValue to the marshaller caller.

The following code implements a simple marshaller in C for a C function which takes an integer as first parameter and returns void.

    g_cclosure_marshal_VOID__INT (GClosure     *closure,
                                  GValue       *return_value,
                                  guint         n_param_values,
                                  const GValue *param_values,
                                  gpointer      invocation_hint,
                                  gpointer      marshal_data)
    {
      typedef void (*GMarshalFunc_VOID__INT) (gpointer     data1,
                                              gint         arg_1,
                                              gpointer     data2);
      register GMarshalFunc_VOID__INT callback;
      register GCClosure *cc = (GCClosure*) closure;
      register gpointer data1, data2;

      g_return_if_fail (n_param_values == 2);

      data1 = g_value_peek_pointer (param_values + 0);
      data2 = closure->data;

      callback = (GMarshalFunc_VOID__INT) (marshal_data ? marshal_data : cc->callback);

      callback (data1,
                g_marshal_value_peek_int (param_values + 1),
                data2);
    }

Of course, there exist other kinds of marshallers. For example, James Henstridge wrote a generic Python marshaller which is used by all Python closures (a Python closure is used to have Python-based callback be invoked by the closure invocation process). This Python marshaller transforms the input GValue list representing the function parameters into a Python tuple which is the equivalent structure in Python (you can look in `pyg_closure_marshal` in `pygtype.c` in the pygobject module in the GNOME source code repository).

## Signals

GObject's signals have nothing to do with standard UNIX signals: they connect arbitrary application-specific events with any number of listeners. For example, in GTK+, every user event (keystroke or mouse move) is received from the X server and generates a GTK+ event under the form of a signal emission on a given object instance.

Each signal is registered in the type system together with the type on which it can be emitted: users of the type are said to connect to the signal on a given type instance when they register a closure to be invoked upon the signal emission. Users can also emit the signal by themselves or stop the emission of the signal from within one of the closures connected to the signal.

When a signal is emitted on a given type instance, all the closures connected to this signal on this type instance will be invoked. All the closures connected to such a signal represent callbacks whose signature looks like:

    return_type function_callback (gpointer instance, ... , gpointer user_data);

### Signal registration

To register a new signal on an existing type, we can use any of `g_signal_newv`, `g_signal_new_valist` or `g_signal_new` functions:

    guint g_signal_newv (const gchar        *signal_name,
                         GType               itype,
                         GSignalFlags        signal_flags,
                         GClosure           *class_closure,
                         GSignalAccumulator  accumulator,
                         gpointer            accu_data,
                         GSignalCMarshaller  c_marshaller,
                         GType               return_type,
                         guint               n_params,
                         GType              *param_types);

The number of parameters to these functions is a bit intimidating but they are relatively simple:

- signal_name: is a string which can be used to uniquely identify a given signal.

- itype: is the instance type on which this signal can be emitted.

- signal_flags: partly defines the order in which closures which were connected to the signal are invoked.

- class_closure: this is the default closure for the signal: if it is not NULL upon the signal emission, it will be invoked upon this emission of the signal. The moment where this closure is invoked compared to other closures connected to that signal depends partly on the signal_flags.

- accumulator: this is a function pointer which is invoked after each closure has been invoked. If it returns FALSE, signal emission is stopped. If it returns TRUE, signal emission proceeds normally. It is also used to compute the return value of the signal based on the return value of all the invoked closures.

- accumulator_data: this pointer will be passed down to each invocation of the accumulator during emission.

- c_marshaller: this is the default C marshaller for any closure which is connected to this signal.

- return_type: this is the type of the return value of the signal.

- n_params: this is the number of parameters this signal takes.

- param_types: this is an array of GTypes which indicate the type of each parameter of the signal. The length of this array is indicated by n_params.

As you can see from the above definition, a signal is basically a description of the closures which can be connected to this signal and a description of the order in which the closures connected to this signal will be invoked.

### Signal connection

If you want to connect to a signal with a closure, you have three possibilities:

- You can register a class closure at signal registration: this is a system-wide operation. i.e.: the class_closure will be invoked during each emission of a given signal on all the instances of the type which supports that signal.

- You can use `g_signal_override_class_closure` which overrides the class_closure of a given type. It is possible to call this function only on a derived type of the type on which the signal was registered. This function is of use only to language bindings.

- You can register a closure with the `g_signal_connect` family of functions. This is an instance-specific operation: the closure will be invoked only during emission of a given signal on a given instance.

It is also possible to connect a different kind of callback on a given signal: emission hooks are invoked whenever a given signal is emitted whatever the instance on which it is emitted. Emission hooks are used for example to get all mouse_clicked emissions in an application to be able to emit the small mouse click sound. Emission hooks are connected with `g_signal_add_emission_hook` and removed with `g_signal_remove_emission_hook`.

### Signal emission

Signal emission is done through the use of the `g_signal_emit` family of functions.

    void g_signal_emitv (const GValue *instance_and_params,
                         guint         signal_id,
                         GQuark        detail,
                         GValue       *return_value);

- The instance_and_params array of GValues contains the list of input parameters to the signal. The first element of the array is the instance pointer on which to invoke the signal. The following elements of the array contain the list of parameters to the signal.

- signal_id identifies the signal to invoke.

- detail identifies the specific detail of the signal to invoke. A detail is a kind of magic token/argument which is passed around during signal emission and which is used by closures connected to the signal to filter out unwanted signal emissions. In most cases, you can safely set this value to zero. See for more details about this parameter.

- return_value holds the return value of the last closure invoked during emission if no accumulator was specified. If an accumulator was specified during signal creation, this accumulator is used to calculate the return_value as a function of the return values of all the closures invoked during emission. James (again!!) gives a few non-trivial examples of accumulators: For instance, you may have an accumulator that ignores NULL returns from closures, and only accumulates the non-NULL ones. Another accumulator may try to return the list of values returned by the closures. If no closure is invoked during emission, the return_value is nonetheless initialized to zero/null.

Internally, the GValue array is passed to the emission function proper, `signal_emit_unlocked_R` (implemented in `gsignal.c`). Signal emission can be decomposed in 5 steps:

- RUN_FIRST: if the G_SIGNAL_RUN_FIRST flag was used during signal registration and if there exist a class_closure for this signal, the class_closure is invoked. Jump to EMISSION_HOOK state.

- EMISSION_HOOK: if any emission hook was added to the signal, they are invoked from first to last added. Accumulate return values and jump to HANDLER_RUN_FIRST state.

- HANDLER_RUN_FIRST: if any closure were connected with the `g_signal_connect` family of functions, and if they are not blocked (with the `g_signal_handler_block` family of functions) they are run here, from first to last connected. Jump to RUN_LAST state.

- RUN_LAST: if the G_SIGNAL_RUN_LAST flag was set during registration and if a class_closure was set, it is invoked here. Jump to HANDLER_RUN_LAST state.

- HANDLER_RUN_LAST: if any closure were connected with the `g_signal_connect_after` family of functions, if they were not invoked during HANDLER_RUN_FIRST and if they are not blocked, they are run here, from first to last connected. Jump to RUN_CLEANUP state.

- RUN_CLEANUP: if the G_SIGNAL_RUN_CLEANUP flag was set during registration and if a class_closure was set, it is invoked here. Signal emission is completed here.

If, at any point during emission (except in RUN_CLEANUP state), one of the closures or emission hook stops the signal emission with `g_signal_stop_emission`, emission jumps to CLEANUP state.

If, at any point during emission, one of the closures or emission hook emits the same signal on the same instance, emission is restarted from the RUN_FIRST state.

The accumulator function is invoked in all states, after invocation of each closure (except in EMISSION_HOOK and CLEANUP). It accumulates the closure return value into the signal return value and returns TRUE or FALSE. If, at any point, it does not return TRUE, emission jumps to CLEANUP state.

If no accumulator function was provided, the value returned by the last handler run will be returned by `g_signal_emit`.

### The detail argument

All the functions related to signal emission or signal connection have a parameter named the detail. Sometimes, this parameter is hidden by the API but it is always there, under one form or another.

Of the three main connection functions, only one has an explicit detail parameter as a GQuark A GQuark is an integer which uniquely represents a string. It is possible to transform back and forth between the integer and string representations with the functions `g_quark_from_string` and `g_quark_to_string`. :

    gulong     g_signal_connect_closure_by_id          (gpointer          instance,
                               guint          signal_id,
                               GQuark          detail,
                               GClosure         *closure,
                               gboolean          after);

The two other functions hide the detail parameter in the signal name identification:

    gulong     g_signal_connect_closure          (gpointer          instance,
                               const gchar       *detailed_signal,
                               GClosure         *closure,
                               gboolean          after);
    gulong     g_signal_connect_data              (gpointer          instance,
                               const gchar     *detailed_signal,
                               GCallback      c_handler,
                               gpointer          data,
                               GClosureNotify      destroy_data,
                               GConnectFlags      connect_flags);

Their detailed_signal parameter is a string which identifies the name of the signal to connect to. However, the format of this string is structured to look like signal_name::detail_name. Connecting to the signal named notify::cursor_position will actually connect to the signal named notify with the cursor_position name. Internally, the detail string is transformed to a GQuark if it is present.

Of the four main signal emission functions, three have an explicit detail parameter as a GQuark again:

    void                  g_signal_emitv        (const GValue       *instance_and_params,
                             guint               signal_id,
                             GQuark              detail,
                             GValue             *return_value);
    void                  g_signal_emit_valist  (gpointer            instance,
                             guint               signal_id,
                             GQuark              detail,
                             va_list             var_args);
    void                  g_signal_emit         (gpointer            instance,
                             guint               signal_id,
                             GQuark              detail,
                             ...);

The fourth function hides it in its signal name parameter:

    void                  g_signal_emit_by_name (gpointer            instance,
                             const gchar        *detailed_signal,
                             ...);

The format of the detailed_signal parameter is exactly the same as the format used by the `g_signal_connect` functions: signal_name::detail_name.

If a detail is provided by the user to the emission function, it is used during emission to match against the closures which also provide a detail. If the closures' detail does not match the detail provided by the user, they will not be invoked (even though they are connected to a signal which is being emitted).

This completely optional filtering mechanism is mainly used as an optimization for signals which are often emitted for many different reasons: the clients can filter out which events they are interested in before the closure's marshalling code runs. For example, this is used extensively by the notify signal of GObject: whenever a property is modified on a GObject, instead of just emitting the notify signal, GObject associates as a detail to this signal emission the name of the property modified. This allows clients who wish to be notified of changes to only one property to filter most events before receiving them.

As a simple rule, users can and should set the detail parameter to zero: this will disable completely this optional filtering.