glib.MainLoop.MainLoop Class Reference

List of all members.

Detailed Description

Description The main event loop manages all the available sources of events for GLib and GTK+ applications.

These events can come from any number of different types of sources such as file descriptors (plain files, pipes or sockets) and timeouts. New types of event sources can also be added using g_source_attach(). To allow multiple independent sets of sources to be handled in different threads, each source is associated with a GMainContext. A GMainContext can only be running in a single thread, but sources can be added to it and removed from it from other threads. Each event source is assigned a priority. The default priority, G_PRIORITY_DEFAULT, is 0. Values less than 0 denote higher priorities. Values greater than 0 denote lower priorities. Events from high priority sources are always processed before events from lower priority sources. Idle functions can also be added, and assigned a priority. These will be run whenever no events with a higher priority are ready to be processed. The GMainLoop data type represents a main event loop. A GMainLoop is created with g_main_loop_new(). After adding the initial event sources, g_main_loop_run() is called. This continuously checks for new events from each of the event sources and dispatches them. Finally, the processing of an event from one of the sources leads to a call to g_main_loop_quit() to exit the main loop, and g_main_loop_run() returns. It is possible to create new instances of GMainLoop recursively. This is often used in GTK+ applications when showing modal dialog boxes. Note that event sources are associated with a particular GMainContext, and will be checked and dispatched for all main loops associated with that GMainContext. GTK+ contains wrappers of some of these functions, e.g. gtk_main(), gtk_main_quit() and gtk_events_pending(). Creating new sources types One of the unusual features of the GTK+ main loop functionality is that new types of event source can be created and used in addition to the builtin type of event source. A new event source type is used for handling GDK events. A new source type is created by deriving from the GSource structure. The derived type of source is represented by a structure that has the GSource structure as a first element, and other elements specific to the new source type. To create an instance of the new source type, call g_source_new() passing in the size of the derived structure and a table of functions. These GSourceFuncs determine the behavior of the new source types. New source types basically interact with with the main context in two ways. Their prepare function in GSourceFuncs can set a timeout to determine the maximum amount of time that the main loop will sleep before checking the source again. In addition, or as well, the source can add file descriptors to the set that the main context checks using g_source_add_poll().


Customizing the main loop iteration Single iterations of a GMainContext can be run with g_main_context_iteration(). In some cases, more detailed control of exactly how the details of the main loop work is desired, for instance, when integrating the GMainLoop with an external main loop. In such cases, you can call the component functions of g_main_context_iteration() directly. These functions are g_main_context_prepare(), g_main_context_query(), g_main_context_check() and g_main_context_dispatch(). The operation of these functions can best be seen in terms of a state diagram, as shown in Figure1, States of a Main Context. Figure1.States of a Main Context


Public Member Functions

GMainLoopgetMainLoopStruct ()
 this (GMainLoop *gMainLoop)
 Sets our main struct and passes it to the parent class.
MainLoop ref ()
 Increases the reference count on a GMainLoop object by one.
 this (MainContext context, int isRunning)
 Creates a new GMainLoop structure.
void unref ()
 Decreases the reference count on a GMainLoop object by one.
void run ()
 Runs a main loop until g_main_loop_quit() is called on the loop.
void quit ()
 Stops a GMainLoop from running.
int isRunning ()
 Checks to see if the main loop is currently being run via g_main_loop_run().
MainContext getContext ()
 Returns the GMainContext of loop.

Static Public Member Functions

static int gMainDepth ()
 Return value: The main loop recursion level in the current thread Returns: the depth of the stack of calls to g_main_context_dispatch() on any GMainContext in the current thread.
static Source gMainCurrentSource ()
 Returns the currently firing source for this thread.
static Source gIdleSourceNew ()
 Creates a new idle source.
static uint gIdleAdd (GSourceFunc funct, void *data)
 Adds a function to be called whenever there are no higher priority events pending to the default main loop.
static uint gIdleAddFull (int priority, GSourceFunc funct, void *data, GDestroyNotify notify)
 Adds a function to be called whenever there are no higher priority events pending.
static int gIdleRemoveByData (void *data)
 Removes the idle function with the given data.

Protected Member Functions

void * getStruct ()
 the main Gtk struct as a void*

Protected Attributes

GMainLoopgMainLoop
 the main Gtk struct


Constructor & Destructor Documentation

glib.MainLoop.MainLoop.this ( GMainLoop gMainLoop  ) 

Sets our main struct and passes it to the parent class.

glib.MainLoop.MainLoop.this ( MainContext  context,
int  isRunning 
)

Creates a new GMainLoop structure.

context: a GMainContext (if NULL, the default context will be used). is_running: set to TRUE to indicate that the loop is running. This is not very important since calling g_main_loop_run() will set this to TRUE anyway. Returns: a new GMainLoop.


Member Function Documentation

MainContext glib.MainLoop.MainLoop.getContext (  ) 

Returns the GMainContext of loop.

loop: a GMainLoop. Returns: the GMainContext of loop

GMainLoop* glib.MainLoop.MainLoop.getMainLoopStruct (  ) 

void* glib.MainLoop.MainLoop.getStruct (  )  [protected]

the main Gtk struct as a void*

static uint glib.MainLoop.MainLoop.gIdleAdd ( GSourceFunc  funct,
void *  data 
) [static]

Adds a function to be called whenever there are no higher priority events pending to the default main loop.

The function is given the default idle priority, G_PRIORITY_DEFAULT_IDLE. If the function returns FALSE it is automatically removed from the list of event sources and will not be called again. function: function to call data: data to pass to function. Returns: the ID (greater than 0) of the event source.

static uint glib.MainLoop.MainLoop.gIdleAddFull ( int  priority,
GSourceFunc  funct,
void *  data,
GDestroyNotify  notify 
) [static]

Adds a function to be called whenever there are no higher priority events pending.

If the function returns FALSE it is automatically removed from the list of event sources and will not be called again. priority: the priority of the idle source. Typically this will be in the range btweeen G_PRIORITY_DEFAULT_IDLE and G_PRIORITY_HIGH_IDLE. function: function to call data: data to pass to function notify: function to call when the idle is removed, or NULL Returns: the ID (greater than 0) of the event source.

static int glib.MainLoop.MainLoop.gIdleRemoveByData ( void *  data  )  [static]

Removes the idle function with the given data.

data: the data for the idle source's callback. Returns: TRUE if an idle source was found and removed.

static Source glib.MainLoop.MainLoop.gIdleSourceNew (  )  [static]

Creates a new idle source.

The source will not initially be associated with any GMainContext and must be added to one with g_source_attach() before it will be executed. Note that the default priority for idle sources is G_PRIORITY_DEFAULT_IDLE, as compared to other sources which have a default priority of G_PRIORITY_DEFAULT. Returns: the newly-created idle source

static Source glib.MainLoop.MainLoop.gMainCurrentSource (  )  [static]

Returns the currently firing source for this thread.

Returns: The currently firing source or NULL. Since 2.12

static int glib.MainLoop.MainLoop.gMainDepth (  )  [static]

Return value: The main loop recursion level in the current thread Returns: the depth of the stack of calls to g_main_context_dispatch() on any GMainContext in the current thread.

That is, when called from the toplevel, it gives 0. When called from within a callback from g_main_context_iteration() (or g_main_loop_run(), etc.) it returns 1. When called from within a callback to a recursive call to g_main_context_iterate(), it returns 2. And so forth. This function is useful in a situation like the following: Imagine an extremely simple "garbage collected" system. Example1. static GList *free_list; gpointer allocate_memory (gsize size) { gpointer result = g_malloc (size); free_list = g_list_prepend (free_list, result); return result; } void free_allocated_memory (void) { GList *l; for (l = free_list; l; l = l->next); g_free (l->data); g_list_free (free_list); free_list = NULL; } [...] while (TRUE); { g_main_context_iteration (NULL, TRUE); free_allocated_memory(); } This works from an application, however, if you want to do the same thing from a library, it gets more difficult, since you no longer control the main loop. You might think you can simply use an idle function to make the call to free_allocated_memory(), but that doesn't work, since the idle function could be called from a recursive callback. This can be fixed by using g_main_depth() Example2. gpointer allocate_memory (gsize size) { FreeListBlock *block = g_new (FreeListBlock, 1);\ block->mem = g_malloc (size); block->depth = g_main_depth(); free_list = g_list_prepend (free_list, block); return block->mem; } void free_allocated_memory (void) { GList *l; int depth = g_main_depth(); for (l = free_list; l; ); { GList *next = l->next; FreeListBlock *block = l->data; if (block->depth > depth) { g_free (block->mem); g_free (block); free_list = g_list_delete_link (free_list, l); } l = next; } } There is a temptation to use g_main_depth() to solve problems with reentrancy. For instance, while waiting for data to be received from the network in response to a menu item, the menu item might be selected again. It might seem that one could make the menu item's callback return immediately and do nothing if g_main_depth() returns a value greater than 1. However, this should be avoided since the user then sees selecting the menu item do nothing. Furthermore, you'll find yourself adding these checks all over your code, since there are doubtless many, many things that the user could do. Instead, you can use the following techniques: Use gtk_widget_set_sensitive() or modal dialogs to prevent the user from interacting with elements while the main loop is recursing. Avoid main loop recursion in situations where you can't handle arbitrary callbacks. Instead, structure your code so that you simply return to the main loop and then get called again when there is more work to do.

int glib.MainLoop.MainLoop.isRunning (  ) 

Checks to see if the main loop is currently being run via g_main_loop_run().

loop: a GMainLoop. Returns: TRUE if the mainloop is currently being run.

void glib.MainLoop.MainLoop.quit (  ) 

Stops a GMainLoop from running.

Any calls to g_main_loop_run() for the loop will return. loop: a GMainLoop

MainLoop glib.MainLoop.MainLoop.ref (  ) 

Increases the reference count on a GMainLoop object by one.

loop: a GMainLoop Returns: loop

void glib.MainLoop.MainLoop.run (  ) 

Runs a main loop until g_main_loop_quit() is called on the loop.

If this is called for the thread of the loop's GMainContext, it will process events from the loop, otherwise it will simply wait. loop: a GMainLoop

void glib.MainLoop.MainLoop.unref (  ) 

Decreases the reference count on a GMainLoop object by one.

If the result is zero, free the loop and free all associated memory. loop: a GMainLoop


Member Data Documentation

GMainLoop* glib.MainLoop.MainLoop.gMainLoop [protected]

the main Gtk struct


SourceForge.net Logo DSource.org Logo digitalmars.com Logo