mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-11 03:46:17 +01:00
gmain: add GSourceIter
add an explicit iterator for GMainContext sources https://bugzilla.gnome.org/show_bug.cgi?id=619329
This commit is contained in:
parent
8e65c30431
commit
aaaaab91de
148
glib/gmain.c
148
glib/gmain.c
@ -309,6 +309,13 @@ struct _GSourcePrivate
|
|||||||
GSource *parent_source;
|
GSource *parent_source;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct _GSourceIter
|
||||||
|
{
|
||||||
|
GMainContext *context;
|
||||||
|
gboolean may_modify;
|
||||||
|
GSource *source;
|
||||||
|
} GSourceIter;
|
||||||
|
|
||||||
#define LOCK_CONTEXT(context) g_mutex_lock (&context->mutex)
|
#define LOCK_CONTEXT(context) g_mutex_lock (&context->mutex)
|
||||||
#define UNLOCK_CONTEXT(context) g_mutex_unlock (&context->mutex)
|
#define UNLOCK_CONTEXT(context) g_mutex_unlock (&context->mutex)
|
||||||
#define G_THREAD_SELF g_thread_self ()
|
#define G_THREAD_SELF g_thread_self ()
|
||||||
@ -347,6 +354,13 @@ static void g_main_context_add_poll_unlocked (GMainContext *context,
|
|||||||
static void g_main_context_remove_poll_unlocked (GMainContext *context,
|
static void g_main_context_remove_poll_unlocked (GMainContext *context,
|
||||||
GPollFD *fd);
|
GPollFD *fd);
|
||||||
|
|
||||||
|
static void g_source_iter_init (GSourceIter *iter,
|
||||||
|
GMainContext *context,
|
||||||
|
gboolean may_modify);
|
||||||
|
static gboolean g_source_iter_next (GSourceIter *iter,
|
||||||
|
GSource **source);
|
||||||
|
static void g_source_iter_clear (GSourceIter *iter);
|
||||||
|
|
||||||
static gboolean g_timeout_prepare (GSource *source,
|
static gboolean g_timeout_prepare (GSource *source,
|
||||||
gint *timeout);
|
gint *timeout);
|
||||||
static gboolean g_timeout_check (GSource *source);
|
static gboolean g_timeout_check (GSource *source);
|
||||||
@ -472,7 +486,9 @@ poll_rec_list_free (GMainContext *context,
|
|||||||
void
|
void
|
||||||
g_main_context_unref (GMainContext *context)
|
g_main_context_unref (GMainContext *context)
|
||||||
{
|
{
|
||||||
|
GSourceIter iter;
|
||||||
GSource *source;
|
GSource *source;
|
||||||
|
|
||||||
g_return_if_fail (context != NULL);
|
g_return_if_fail (context != NULL);
|
||||||
g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
|
g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
|
||||||
|
|
||||||
@ -483,13 +499,9 @@ g_main_context_unref (GMainContext *context)
|
|||||||
main_context_list = g_slist_remove (main_context_list, context);
|
main_context_list = g_slist_remove (main_context_list, context);
|
||||||
G_UNLOCK (main_context_list);
|
G_UNLOCK (main_context_list);
|
||||||
|
|
||||||
source = context->source_list;
|
g_source_iter_init (&iter, context, TRUE);
|
||||||
while (source)
|
while (g_source_iter_next (&iter, &source))
|
||||||
{
|
|
||||||
GSource *next = source->next;
|
|
||||||
g_source_destroy_internal (source, context, FALSE);
|
g_source_destroy_internal (source, context, FALSE);
|
||||||
source = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_mutex_clear (&context->mutex);
|
g_mutex_clear (&context->mutex);
|
||||||
|
|
||||||
@ -804,6 +816,53 @@ g_source_new (GSourceFuncs *source_funcs,
|
|||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Holds context's lock */
|
||||||
|
static void
|
||||||
|
g_source_iter_init (GSourceIter *iter,
|
||||||
|
GMainContext *context,
|
||||||
|
gboolean may_modify)
|
||||||
|
{
|
||||||
|
iter->context = context;
|
||||||
|
iter->source = NULL;
|
||||||
|
iter->may_modify = may_modify;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Holds context's lock */
|
||||||
|
static gboolean
|
||||||
|
g_source_iter_next (GSourceIter *iter, GSource **source)
|
||||||
|
{
|
||||||
|
GSource *next_source;
|
||||||
|
|
||||||
|
if (iter->source)
|
||||||
|
{
|
||||||
|
next_source = iter->source->next;
|
||||||
|
if (iter->may_modify)
|
||||||
|
SOURCE_UNREF (iter->source, iter->context);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
next_source = iter->context->source_list;
|
||||||
|
|
||||||
|
iter->source = next_source;
|
||||||
|
if (iter->source && iter->may_modify)
|
||||||
|
iter->source->ref_count++;
|
||||||
|
|
||||||
|
*source = iter->source;
|
||||||
|
return *source != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Holds context's lock. Only necessary to call if you broke out of
|
||||||
|
* the g_source_iter_next() loop early.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
g_source_iter_clear (GSourceIter *iter)
|
||||||
|
{
|
||||||
|
if (iter->source && iter->may_modify)
|
||||||
|
{
|
||||||
|
SOURCE_UNREF (iter->source, iter->context);
|
||||||
|
iter->source = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Holds context's lock
|
/* Holds context's lock
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
@ -1702,6 +1761,7 @@ GSource *
|
|||||||
g_main_context_find_source_by_id (GMainContext *context,
|
g_main_context_find_source_by_id (GMainContext *context,
|
||||||
guint source_id)
|
guint source_id)
|
||||||
{
|
{
|
||||||
|
GSourceIter iter;
|
||||||
GSource *source;
|
GSource *source;
|
||||||
|
|
||||||
g_return_val_if_fail (source_id > 0, NULL);
|
g_return_val_if_fail (source_id > 0, NULL);
|
||||||
@ -1711,14 +1771,14 @@ g_main_context_find_source_by_id (GMainContext *context,
|
|||||||
|
|
||||||
LOCK_CONTEXT (context);
|
LOCK_CONTEXT (context);
|
||||||
|
|
||||||
source = context->source_list;
|
g_source_iter_init (&iter, context, FALSE);
|
||||||
while (source)
|
while (g_source_iter_next (&iter, &source))
|
||||||
{
|
{
|
||||||
if (!SOURCE_DESTROYED (source) &&
|
if (!SOURCE_DESTROYED (source) &&
|
||||||
source->source_id == source_id)
|
source->source_id == source_id)
|
||||||
break;
|
break;
|
||||||
source = source->next;
|
|
||||||
}
|
}
|
||||||
|
g_source_iter_clear (&iter);
|
||||||
|
|
||||||
UNLOCK_CONTEXT (context);
|
UNLOCK_CONTEXT (context);
|
||||||
|
|
||||||
@ -1742,6 +1802,7 @@ g_main_context_find_source_by_funcs_user_data (GMainContext *context,
|
|||||||
GSourceFuncs *funcs,
|
GSourceFuncs *funcs,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
|
GSourceIter iter;
|
||||||
GSource *source;
|
GSource *source;
|
||||||
|
|
||||||
g_return_val_if_fail (funcs != NULL, NULL);
|
g_return_val_if_fail (funcs != NULL, NULL);
|
||||||
@ -1751,8 +1812,8 @@ g_main_context_find_source_by_funcs_user_data (GMainContext *context,
|
|||||||
|
|
||||||
LOCK_CONTEXT (context);
|
LOCK_CONTEXT (context);
|
||||||
|
|
||||||
source = context->source_list;
|
g_source_iter_init (&iter, context, FALSE);
|
||||||
while (source)
|
while (g_source_iter_next (&iter, &source))
|
||||||
{
|
{
|
||||||
if (!SOURCE_DESTROYED (source) &&
|
if (!SOURCE_DESTROYED (source) &&
|
||||||
source->source_funcs == funcs &&
|
source->source_funcs == funcs &&
|
||||||
@ -1766,8 +1827,8 @@ g_main_context_find_source_by_funcs_user_data (GMainContext *context,
|
|||||||
if (callback_data == user_data)
|
if (callback_data == user_data)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
source = source->next;
|
|
||||||
}
|
}
|
||||||
|
g_source_iter_clear (&iter);
|
||||||
|
|
||||||
UNLOCK_CONTEXT (context);
|
UNLOCK_CONTEXT (context);
|
||||||
|
|
||||||
@ -1789,6 +1850,7 @@ GSource *
|
|||||||
g_main_context_find_source_by_user_data (GMainContext *context,
|
g_main_context_find_source_by_user_data (GMainContext *context,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
|
GSourceIter iter;
|
||||||
GSource *source;
|
GSource *source;
|
||||||
|
|
||||||
if (context == NULL)
|
if (context == NULL)
|
||||||
@ -1796,8 +1858,8 @@ g_main_context_find_source_by_user_data (GMainContext *context,
|
|||||||
|
|
||||||
LOCK_CONTEXT (context);
|
LOCK_CONTEXT (context);
|
||||||
|
|
||||||
source = context->source_list;
|
g_source_iter_init (&iter, context, FALSE);
|
||||||
while (source)
|
while (g_source_iter_next (&iter, &source))
|
||||||
{
|
{
|
||||||
if (!SOURCE_DESTROYED (source) &&
|
if (!SOURCE_DESTROYED (source) &&
|
||||||
source->callback_funcs)
|
source->callback_funcs)
|
||||||
@ -1810,8 +1872,8 @@ g_main_context_find_source_by_user_data (GMainContext *context,
|
|||||||
if (callback_data == user_data)
|
if (callback_data == user_data)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
source = source->next;
|
|
||||||
}
|
}
|
||||||
|
g_source_iter_clear (&iter);
|
||||||
|
|
||||||
UNLOCK_CONTEXT (context);
|
UNLOCK_CONTEXT (context);
|
||||||
|
|
||||||
@ -2562,30 +2624,6 @@ g_main_dispatch (GMainContext *context)
|
|||||||
g_ptr_array_set_size (context->pending_dispatches, 0);
|
g_ptr_array_set_size (context->pending_dispatches, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Holds context's lock */
|
|
||||||
static inline GSource *
|
|
||||||
next_valid_source (GMainContext *context,
|
|
||||||
GSource *source)
|
|
||||||
{
|
|
||||||
GSource *new_source = source ? source->next : context->source_list;
|
|
||||||
|
|
||||||
while (new_source)
|
|
||||||
{
|
|
||||||
if (!SOURCE_DESTROYED (new_source))
|
|
||||||
{
|
|
||||||
new_source->ref_count++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
new_source = new_source->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (source)
|
|
||||||
SOURCE_UNREF (source, context);
|
|
||||||
|
|
||||||
return new_source;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_main_context_acquire:
|
* g_main_context_acquire:
|
||||||
* @context: a #GMainContext
|
* @context: a #GMainContext
|
||||||
@ -2761,6 +2799,7 @@ g_main_context_prepare (GMainContext *context,
|
|||||||
gint n_ready = 0;
|
gint n_ready = 0;
|
||||||
gint current_priority = G_MAXINT;
|
gint current_priority = G_MAXINT;
|
||||||
GSource *source;
|
GSource *source;
|
||||||
|
GSourceIter iter;
|
||||||
|
|
||||||
if (context == NULL)
|
if (context == NULL)
|
||||||
context = g_main_context_default ();
|
context = g_main_context_default ();
|
||||||
@ -2802,18 +2841,15 @@ g_main_context_prepare (GMainContext *context,
|
|||||||
|
|
||||||
context->timeout = -1;
|
context->timeout = -1;
|
||||||
|
|
||||||
source = next_valid_source (context, NULL);
|
g_source_iter_init (&iter, context, TRUE);
|
||||||
while (source)
|
while (g_source_iter_next (&iter, &source))
|
||||||
{
|
{
|
||||||
gint source_timeout = -1;
|
gint source_timeout = -1;
|
||||||
|
|
||||||
|
if (SOURCE_DESTROYED (source) || SOURCE_BLOCKED (source))
|
||||||
|
continue;
|
||||||
if ((n_ready > 0) && (source->priority > current_priority))
|
if ((n_ready > 0) && (source->priority > current_priority))
|
||||||
{
|
|
||||||
SOURCE_UNREF (source, context);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
if (SOURCE_BLOCKED (source))
|
|
||||||
goto next;
|
|
||||||
|
|
||||||
if (!(source->flags & G_SOURCE_READY))
|
if (!(source->flags & G_SOURCE_READY))
|
||||||
{
|
{
|
||||||
@ -2856,10 +2892,8 @@ g_main_context_prepare (GMainContext *context,
|
|||||||
else
|
else
|
||||||
context->timeout = MIN (context->timeout, source_timeout);
|
context->timeout = MIN (context->timeout, source_timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
next:
|
|
||||||
source = next_valid_source (context, source);
|
|
||||||
}
|
}
|
||||||
|
g_source_iter_clear (&iter);
|
||||||
|
|
||||||
UNLOCK_CONTEXT (context);
|
UNLOCK_CONTEXT (context);
|
||||||
|
|
||||||
@ -2954,6 +2988,7 @@ g_main_context_check (GMainContext *context,
|
|||||||
gint n_fds)
|
gint n_fds)
|
||||||
{
|
{
|
||||||
GSource *source;
|
GSource *source;
|
||||||
|
GSourceIter iter;
|
||||||
GPollRec *pollrec;
|
GPollRec *pollrec;
|
||||||
gint n_ready = 0;
|
gint n_ready = 0;
|
||||||
gint i;
|
gint i;
|
||||||
@ -2991,16 +3026,13 @@ g_main_context_check (GMainContext *context,
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
source = next_valid_source (context, NULL);
|
g_source_iter_init (&iter, context, TRUE);
|
||||||
while (source)
|
while (g_source_iter_next (&iter, &source))
|
||||||
{
|
{
|
||||||
|
if (SOURCE_DESTROYED (source) || SOURCE_BLOCKED (source))
|
||||||
|
continue;
|
||||||
if ((n_ready > 0) && (source->priority > max_priority))
|
if ((n_ready > 0) && (source->priority > max_priority))
|
||||||
{
|
|
||||||
SOURCE_UNREF (source, context);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
if (SOURCE_BLOCKED (source))
|
|
||||||
goto next;
|
|
||||||
|
|
||||||
if (!(source->flags & G_SOURCE_READY))
|
if (!(source->flags & G_SOURCE_READY))
|
||||||
{
|
{
|
||||||
@ -3041,10 +3073,8 @@ g_main_context_check (GMainContext *context,
|
|||||||
*/
|
*/
|
||||||
max_priority = source->priority;
|
max_priority = source->priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
next:
|
|
||||||
source = next_valid_source (context, source);
|
|
||||||
}
|
}
|
||||||
|
g_source_iter_clear (&iter);
|
||||||
|
|
||||||
UNLOCK_CONTEXT (context);
|
UNLOCK_CONTEXT (context);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user