diff options
author | Dan Winship <danw@gnome.org> | 2012-06-22 22:21:05 -0400 |
---|---|---|
committer | Dan Winship <danw@gnome.org> | 2012-06-26 08:40:31 -0400 |
commit | aaaaab91de10445a178e8183a95d98189249e868 (patch) | |
tree | bb8ea0608081633b48441dd8afca57fc52c85d0a | |
parent | 8e65c304315a7f54addd9c2771d20eca007f9d6a (diff) | |
download | glib-aaaaab91de10445a178e8183a95d98189249e868.tar.gz |
gmain: add GSourceIter
add an explicit iterator for GMainContext sources
https://bugzilla.gnome.org/show_bug.cgi?id=619329
-rw-r--r-- | glib/gmain.c | 154 |
1 files changed, 92 insertions, 62 deletions
diff --git a/glib/gmain.c b/glib/gmain.c index 21b3a7245..dea2f3ac0 100644 --- a/glib/gmain.c +++ b/glib/gmain.c @@ -309,6 +309,13 @@ struct _GSourcePrivate GSource *parent_source; }; +typedef struct _GSourceIter +{ + GMainContext *context; + gboolean may_modify; + GSource *source; +} GSourceIter; + #define LOCK_CONTEXT(context) g_mutex_lock (&context->mutex) #define UNLOCK_CONTEXT(context) g_mutex_unlock (&context->mutex) #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, 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, gint *timeout); static gboolean g_timeout_check (GSource *source); @@ -472,7 +486,9 @@ poll_rec_list_free (GMainContext *context, void g_main_context_unref (GMainContext *context) { + GSourceIter iter; GSource *source; + g_return_if_fail (context != NULL); 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); G_UNLOCK (main_context_list); - source = context->source_list; - while (source) - { - GSource *next = source->next; - g_source_destroy_internal (source, context, FALSE); - source = next; - } + g_source_iter_init (&iter, context, TRUE); + while (g_source_iter_next (&iter, &source)) + g_source_destroy_internal (source, context, FALSE); g_mutex_clear (&context->mutex); @@ -804,6 +816,53 @@ g_source_new (GSourceFuncs *source_funcs, 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 */ static void @@ -1702,6 +1761,7 @@ GSource * g_main_context_find_source_by_id (GMainContext *context, guint source_id) { + GSourceIter iter; GSource *source; 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); - source = context->source_list; - while (source) + g_source_iter_init (&iter, context, FALSE); + while (g_source_iter_next (&iter, &source)) { if (!SOURCE_DESTROYED (source) && source->source_id == source_id) break; - source = source->next; } + g_source_iter_clear (&iter); UNLOCK_CONTEXT (context); @@ -1742,6 +1802,7 @@ g_main_context_find_source_by_funcs_user_data (GMainContext *context, GSourceFuncs *funcs, gpointer user_data) { + GSourceIter iter; GSource *source; 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); - source = context->source_list; - while (source) + g_source_iter_init (&iter, context, FALSE); + while (g_source_iter_next (&iter, &source)) { if (!SOURCE_DESTROYED (source) && source->source_funcs == funcs && @@ -1766,8 +1827,8 @@ g_main_context_find_source_by_funcs_user_data (GMainContext *context, if (callback_data == user_data) break; } - source = source->next; } + g_source_iter_clear (&iter); UNLOCK_CONTEXT (context); @@ -1789,6 +1850,7 @@ GSource * g_main_context_find_source_by_user_data (GMainContext *context, gpointer user_data) { + GSourceIter iter; GSource *source; if (context == NULL) @@ -1796,8 +1858,8 @@ g_main_context_find_source_by_user_data (GMainContext *context, LOCK_CONTEXT (context); - source = context->source_list; - while (source) + g_source_iter_init (&iter, context, FALSE); + while (g_source_iter_next (&iter, &source)) { if (!SOURCE_DESTROYED (source) && source->callback_funcs) @@ -1810,8 +1872,8 @@ g_main_context_find_source_by_user_data (GMainContext *context, if (callback_data == user_data) break; } - source = source->next; } + g_source_iter_clear (&iter); UNLOCK_CONTEXT (context); @@ -2562,30 +2624,6 @@ g_main_dispatch (GMainContext *context) 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: * @context: a #GMainContext @@ -2761,6 +2799,7 @@ g_main_context_prepare (GMainContext *context, gint n_ready = 0; gint current_priority = G_MAXINT; GSource *source; + GSourceIter iter; if (context == NULL) context = g_main_context_default (); @@ -2802,18 +2841,15 @@ g_main_context_prepare (GMainContext *context, context->timeout = -1; - source = next_valid_source (context, NULL); - while (source) + g_source_iter_init (&iter, context, TRUE); + while (g_source_iter_next (&iter, &source)) { gint source_timeout = -1; + if (SOURCE_DESTROYED (source) || SOURCE_BLOCKED (source)) + continue; if ((n_ready > 0) && (source->priority > current_priority)) - { - SOURCE_UNREF (source, context); - break; - } - if (SOURCE_BLOCKED (source)) - goto next; + break; if (!(source->flags & G_SOURCE_READY)) { @@ -2856,10 +2892,8 @@ g_main_context_prepare (GMainContext *context, else context->timeout = MIN (context->timeout, source_timeout); } - - next: - source = next_valid_source (context, source); } + g_source_iter_clear (&iter); UNLOCK_CONTEXT (context); @@ -2954,6 +2988,7 @@ g_main_context_check (GMainContext *context, gint n_fds) { GSource *source; + GSourceIter iter; GPollRec *pollrec; gint n_ready = 0; gint i; @@ -2991,16 +3026,13 @@ g_main_context_check (GMainContext *context, i++; } - source = next_valid_source (context, NULL); - while (source) + g_source_iter_init (&iter, context, TRUE); + while (g_source_iter_next (&iter, &source)) { + if (SOURCE_DESTROYED (source) || SOURCE_BLOCKED (source)) + continue; if ((n_ready > 0) && (source->priority > max_priority)) - { - SOURCE_UNREF (source, context); - break; - } - if (SOURCE_BLOCKED (source)) - goto next; + break; if (!(source->flags & G_SOURCE_READY)) { @@ -3041,10 +3073,8 @@ g_main_context_check (GMainContext *context, */ max_priority = source->priority; } - - next: - source = next_valid_source (context, source); } + g_source_iter_clear (&iter); UNLOCK_CONTEXT (context); |