From 38df72dcbd6d99c22cd0f695c6e6408b280b4167 Mon Sep 17 00:00:00 2001 From: Sven Neumann Date: Tue, 5 Aug 2008 16:09:29 +0000 Subject: [PATCH] keep a queue of D-Bus requests and work on them one after another instead 2008-08-05 Sven Neumann * app/gui/gimpdbusservice.[ch]: keep a queue of D-Bus requests and work on them one after another instead of handling them all in parallel. Complements the fix for bug #546426. svn path=/trunk/; revision=26386 --- ChangeLog | 6 ++ app/gui/gimpdbusservice.c | 143 +++++++++++++++++++++++++++++--------- app/gui/gimpdbusservice.h | 2 + 3 files changed, 117 insertions(+), 34 deletions(-) diff --git a/ChangeLog b/ChangeLog index f23590a767..df515c628f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-08-05 Sven Neumann + + * app/gui/gimpdbusservice.[ch]: keep a queue of D-Bus requests and + work on them one after another instead of handling them all in + parallel. Complements the fix for bug #546426. + 2008-08-05 Sven Neumann * plug-ins/common/value-propagate.c (value_propagate_body): diff --git a/app/gui/gimpdbusservice.c b/app/gui/gimpdbusservice.c index 5b5b81201b..d8a17cf361 100644 --- a/app/gui/gimpdbusservice.c +++ b/app/gui/gimpdbusservice.c @@ -39,15 +39,42 @@ #include "gimpdbusservice-glue.h" +typedef struct +{ + Gimp *gimp; + gchar *uri; + gboolean as_new; +} OpenData; + + static void gimp_dbus_service_class_init (GimpDBusServiceClass *klass); static void gimp_dbus_service_init (GimpDBusService *service); +static void gimp_dbus_service_dispose (GObject *object); +static void gimp_dbus_service_finalize (GObject *object); + +static void gimp_dbus_service_queue_open (GimpDBusService *service, + const gchar *uri, + gboolean as_new); + +static OpenData * gimp_dbus_service_open_data_new (GimpDBusService *service, + const gchar *uri, + gboolean as_new); +static void gimp_dbus_service_open_data_free (OpenData *data); + G_DEFINE_TYPE (GimpDBusService, gimp_dbus_service, G_TYPE_OBJECT) +#define parent_class gimp_dbus_service_parent_class + static void gimp_dbus_service_class_init (GimpDBusServiceClass *klass) { + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = gimp_dbus_service_dispose; + object_class->finalize = gimp_dbus_service_finalize; + dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass), &dbus_glib_gimp_object_info); } @@ -55,6 +82,7 @@ gimp_dbus_service_class_init (GimpDBusServiceClass *klass) static void gimp_dbus_service_init (GimpDBusService *service) { + service->queue = g_queue_new (); } GObject * @@ -71,42 +99,37 @@ gimp_dbus_service_new (Gimp *gimp) return G_OBJECT (service); } -typedef struct +static void +gimp_dbus_service_dispose (GObject *object) { - Gimp *gimp; - gchar *uri; - gboolean as_new; -} IdleData; + GimpDBusService *service = GIMP_DBUS_SERVICE (object); -static IdleData * -gimp_dbus_service_open_idle_new (GimpDBusService *service, - const gchar *uri, - gboolean as_new) -{ - IdleData *data = g_slice_new (IdleData); + if (service->source) + { + g_source_remove (g_source_get_id (service->source)); + service->source = NULL; + } - data->gimp = g_object_ref (service->gimp); - data->uri = g_strdup (uri); - data->as_new = as_new; + while (! g_queue_is_empty (service->queue)) + { + gimp_dbus_service_open_data_free (g_queue_pop_head (service->queue)); + } - return data; + G_OBJECT_CLASS (parent_class)->dispose (object); } static void -gimp_dbus_service_open_idle_free (IdleData *data) +gimp_dbus_service_finalize (GObject *object) { - g_object_unref (data->gimp); - g_free (data->uri); + GimpDBusService *service = GIMP_DBUS_SERVICE (object); - g_slice_free (IdleData, data); -} + if (service->queue) + { + g_queue_free (service->queue); + service->queue = NULL; + } -static gboolean -gimp_dbus_service_open_idle (IdleData *data) -{ - file_open_from_command_line (data->gimp, data->uri, data->as_new); - - return FALSE; + G_OBJECT_CLASS (parent_class)->finalize (object); } gboolean @@ -119,10 +142,7 @@ gimp_dbus_service_open (GimpDBusService *service, g_return_val_if_fail (uri != NULL, FALSE); g_return_val_if_fail (success != NULL, FALSE); - g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, - (GSourceFunc) gimp_dbus_service_open_idle, - gimp_dbus_service_open_idle_new (service, uri, FALSE), - (GDestroyNotify) gimp_dbus_service_open_idle_free); + gimp_dbus_service_queue_open (service, uri, FALSE); /* The call always succeeds as it is handled in one way or another. * Even presenting an error message is considered success ;-) @@ -142,10 +162,7 @@ gimp_dbus_service_open_as_new (GimpDBusService *service, g_return_val_if_fail (uri != NULL, FALSE); g_return_val_if_fail (success != NULL, FALSE); - g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, - (GSourceFunc) gimp_dbus_service_open_idle, - gimp_dbus_service_open_idle_new (service, uri, TRUE), - (GDestroyNotify) gimp_dbus_service_open_idle_free); + gimp_dbus_service_queue_open (service, uri, TRUE); /* The call always succeeds as it is handled in one way or another. * Even presenting an error message is considered success ;-) @@ -170,5 +187,63 @@ gimp_dbus_service_activate (GimpDBusService *service, return TRUE; } +static OpenData * +gimp_dbus_service_open_data_new (GimpDBusService *service, + const gchar *uri, + gboolean as_new) +{ + OpenData *data = g_slice_new (OpenData); + + data->gimp = g_object_ref (service->gimp); + data->uri = g_strdup (uri); + data->as_new = as_new; + + return data; +} + +static void +gimp_dbus_service_open_data_free (OpenData *data) +{ + g_object_unref (data->gimp); + g_free (data->uri); + + g_slice_free (OpenData, data); +} + +static gboolean +gimp_dbus_service_open_idle (GQueue *queue) +{ + OpenData *data = g_queue_pop_tail (queue); + + if (data) + { + file_open_from_command_line (data->gimp, data->uri, data->as_new); + gimp_dbus_service_open_data_free (data); + + return TRUE; + } + + return FALSE; +} + +static void +gimp_dbus_service_queue_open (GimpDBusService *service, + const gchar *uri, + gboolean as_new) +{ + g_queue_push_tail (service->queue, + gimp_dbus_service_open_data_new (service, uri, as_new)); + + if (! service->source) + { + service->source = g_idle_source_new (); + + g_source_set_callback (service->source, + (GSourceFunc) gimp_dbus_service_open_idle, + service->queue, NULL); + g_source_attach (service->source, NULL); + g_source_unref (service->source); + } +} #endif /* HAVE_DBUS_GLIB */ diff --git a/app/gui/gimpdbusservice.h b/app/gui/gimpdbusservice.h index dabfce0509..6fee49b768 100644 --- a/app/gui/gimpdbusservice.h +++ b/app/gui/gimpdbusservice.h @@ -46,6 +46,8 @@ struct _GimpDBusService GObject parent_instance; Gimp *gimp; + GQueue *queue; + GSource *source; }; struct _GimpDBusServiceClass