[gnome-color-manager] Allow UDEV and CUPS coldplug to be done multi-threaded
- From: Richard Hughes <rhughes src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-color-manager] Allow UDEV and CUPS coldplug to be done multi-threaded
- Date: Thu, 11 Feb 2010 17:50:43 +0000 (UTC)
commit 5368e6d8e11edbf874b7ab835d4200df977ce217
Author: Richard Hughes <richard hughsie com>
Date: Thu Feb 11 17:49:31 2010 +0000
Allow UDEV and CUPS coldplug to be done multi-threaded
src/gcm-client.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++----
src/gcm-client.h | 2 +
src/gcm-dbus.c | 1 +
src/gcm-prefs.c | 48 +++++++++++++-------
4 files changed, 157 insertions(+), 26 deletions(-)
---
diff --git a/src/gcm-client.c b/src/gcm-client.c
index 7a6e32c..671867c 100644
--- a/src/gcm-client.c
+++ b/src/gcm-client.c
@@ -62,11 +62,16 @@ struct _GcmClientPrivate
GUdevClient *gudev_client;
GcmScreen *screen;
http_t *http;
+ gboolean loading;
+ guint loading_refcount;
+ gboolean use_threads;
};
enum {
PROP_0,
PROP_DISPLAY_NAME,
+ PROP_LOADING,
+ PROP_USE_THREADS,
PROP_LAST
};
@@ -81,6 +86,43 @@ static guint signals[SIGNAL_LAST] = { 0 };
G_DEFINE_TYPE (GcmClient, gcm_client, G_TYPE_OBJECT)
/**
+ * gcm_client_set_use_threads:
+ **/
+void
+gcm_client_set_use_threads (GcmClient *client, gboolean use_threads)
+{
+ client->priv->use_threads = use_threads;
+ g_object_notify (G_OBJECT (client), "use-threads");
+}
+
+/**
+ * gcm_client_set_loading:
+ **/
+static void
+gcm_client_set_loading (GcmClient *client, gboolean ret)
+{
+ client->priv->loading = ret;
+ g_object_notify (G_OBJECT (client), "loading");
+ egg_debug ("loading: %i", ret);
+}
+
+/**
+ * gcm_client_done_loading:
+ **/
+static void
+gcm_client_done_loading (GcmClient *client)
+{
+ static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
+
+ /* decrement refcount, with a lock */
+ g_static_mutex_lock (&mutex);
+ client->priv->loading_refcount--;
+ if (client->priv->loading_refcount == 0)
+ gcm_client_set_loading (client, FALSE);
+ g_static_mutex_unlock (&mutex);
+}
+
+/**
* gcm_client_get_devices:
*
* @client: a valid %GcmClient instance
@@ -283,10 +325,23 @@ gcm_client_add_connected_devices_udev (GcmClient *client, GError **error)
g_list_foreach (devices, (GFunc) g_object_unref, NULL);
g_list_free (devices);
+
+ /* inform the UI */
+ gcm_client_done_loading (client);
return TRUE;
}
/**
+ * gcm_client_add_connected_devices_udev_thrd:
+ **/
+static gpointer
+gcm_client_add_connected_devices_udev_thrd (GcmClient *client)
+{
+ gcm_client_add_connected_devices_udev (client, NULL);
+ return NULL;
+}
+
+/**
* gcm_client_get_device_by_window_covered:
**/
static gfloat
@@ -555,10 +610,23 @@ gcm_client_add_connected_devices_cups (GcmClient *client, GError **error)
for (i = 0; i < num_dests; i++)
gcm_client_cups_add (client, dests[i]);
cupsFreeDests (num_dests, dests);
+
+ /* inform the UI */
+ gcm_client_done_loading (client);
return TRUE;
}
/**
+ * gcm_client_add_connected_devices_cups_thrd:
+ **/
+static gpointer
+gcm_client_add_connected_devices_cups_thrd (GcmClient *client)
+{
+ gcm_client_add_connected_devices_cups (client, NULL);
+ return NULL;
+}
+
+/**
* gcm_client_add_unconnected_device:
**/
static void
@@ -686,23 +754,40 @@ gboolean
gcm_client_add_connected (GcmClient *client, GError **error)
{
gboolean ret;
+ GThread *thread;
g_return_val_if_fail (GCM_IS_CLIENT (client), FALSE);
- /* udev */
- ret = gcm_client_add_connected_devices_udev (client, error);
- if (!ret)
- goto out;
-
- /* xrandr */
+ /* XRandR */
ret = gcm_client_add_connected_devices_xrandr (client, error);
if (!ret)
goto out;
- /* cups */
- ret = gcm_client_add_connected_devices_cups (client, error);
- if (!ret)
- goto out;
+ /* inform UI if we are loading devces still */
+ client->priv->loading_refcount = 2;
+ gcm_client_set_loading (client, TRUE);
+
+ /* UDEV */
+ if (client->priv->use_threads) {
+ thread = g_thread_create ((GThreadFunc) gcm_client_add_connected_devices_udev_thrd, client, FALSE, error);
+ if (thread == NULL)
+ goto out;
+ } else {
+ ret = gcm_client_add_connected_devices_udev (client, error);
+ if (!ret)
+ goto out;
+ }
+
+ /* CUPS */
+ if (client->priv->use_threads) {
+ thread = g_thread_create ((GThreadFunc) gcm_client_add_connected_devices_cups_thrd, client, FALSE, error);
+ if (thread == NULL)
+ goto out;
+ } else {
+ ret = gcm_client_add_connected_devices_cups (client, error);
+ if (!ret)
+ goto out;
+ }
out:
return ret;
}
@@ -797,6 +882,12 @@ gcm_client_get_property (GObject *object, guint prop_id, GValue *value, GParamSp
case PROP_DISPLAY_NAME:
g_value_set_string (value, priv->display_name);
break;
+ case PROP_LOADING:
+ g_value_set_boolean (value, priv->loading);
+ break;
+ case PROP_USE_THREADS:
+ g_value_set_boolean (value, priv->use_threads);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -817,6 +908,9 @@ gcm_client_set_property (GObject *object, guint prop_id, const GValue *value, GP
g_free (priv->display_name);
priv->display_name = g_strdup (g_value_get_string (value));
break;
+ case PROP_USE_THREADS:
+ priv->use_threads = g_value_get_boolean (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -861,6 +955,22 @@ gcm_client_class_init (GcmClientClass *klass)
g_object_class_install_property (object_class, PROP_DISPLAY_NAME, pspec);
/**
+ * GcmClient:loading:
+ */
+ pspec = g_param_spec_boolean ("loading", NULL, NULL,
+ TRUE,
+ G_PARAM_READABLE);
+ g_object_class_install_property (object_class, PROP_LOADING, pspec);
+
+ /**
+ * GcmClient:use-threads:
+ */
+ pspec = g_param_spec_boolean ("use-threads", NULL, NULL,
+ TRUE,
+ G_PARAM_READWRITE);
+ g_object_class_install_property (object_class, PROP_USE_THREADS, pspec);
+
+ /**
* GcmClient::added
**/
signals[SIGNAL_ADDED] =
@@ -893,6 +1003,8 @@ gcm_client_init (GcmClient *client)
client->priv = GCM_CLIENT_GET_PRIVATE (client);
client->priv->display_name = NULL;
+ client->priv->loading_refcount = 0;
+ client->priv->use_threads = FALSE;
client->priv->array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
client->priv->screen = gcm_screen_new ();
g_signal_connect (client->priv->screen, "outputs-changed",
diff --git a/src/gcm-client.h b/src/gcm-client.h
index 1638aea..147a753 100644
--- a/src/gcm-client.h
+++ b/src/gcm-client.h
@@ -74,6 +74,8 @@ gboolean gcm_client_add_connected (GcmClient *client,
gboolean gcm_client_add_saved (GcmClient *client,
GError **error);
GPtrArray *gcm_client_get_devices (GcmClient *client);
+void gcm_client_set_use_threads (GcmClient *client,
+ gboolean use_threads);
G_END_DECLS
diff --git a/src/gcm-dbus.c b/src/gcm-dbus.c
index b8e3d5a..2a1d5bb 100644
--- a/src/gcm-dbus.c
+++ b/src/gcm-dbus.c
@@ -498,6 +498,7 @@ gcm_dbus_init (GcmDbus *dbus)
dbus->priv = GCM_DBUS_GET_PRIVATE (dbus);
dbus->priv->gconf_client = gconf_client_get_default ();
dbus->priv->client = gcm_client_new ();
+ gcm_client_set_use_threads (dbus->priv->client, TRUE);
dbus->priv->profile_store = gcm_profile_store_new ();
dbus->priv->timer = g_timer_new ();
diff --git a/src/gcm-prefs.c b/src/gcm-prefs.c
index 7368cad..8dd8e6c 100644
--- a/src/gcm-prefs.c
+++ b/src/gcm-prefs.c
@@ -59,7 +59,6 @@ static gboolean setting_up_device = FALSE;
static GtkWidget *info_bar = NULL;
static GtkWidget *cie_widget = NULL;
static GtkWidget *trc_widget = NULL;
-static guint loading_refcount = 0;
static GConfClient *gconf_client = NULL;
enum {
@@ -2453,8 +2452,6 @@ static gboolean
gcm_prefs_added_idle_cb (GcmDevice *device)
{
GcmDeviceTypeEnum type;
- GtkTreePath *path;
- GtkWidget *widget;
egg_debug ("added: %s", gcm_device_get_id (device));
/* remove the saved device if it's already there */
@@ -2471,17 +2468,6 @@ gcm_prefs_added_idle_cb (GcmDevice *device)
else
gcm_prefs_add_device_type (device);
- /* clear loading widget */
- if (--loading_refcount == 0) {
- gtk_widget_hide (info_bar);
-
- /* set the cursor on the first device */
- widget = GTK_WIDGET (gtk_builder_get_object (builder, "treeview_devices"));
- path = gtk_tree_path_new_from_string ("0");
- gtk_tree_view_set_cursor (GTK_TREE_VIEW (widget), path, NULL, FALSE);
- gtk_tree_path_free (path);
- }
-
/* unref the instance */
g_object_unref (device);
return FALSE;
@@ -2493,9 +2479,7 @@ gcm_prefs_added_idle_cb (GcmDevice *device)
static void
gcm_prefs_added_cb (GcmClient *gcm_client_, GcmDevice *gcm_device, gpointer user_data)
{
- gtk_widget_show (info_bar);
g_idle_add ((GSourceFunc) gcm_prefs_added_idle_cb, g_object_ref (gcm_device));
- loading_refcount++;
}
/**
@@ -2890,6 +2874,35 @@ gcm_prefs_profile_store_changed_cb (GcmProfileStore *_profile_store, gpointer us
}
/**
+ * gcm_prefs_client_notify_loading_cb:
+ **/
+static void
+gcm_prefs_client_notify_loading_cb (GcmClient *client, GParamSpec *pspec, gpointer data)
+{
+ gboolean loading;
+ GtkTreePath *path;
+ GtkWidget *widget;
+
+ /* get the new state */
+ g_object_get (client, "loading", &loading, NULL);
+
+ /*if loading show the bar */
+ if (loading) {
+ gtk_widget_show (info_bar);
+ return;
+ }
+
+ /* otherwise clear the loading widget */
+ gtk_widget_hide (info_bar);
+
+ /* set the cursor on the first device */
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "treeview_devices"));
+ path = gtk_tree_path_new_from_string ("0");
+ gtk_tree_view_set_cursor (GTK_TREE_VIEW (widget), path, NULL, FALSE);
+ gtk_tree_path_free (path);
+}
+
+/**
* main:
**/
int
@@ -3127,8 +3140,11 @@ main (int argc, char **argv)
/* use a device client array */
gcm_client = gcm_client_new ();
+ gcm_client_set_use_threads (gcm_client, TRUE);
g_signal_connect (gcm_client, "added", G_CALLBACK (gcm_prefs_added_cb), NULL);
g_signal_connect (gcm_client, "removed", G_CALLBACK (gcm_prefs_removed_cb), NULL);
+ g_signal_connect (gcm_client, "notify::loading",
+ G_CALLBACK (gcm_prefs_client_notify_loading_cb), NULL);
/* use the color device */
color_device = gcm_color_device_new ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]