mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-27 07:56:14 +01:00
Bug 618737 - "dispatch to context" functionality
Adds a new function g_main_context_invoke() (and _full() variant). This function takes a main context, a function and a user_data. If the main context is already acquired in the current thread, the function is invoked directly. If the main context is the default main context of the current thread and it can be acquired then the function is invoked directly while the context is owned. Otherwise, the function is scheduled as an idle on the context.
This commit is contained in:
parent
63fb3ff774
commit
92974b80fc
@ -708,6 +708,8 @@ g_main_context_set_poll_func
|
||||
g_main_context_unref
|
||||
g_main_context_wait
|
||||
g_main_context_wakeup
|
||||
g_main_context_invoke
|
||||
g_main_context_invoke_full
|
||||
g_main_depth
|
||||
g_main_current_source
|
||||
g_main_loop_get_context
|
||||
|
110
glib/gmain.c
110
glib/gmain.c
@ -4356,3 +4356,113 @@ g_idle_remove_by_data (gpointer data)
|
||||
{
|
||||
return g_source_remove_by_funcs_user_data (&g_idle_funcs, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_main_context_invoke:
|
||||
* @context: a #GMainContext, or %NULL
|
||||
* @function: function to call
|
||||
* @data: data to pass to @function
|
||||
*
|
||||
* Invokes a function in such a way that @context is owned during the
|
||||
* invocation of @function.
|
||||
*
|
||||
* If @context is %NULL then the global default main context — as
|
||||
* returned by g_main_context_default() — is used.
|
||||
*
|
||||
* If @context is owned by the current thread, @function is called
|
||||
* directly. Otherwise, if @context is the thread-default main context
|
||||
* of the current thread and g_main_context_acquire() succeeds, then
|
||||
* @function is called and g_main_context_release() is called
|
||||
* afterwards.
|
||||
*
|
||||
* In any other case, an idle source is created to call @function and
|
||||
* that source is attached to @context (presumably to be run in another
|
||||
* thread). The idle source is attached with #G_PRIORITY_DEFAULT
|
||||
* priority. If you want a different priority, use
|
||||
* g_main_context_invoke_full().
|
||||
*
|
||||
* Note that, as with normal idle functions, @function should probably
|
||||
* return %FALSE. If it returns %TRUE, it will be continuously run in a
|
||||
* loop (and may prevent this call from returning).
|
||||
*
|
||||
* Since: 2.28
|
||||
**/
|
||||
void
|
||||
g_main_context_invoke (GMainContext *context,
|
||||
GSourceFunc function,
|
||||
gpointer data)
|
||||
{
|
||||
g_main_context_invoke_full (context,
|
||||
G_PRIORITY_DEFAULT,
|
||||
function, data, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_main_context_invoke_full:
|
||||
* @context: a #GMainContext, or %NULL
|
||||
* @priority: the priority at which to run @function
|
||||
* @function: function to call
|
||||
* @data: data to pass to @function
|
||||
* @notify: a function to call when @data is no longer in use, or %NULL.
|
||||
*
|
||||
* Invokes a function in such a way that @context is owned during the
|
||||
* invocation of @function.
|
||||
*
|
||||
* This function is the same as g_main_context_invoke() except that it
|
||||
* lets you specify the priority incase @function ends up being
|
||||
* scheduled as an idle and also lets you give a #GDestroyNotify for @data.
|
||||
*
|
||||
* @notify should not assume that it is called from any particular
|
||||
* thread or with any particular context acquired.
|
||||
*
|
||||
* Since: 2.28
|
||||
**/
|
||||
void
|
||||
g_main_context_invoke_full (GMainContext *context,
|
||||
gint priority,
|
||||
GSourceFunc function,
|
||||
gpointer data,
|
||||
GDestroyNotify notify)
|
||||
{
|
||||
g_return_if_fail (function != NULL);
|
||||
|
||||
if (!context)
|
||||
context = g_main_context_default ();
|
||||
|
||||
if (g_main_context_is_owner (context))
|
||||
{
|
||||
while (function (data));
|
||||
if (notify != NULL)
|
||||
notify (data);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
GMainContext *thread_default;
|
||||
|
||||
thread_default = g_main_context_get_thread_default ();
|
||||
|
||||
if (!thread_default)
|
||||
thread_default = g_main_context_default ();
|
||||
|
||||
if (thread_default == context && g_main_context_acquire (context))
|
||||
{
|
||||
while (function (data));
|
||||
|
||||
g_main_context_release (context);
|
||||
|
||||
if (notify != NULL)
|
||||
notify (data);
|
||||
}
|
||||
else
|
||||
{
|
||||
GSource *source;
|
||||
|
||||
source = g_idle_source_new ();
|
||||
g_source_set_priority (source, priority);
|
||||
g_source_set_callback (source, function, data, notify);
|
||||
g_source_attach (source, context);
|
||||
g_source_unref (source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -521,6 +521,15 @@ guint g_idle_add_full (gint priority,
|
||||
GDestroyNotify notify);
|
||||
gboolean g_idle_remove_by_data (gpointer data);
|
||||
|
||||
void g_main_context_invoke_full (GMainContext *context,
|
||||
gint priority,
|
||||
GSourceFunc function,
|
||||
gpointer data,
|
||||
GDestroyNotify notify);
|
||||
void g_main_context_invoke (GMainContext *context,
|
||||
GSourceFunc function,
|
||||
gpointer data);
|
||||
|
||||
/* Hook for GClosure / GSource integration. Don't touch */
|
||||
GLIB_VAR GSourceFuncs g_timeout_funcs;
|
||||
GLIB_VAR GSourceFuncs g_child_watch_funcs;
|
||||
|
Loading…
Reference in New Issue
Block a user