manages all available sources of events.
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 <g-main-context>
. A
<g-main-context>
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 <g-main-loop>
data type represents a main event loop. A
<g-main-loop>
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 <g-main-loop>
recursively. This
is often used in GTK+ applications when showing modal dialog boxes. Note that
event sources are associated with a particular <g-main-context>
, and will
be checked and dispatched for all main loops associated with that
<g-main-context>
.
GTK+ contains wrappers of some of these functions, e.g. gtk-main
,
gtk-main-quit
and gtk-events-pending
.
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 <g-source>
structure.
The derived type of source is represented by a structure that has the
<g-source>
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 <g-source-funcs>
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 <g-source-funcs>
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
.
Single iterations of a <g-main-context>
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 <g-main-loop>
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 (the missing figure, mainloop-states.
<g-main-context>
) (is_running bool
) ⇒ (ret <g-main-loop>
)Creates a new
<g-main-loop>
structure.
- context
- a
<g-main-context>
(if ‘#f
’, the default context will be used).- is-running
- set to ‘
#t
’ to indicate that the loop is running. This is not very important since callingg-main-loop-run
will set this to ‘#t
’ anyway.- ret
- a new
<g-main-loop>
.
<g-main-loop>
)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<g-main-context>
, it will process events from the loop, otherwise it will simply wait.
- loop
- a
<g-main-loop>
<g-main-loop>
)Stops a
<g-main-loop>
from running. Any calls tog-main-loop-run
for the loop will return.
- loop
- a
<g-main-loop>
<g-main-loop>
) ⇒ (ret bool
)Checks to see if the main loop is currently being run via
g-main-loop-run
.
- loop
- a
<g-main-loop>
.- ret
- ‘
#t
’ if the mainloop is currently being run.
<g-main-loop>
) ⇒ (ret <g-main-context>
)Returns the
<g-main-context>
of loop.
- loop
- a
<g-main-loop>
.- ret
- the
<g-main-context>
of loop
<g-main-context>
)Creates a new
<g-main-context>
strcuture
- ret
- the new
<g-main-context>
<g-main-context>
)Returns the default main context. This is the main context used for main loop functions when a main loop is not explicitly specified.
- ret
- the default main context.
<g-main-context>
) (may_block bool
) ⇒ (ret bool
)Runs a single iteration for the given main loop. This involves checking to see if any event sources are ready to be processed, then if no events sources are ready and may-block is ‘
#t
’, waiting for a source to become ready, then dispatching the highest priority events sources that are ready. Note that even when may-block is ‘#t
’, it is still possible forg-main-context-iteration
to return ‘#f
’, since the the wait may be interrupted for other reasons than an event source becoming ready.
- context
- a
<g-main-context>
(if ‘#f
’, the default context will be used)- may-block
- whether the call may block.
- ret
- ‘
#t
’ if events were dispatched.
<g-main-context>
) ⇒ (ret bool
)Checks if any sources have pending events for the given context.
- context
- a
<g-main-context>
(if ‘#f
’, the default context will be used)- ret
- ‘
#t
’ if events are pending.
<g-main-context>
) (source_id unsigned-int
) ⇒ (ret <g-source>
)Finds a
<g-source>
given a pair of context and ID.
- context
- a
<g-main-context>
(if ‘#f
’, the default context will be used)- source-id
- the source ID, as returned by
g-source-get-id
.- ret
- the
<g-source>
if found, otherwise, ‘#f
’
<g-main-context>
)If context is currently waiting in a
poll
, interrupt thepoll
, and continue the iteration process.
- context
- a
<g-main-context>
<g-main-context>
) ⇒ (ret bool
)Tries to become the owner of the specified context. If some other context is the owner of the context, returns ‘
#f
’ immediately. Ownership is properly recursive: the owner can require ownership again and will release ownership wheng-main-context-release
is called as many times asg-main-context-acquire
.You must be the owner of a context before you can call
g-main-context-prepare
,g-main-context-query
,g-main-context-check
,g-main-context-dispatch
.
- context
- a
<g-main-context>
- ret
- ‘
#t
’ if the operation succeeded, and this thread is now the owner of context.
<g-main-context>
)Releases ownership of a context previously acquired by this thread with
g-main-context-acquire
. If the context was acquired multiple times, the only release ownership wheng-main-context-release
is called as many times as it was acquired.
- context
- a
<g-main-context>
<g-main-context>
) ⇒ (ret bool
)Determines whether this thread holds the (recursive) ownership of this
<g-maincontext>
. This is useful to know before waiting on another thread that may be blocking to get ownership of context.
- context
- a
<g-main-context>
- ret
- ‘
#t
’ if current thread is owner of context.Since 2.10
<g-main-context>
) ⇒ (ret bool
) (priority int
)Prepares to poll sources within a main loop. The resulting information for polling is determined by calling
g-main-context-query
.
- context
- a
<g-main-context>
- priority
- location to store priority of highest priority source already ready.
- ret
- ‘
#t
’ if some source is ready to be dispatched prior to polling.
int
)Return value: The main loop recursion level in the current thread
The value returned is the depth of the stack of calls to
g-main-context-dispatch
on any<g-main-context>
in the current thread. That is, when called from the toplevel, it gives 0. When called from within a callback fromg-main-context-iteration
(org-main-loop-run
, etc.) it returns 1. When called from within a callback to a recursive call tog-main-context-iterate
, it returns 2. And so forth.This function is an attractive nuisance, and its use normally indicates a misunderstanding of how main loop reentrancy works. Use
gtk-widget-set-sensitive
or modal dialogs to prevent the user from interacting with elements while the main loop is recursing.A better idea is to avoid main loop recursion entirely. 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.
<g-source>
)Returns the currently firing source for this thread.
- ret
- The currently firing source or ‘
#f
’.Since 2.12
unsigned-int
) ⇒ (ret <g-source>
)Creates a new timeout source.
The source will not initially be associated with any
<g-main-context>
and must be added to one withg-source-attach
before it will be executed.
- interval
- the timeout interval in milliseconds.
- ret
- the newly-created timeout source
<g-source>
)Creates a new idle source.
The source will not initially be associated with any
<g-main-context>
and must be added to one withg-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’.
- ret
- the newly-created idle source
int
) ⇒ (ret <g-source>
)Creates a new child_watch source.
The source will not initially be associated with any
<g-main-context>
and must be added to one withg-source-attach
before it will be executed.Note that child watch sources can only be used in conjunction with ‘g_spawn...’ when the ‘G_SPAWN_DO_NOT_REAP_CHILD’ flag is used.
Note that on platforms where
<g-pid>
must be explicitly closed (seeg-spawn-close-pid
) pid must not be closed while the source is still active. Typically, you will want to callg-spawn-close-pid
in the callback function for the source.Note further that using
g-child-watch-source-new
is not compatible with calling ‘waitpid(-1)’ in the application. Callingwaitpid
for individual pids will still work fine.
- pid
- process id of a child process to watch. On Windows, a HANDLE for the process to watch (which actually doesn't have to be a child).
- ret
- the newly-created child watch source
Since 2.4
<g-source>
) (context <g-main-context>
) ⇒ (ret unsigned-int
)Adds a
<g-source>
to a context so that it will be executed within that context.
- source
- a
<g-source>
- context
- a
<g-main-context>
(if ‘#f
’, the default context will be used)- ret
- the ID (greater than 0) for the source within the
<g-main-context>
.
<g-source>
)Removes a source from its
<g-main-context>
, if any, and mark it as destroyed. The source cannot be subsequently added to another context.
- source
- a
<g-source>
<g-source>
) ⇒ (ret bool
)Returns whether source has been destroyed.
This is important when you operate upon your objects from within idle handlers, but may have freed the object before the dispatch of your idle handler.
static gboolean idle_callback (gpointer data) { SomeWidget *self = data; GDK_THREADS_ENTER (); /* do stuff with self */ self->idle_id = 0; GDK_THREADS_LEAVE (); return FALSE; } static void some_widget_do_stuff_later (SomeWidget *self) { self->idle_id = g_idle_add (idle_callback, self); } static void some_widget_finalize (GObject *object) { SomeWidget *self = SOME_WIDGET (object); if (self->idle_id) g_source_remove (self->idle_id); G_OBJECT_CLASS (parent_class)->finalize (object); }This will fail in a multi-threaded application if the widget is destroyed before the idle handler fires due to the use after free in the callback. A solution, to this particular problem, is to check to if the source has already been destroy within the callback.
static gboolean idle_callback (gpointer data) { SomeWidget *self = data; GDK_THREADS_ENTER (); if (!g_source_is_destroyed (g_main_current_source ())) { /* do stuff with self */ } GDK_THREADS_LEAVE (); return FALSE; }
- source
- a
<g-source>
- ret
- ‘
#t
’ if the source has been destroyedSince 2.12
<g-source>
) (priority int
)Sets the priority of a source. While the main loop is being run, a source will be dispatched if it is ready to be dispatched and no sources at a higher (numerically smaller) priority are ready to be dispatched.
- source
- a
<g-source>
- priority
- the new priority.
<g-source>
) ⇒ (ret int
)Gets the priority of a source.
- source
- a
<g-source>
- ret
- the priority of the source
<g-source>
) (can_recurse bool
)Sets whether a source can be called recursively. If can-recurse is ‘
#t
’, then while the source is being dispatched then this source will be processed normally. Otherwise, all processing of this source is blocked until the dispatch function returns.
- source
- a
<g-source>
- can-recurse
- whether recursion is allowed for this source
<g-source>
) ⇒ (ret bool
)Checks whether a source is allowed to be called recursively. see
g-source-set-can-recurse
.
- source
- a
<g-source>
- ret
- whether recursion is allowed.
<g-source>
) ⇒ (ret unsigned-int
)Returns the numeric ID for a particular source. The ID of a source is a positive integer which is unique within a particular main loop context. The reverse mapping from ID to source is done by
g-main-context-find-source-by-id
.
- source
- a
<g-source>
- ret
- the ID (greater than 0) for the source
<g-source>
) ⇒ (ret <g-main-context>
)Gets the
<g-main-context>
with which the source is associated. Calling this function on a destroyed source is an error.
- source
- a
<g-source>
- ret
- the
<g-main-context>
with which the source is associated, or ‘#f
’ if the context has not yet been added to a source.
unsigned-int
) ⇒ (ret bool
)Removes the source with the given id from the default main context. The id of a
<g-source>
is given byg-source-get-id
, or will be returned by the functionsg-source-attach
,g-idle-add
,g-idle-add-full
,g-timeout-add
,g-timeout-add-full
,g-child-watch-add
,g-child-watch-add-full
,g-io-add-watch
, andg-io-add-watch-full
.See also
g-source-destroy
.
- tag
- the ID of the source to remove.
- ret
- ‘
#t
’ if the source was found and removed.