Replace a g_slist_prepend/g_slist_remove pair with an on-stack link and
authorChris Wilson <chris@chris-wilson.co.uk>
Thu, 15 Mar 2007 08:47:28 +0000 (08:47 +0000)
committerChris Wilson <cpwilson@src.gnome.org>
Thu, 15 Mar 2007 08:47:28 +0000 (08:47 +0000)
2007-03-15  Chris Wilson  <chris@chris-wilson.co.uk>

* glib/gmain.c (g_main_dispatch): Replace a
g_slist_prepend/g_slist_remove pair with an on-stack link
and open coding. (#416094)

svn path=/trunk/; revision=5407

ChangeLog
glib/gmain.c

index 2347656..6212cbe 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2007-03-15  Chris Wilson  <chris@chris-wilson.co.uk>
+
+       * glib/gmain.c (g_main_dispatch): Replace a
+       g_slist_prepend/g_slist_remove pair with an on-stack link
+       and open coding. (#416094)
+
 2007-03-15  Matthias Clasen  <mclasen@redhat.com>
 
        * glib/gscanner.[hc]: Some optimizations, use a lookup
index 0bbd30f..a273cd3 100644 (file)
@@ -2025,6 +2025,7 @@ g_main_dispatch (GMainContext *context)
          gboolean (*dispatch) (GSource *,
                                GSourceFunc,
                                gpointer);
+         GSList current_source_link;
 
          dispatch = source->source_funcs->dispatch;
          cb_funcs = source->callback_funcs;
@@ -2045,11 +2046,23 @@ g_main_dispatch (GMainContext *context)
          UNLOCK_CONTEXT (context);
 
          current->depth++;
-         current->source = g_slist_prepend (current->source, source);
+         /* 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->source;
+         current->source = &current_source_link;
          need_destroy = ! dispatch (source,
                                     callback,
                                     user_data);
-         current->source = g_slist_remove (current->source, source);
+         g_assert (current->source == &current_source_link);
+         current->source = current_source_link.next;
          current->depth--;
          
          if (cb_funcs)