From ae3d65f60b6aa85831de6b65e7a80b3fdcce6f8d Mon Sep 17 00:00:00 2001 From: Richard Hughes Date: Fri, 16 Dec 2016 09:38:01 +0000 Subject: [PATCH] Move the device add delay to shared code This allows us to reuse the logic in other plugins. --- plugins/usb/fu-plugin-usb.c | 40 +++++------------------------ src/fu-plugin.c | 51 +++++++++++++++++++++++++++++++++++++ src/fu-plugin.h | 2 ++ 3 files changed, 60 insertions(+), 33 deletions(-) diff --git a/plugins/usb/fu-plugin-usb.c b/plugins/usb/fu-plugin-usb.c index 9c4a24ede..e79089a05 100644 --- a/plugins/usb/fu-plugin-usb.c +++ b/plugins/usb/fu-plugin-usb.c @@ -27,7 +27,9 @@ #include "fu-plugin-vfuncs.h" static void -fu_plugin_usb_device_added (FuPlugin *plugin, GUsbDevice *device) +fu_plugin_usb_device_added_cb (GUsbContext *ctx, + GUsbDevice *device, + FuPlugin *plugin) { const gchar *platform_id = NULL; guint8 idx = 0x00; @@ -120,40 +122,12 @@ fu_plugin_usb_device_added (FuPlugin *plugin, GUsbDevice *device) if (!g_usb_device_close (device, &error)) g_debug ("Failed to close: %s", error->message); - /* insert to hash */ - fu_plugin_device_add (plugin, dev); - fu_plugin_cache_add (plugin, platform_id, dev); -} - -typedef struct { - FuPlugin *plugin; - GUsbDevice *device; -} FuPluginHelper; - -static gboolean -fu_plugin_usb_device_added_delay_cb (gpointer user_data) -{ - FuPluginHelper *helper = (FuPluginHelper *) user_data; - fu_plugin_usb_device_added (helper->plugin, helper->device); - g_object_unref (helper->plugin); - g_object_unref (helper->device); - g_free (helper); - return FALSE; -} - -static void -fu_plugin_usb_device_added_cb (GUsbContext *ctx, - GUsbDevice *device, - FuPlugin *plugin) -{ /* use a small delay for hotplugging so that other, better, plugins * can claim this interface and add the FuDevice */ - FuPluginHelper *helper; - g_debug ("waiting a small time for other plugins"); - helper = g_new0 (FuPluginHelper, 1); - helper->plugin = g_object_ref (plugin); - helper->device = g_object_ref (device); - g_timeout_add (500, fu_plugin_usb_device_added_delay_cb, helper); + fu_plugin_device_add_delay (plugin, dev); + + /* insert to hash */ + fu_plugin_cache_add (plugin, platform_id, dev); } static void diff --git a/src/fu-plugin.c b/src/fu-plugin.c index a0b92905f..7faeb036f 100644 --- a/src/fu-plugin.c +++ b/src/fu-plugin.c @@ -39,6 +39,7 @@ typedef struct { gboolean enabled; gchar *name; GHashTable *devices; /* platform_id:GObject */ + GHashTable *devices_delay; /* FuDevice:FuPluginHelper */ FuPluginData *data; } FuPluginPrivate; @@ -196,9 +197,57 @@ fu_plugin_device_add (FuPlugin *plugin, FuDevice *device) g_signal_emit (plugin, signals[SIGNAL_DEVICE_ADDED], 0, device); } +typedef struct { + FuPlugin *plugin; + FuDevice *device; + guint timeout_id; +} FuPluginHelper; + +static void +fu_plugin_helper_free (FuPluginHelper *helper) +{ + g_object_unref (helper->plugin); + g_object_unref (helper->device); + g_free (helper); +} + +static gboolean +fu_plugin_device_add_delay_cb (gpointer user_data) +{ + FuPluginHelper *helper = (FuPluginHelper *) user_data; + fu_plugin_device_add (helper->plugin, helper->device); + fu_plugin_helper_free (helper); + return FALSE; +} + +void +fu_plugin_device_add_delay (FuPlugin *plugin, FuDevice *device) +{ + FuPluginPrivate *priv = GET_PRIVATE (plugin); + FuPluginHelper *helper; + g_debug ("waiting a small time for other plugins"); + helper = g_new0 (FuPluginHelper, 1); + helper->plugin = g_object_ref (plugin); + helper->device = g_object_ref (device); + helper->timeout_id = g_timeout_add (500, fu_plugin_device_add_delay_cb, helper); + g_hash_table_insert (priv->devices_delay, device, helper); +} + void fu_plugin_device_remove (FuPlugin *plugin, FuDevice *device) { + FuPluginPrivate *priv = GET_PRIVATE (plugin); + FuPluginHelper *helper; + + /* waiting for add */ + helper = g_hash_table_lookup (priv->devices_delay, device); + if (helper != NULL) { + g_debug ("ignoring remove from delayed addition"); + g_source_remove (helper->timeout_id); + fu_plugin_helper_free (helper); + return; + } + g_debug ("emit removed from %s: %s", fu_plugin_get_name (plugin), fu_device_get_id (device)); @@ -706,6 +755,7 @@ fu_plugin_init (FuPlugin *plugin) priv->enabled = TRUE; priv->devices = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_object_unref); + priv->devices_delay = g_hash_table_new (g_str_hash, g_str_equal); } static void @@ -729,6 +779,7 @@ fu_plugin_finalize (GObject *object) if (priv->module != NULL) g_module_close (priv->module); g_hash_table_unref (priv->devices); + g_hash_table_unref (priv->devices_delay); g_free (priv->name); g_free (priv->data); diff --git a/src/fu-plugin.h b/src/fu-plugin.h index 9705c8ce6..39b6fd356 100644 --- a/src/fu-plugin.h +++ b/src/fu-plugin.h @@ -69,6 +69,8 @@ void fu_plugin_set_enabled (FuPlugin *plugin, GUsbContext *fu_plugin_get_usb_context (FuPlugin *plugin); void fu_plugin_device_add (FuPlugin *plugin, FuDevice *device); +void fu_plugin_device_add_delay (FuPlugin *plugin, + FuDevice *device); void fu_plugin_device_remove (FuPlugin *plugin, FuDevice *device); void fu_plugin_set_status (FuPlugin *plugin,