keep a queue of D-Bus requests and work on them one after another instead

2008-08-05  Sven Neumann  <sven@gimp.org>

	* 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
This commit is contained in:
Sven Neumann
2008-08-05 16:09:29 +00:00
committed by Sven Neumann
parent b726c54a7a
commit 38df72dcbd
3 changed files with 117 additions and 34 deletions

View File

@ -1,3 +1,9 @@
2008-08-05 Sven Neumann <sven@gimp.org>
* 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 <sven@gimp.org>
* plug-ins/common/value-propagate.c (value_propagate_body):

View File

@ -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 */

View File

@ -46,6 +46,8 @@ struct _GimpDBusService
GObject parent_instance;
Gimp *gimp;
GQueue *queue;
GSource *source;
};
struct _GimpDBusServiceClass