[glib] gmain: Remove dispatching source stack



commit 5ad7893b51d8652561dff72c70d6cb53416a31bf
Author: Ryan Lortie <desrt desrt ca>
Date:   Wed Jun 12 14:57:09 2013 -0400

    gmain: Remove dispatching source stack
    
    This stack exists only to answer the question of "what is the currently
    dispatching source" and is handled in a way that makes it very clear
    that we don't need to be using a linked list at all...
    
    Just store the GSource directly.
    
    Independently discovered (and same solution) by Phillip Susi.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=709113

 glib/gmain.c |   37 ++++++++++++++-----------------------
 1 files changed, 14 insertions(+), 23 deletions(-)
---
diff --git a/glib/gmain.c b/glib/gmain.c
index 4edf05e..9f044fb 100644
--- a/glib/gmain.c
+++ b/glib/gmain.c
@@ -217,7 +217,7 @@ typedef struct _GMainDispatch GMainDispatch;
 struct _GMainDispatch
 {
   gint depth;
-  GSList *dispatching_sources; /* stack of current sources */
+  GSource *source;
 };
 
 #ifdef G_MAIN_POLL_DEBUG
@@ -2853,7 +2853,7 @@ GSource *
 g_main_current_source (void)
 {
   GMainDispatch *dispatch = get_dispatch ();
-  return dispatch->dispatching_sources ? dispatch->dispatching_sources->data : NULL;
+  return dispatch->source;
 }
 
 /**
@@ -3029,7 +3029,7 @@ g_main_dispatch (GMainContext *context)
          gboolean (*dispatch) (GSource *,
                                GSourceFunc,
                                gpointer);
-         GSList current_source_link;
+          GSource *prev_source;
 
          dispatch = source->source_funcs->dispatch;
          cb_funcs = source->callback_funcs;
@@ -3049,26 +3049,17 @@ g_main_dispatch (GMainContext *context)
 
          UNLOCK_CONTEXT (context);
 
-         current->depth++;
-         /* The on-stack allocation of the GSList is unconventional, but
-          * we know that the lifetime of the link is bounded to this
-          * function as the link is kept in a thread specific list and
-          * not manipulated outside of this function and its descendants.
-          * Avoiding the overhead of a g_slist_alloc() is useful as many
-          * applications do little more than dispatch events.
-          *
-          * This is a performance hack - do not revert to g_slist_prepend()!
-          */
-         current_source_link.data = source;
-         current_source_link.next = current->dispatching_sources;
-         current->dispatching_sources = &current_source_link;
-         need_destroy = ! dispatch (source,
-                                    callback,
-                                    user_data);
-         g_assert (current->dispatching_sources == &current_source_link);
-         current->dispatching_sources = current_source_link.next;
-         current->depth--;
-         
+          /* These operations are safe because 'current' is thread-local
+           * and not modified from anywhere but this function.
+           */
+          prev_source = current->source;
+          current->depth++;
+
+          need_destroy = !(* dispatch) (source, callback, user_data);
+
+          current->source = prev_source;
+          current->depth--;
+
          if (cb_funcs)
            cb_funcs->unref (cb_data);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]