Merge branch 'source-attach-trigger-wakeup' into 'main'

Add g_main_context_new_with_flags() and ownerless polling option

See merge request GNOME/glib!1960
This commit is contained in:
Philip Withnall
2021-11-01 18:39:56 +00:00
4 changed files with 112 additions and 2 deletions

View File

@@ -177,6 +177,15 @@
* g_main_context_prepare(), g_main_context_query(),
* g_main_context_check() and g_main_context_dispatch().
*
* If the event loop thread releases #GMainContext ownership until the results
* required by g_main_context_check() are ready you must create a context with
* the flag %G_MAIN_CONTEXT_FLAGS_OWNERLESS_POLLING or else you'll lose
* g_source_attach() notifications. This happens for instance when you integrate
* the GLib event loop into implementations that follow the proactor pattern
* (i.e. in these contexts the `poll()` implementation will reclaim the thread for
* other tasks until the results are ready). One example of the proactor pattern
* is the Boost.Asio library.
*
* ## State of a Main Context # {#mainloop-states}
*
* The operation of these functions can best be seen in terms
@@ -270,6 +279,7 @@ struct _GMainContext
GCond cond;
GThread *owner;
guint owner_count;
GMainContextFlags flags;
GSList *waiters;
gint ref_count; /* (atomic) */
@@ -658,6 +668,23 @@ g_main_context_new_with_next_id (guint next_id)
**/
GMainContext *
g_main_context_new (void)
{
return g_main_context_new_with_flags (G_MAIN_CONTEXT_FLAGS_NONE);
}
/**
* g_main_context_new_with_flags:
* @flags: a bitwise-OR combination of #GMainContextFlags flags that can only be
* set at creation time.
*
* Creates a new #GMainContext structure.
*
* Returns: (transfer full): the new #GMainContext
*
* Since: 2.72
*/
GMainContext *
g_main_context_new_with_flags (GMainContextFlags flags)
{
static gsize initialised;
GMainContext *context;
@@ -681,6 +708,7 @@ g_main_context_new (void)
context->sources = g_hash_table_new (NULL, NULL);
context->owner = NULL;
context->flags = flags;
context->waiters = NULL;
context->ref_count = 1;
@@ -1248,8 +1276,12 @@ g_source_attach_unlocked (GSource *source,
/* If another thread has acquired the context, wake it up since it
* might be in poll() right now.
*/
if (do_wakeup && context->owner && context->owner != G_THREAD_SELF)
g_wakeup_signal (context->wakeup);
if (do_wakeup &&
(context->flags & G_MAIN_CONTEXT_FLAGS_OWNERLESS_POLLING ||
(context->owner && context->owner != G_THREAD_SELF)))
{
g_wakeup_signal (context->wakeup);
}
g_trace_mark (G_TRACE_CURRENT_TIME, 0,
"GLib", "g_source_attach",