aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mm-plugin-manager.c52
1 files changed, 48 insertions, 4 deletions
diff --git a/src/mm-plugin-manager.c b/src/mm-plugin-manager.c
index b46b3a6f..5b3f03e6 100644
--- a/src/mm-plugin-manager.c
+++ b/src/mm-plugin-manager.c
@@ -677,6 +677,10 @@ port_context_new (MMPluginManager *self,
* (needs to be > MIN_WAIT_TIME_MSECS!!) */
#define MIN_PROBING_TIME_MSECS 2500
+/* Additional time to wait for other ports to appear after the last port is
+ * exposed in the system. */
+#define EXTRA_PROBING_TIME_MSECS 1500
+
/* The wait time we define must always be less than the probing time */
G_STATIC_ASSERT (MIN_WAIT_TIME_MSECS < MIN_PROBING_TIME_MSECS);
@@ -716,11 +720,18 @@ struct _DeviceContext {
/* Port support check contexts waiting to be run after min wait time */
GList *wait_port_contexts;
- /* Minimum probing_time. The device support check task cannot be finished
- * before this timeout expires. Once the timeout is expired, the id is reset
- * to 0. */
+ /* Minimum probing time, which is a timeout initialized as soon as the first
+ * port is added to the device context. The device support check task cannot
+ * be finished before this timeout expires. Once the timeout is expired, the
+ * id is reset to 0. */
guint min_probing_time_id;
+ /* Extra probing time, which is a timeout refreshed every time a new port
+ * is added to the device context. The device support check task cannot be
+ * finished before this timeout expires. Once the timeout is expired, the id
+ * is reset to 0. */
+ guint extra_probing_time_id;
+
/* Signal connection ids for the grabbed/released signals from the device.
* These are the signals that will give us notifications of what ports are
* available (or suddenly unavailable) in the device. */
@@ -741,6 +752,7 @@ device_context_unref (DeviceContext *device_context)
g_assert (!device_context->released_id);
g_assert (!device_context->min_wait_time_id);
g_assert (!device_context->min_probing_time_id);
+ g_assert (!device_context->extra_probing_time_id);
g_assert (!device_context->port_contexts);
/* The device support check task must have been completed previously */
@@ -812,7 +824,7 @@ device_context_complete (DeviceContext *device_context)
{
GTask *task;
- /* If the context is completed before the minimum probing time, we need to wait
+ /* If the context is completed before the 2500ms minimum probing time, we need to wait
* until that happens, so that we give enough time to udev/hotplug to report the
* new port additions. */
if (device_context->min_probing_time_id) {
@@ -821,6 +833,14 @@ device_context_complete (DeviceContext *device_context)
return;
}
+ /* If the context is completed less than 1500ms before the last port was exposed,
+ * wait some more. */
+ if (device_context->extra_probing_time_id) {
+ mm_dbg ("[plugin manager] task %s: all port probings completed, but not reached extra probing time yet",
+ device_context->name);
+ return;
+ }
+
/* Steal the task from the context */
g_assert (device_context->task);
task = device_context->task;
@@ -1073,6 +1093,18 @@ device_context_min_probing_time_elapsed (DeviceContext *device_context)
return G_SOURCE_REMOVE;
}
+static gboolean
+device_context_extra_probing_time_elapsed (DeviceContext *device_context)
+{
+ device_context->extra_probing_time_id = 0;
+
+ mm_dbg ("[plugin manager] task %s: extra probing time elapsed", device_context->name);
+
+ /* Wakeup the device context logic */
+ device_context_continue (device_context);
+ return G_SOURCE_REMOVE;
+}
+
static void
device_context_run_port_context (DeviceContext *device_context,
PortContext *port_context)
@@ -1204,6 +1236,13 @@ device_context_port_grabbed (DeviceContext *device_context,
return;
}
+ /* Refresh the extra probing timeout. */
+ if (device_context->extra_probing_time_id)
+ g_source_remove (device_context->extra_probing_time_id);
+ device_context->extra_probing_time_id = g_timeout_add (EXTRA_PROBING_TIME_MSECS,
+ (GSourceFunc) device_context_extra_probing_time_elapsed,
+ device_context);
+
/* Setup a new port context for the newly grabbed port */
port_context = port_context_new (self,
device_context->name,
@@ -1267,6 +1306,10 @@ device_context_cancel (DeviceContext *device_context)
g_source_remove (device_context->min_probing_time_id);
device_context->min_probing_time_id = 0;
}
+ if (device_context->extra_probing_time_id) {
+ g_source_remove (device_context->extra_probing_time_id);
+ device_context->extra_probing_time_id = 0;
+ }
/* Wakeup the device context logic. If we were still waiting for the
* min probing time, this will complete the device context. */
@@ -1285,6 +1328,7 @@ device_context_run (MMPluginManager *self,
g_assert (!device_context->released_id);
g_assert (!device_context->min_wait_time_id);
g_assert (!device_context->min_probing_time_id);
+ g_assert (!device_context->extra_probing_time_id);
/* Connect to device port grabbed/released notifications from the device */
device_context->grabbed_id = g_signal_connect_swapped (device_context->device,